Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9413461
  • 博文数量: 1748
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20070
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1748)

文章存档

2024年(24)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: Android平台

2017-05-02 20:42:48


  1. Target    = demo_gtk

  2. SrcDir= .
  3. ExtList= .cpp .c

  4. Source= $(foreach ext,$(ExtList), \
  5.     $(foreach sd, $(SrcDir), $(wildcard $(addprefix $(sd)/*,$(ext)))))

  6. Objs= $(foreach ext, $(ExtList), \
  7.     $(patsubst %$(ext), %.o, $(filter %$(ext),$(Source))))

  8. CFLAGS := -Wall
  9. LIBS := -lrt -lpthread
  10. INCDIR := -I . -I /usr/include/publib -I/usr/include/jsoncpp/

  11. LIBS += -lopencv_core -lopencv_highgui -lopencv_ml -lopencv_imgproc -lopencv_video -lopencv_objdetect
  12. LIBS += `pkg-config --libs gtk+-2.0`
  13. INCDIR += -I /usr/include/opencv
  14. INCDIR += `pkg-config --cflags gtk+-2.0`

  15. CC=g++
  16. CPP=g++

  17. %.o : %.c
  18.     $(CC) $(CFLAGS) -c $(@D)/$(<F) -o $(@D)/$(@F) $(INCDIR)
  19. %.o : %.cpp
  20.     $(CPP) $(CFLAGS) -c $(@D)/$(<F) -o $(@D)/$(@F) $(INCDIR)

  21. $(Target): $(Objs)
  22.     $(CC) -o $(Target) $(Objs) $(LIBS)

  23. all: $(Target)

  24. objs: $(Objs)
  25.     
  26. RM= rm -rf

  27. clean:
  28.     @$(RM) $(foreach sd, $(SrcDir), $(wildcard $(sd)/*.o))
  29.     @$(RM) $(Target)

  30. cleanall:clean
  31.     @$(RM) $(Target)

  32. rebuild: cleanall all
主要为 mat 对象的 RGB值转换的问题.

  1. #include <gtk/gtk.h>
  2. #include <glib/gstdio.h>
  3. #include <stdio.h>


  4. #include <opencv2/highgui/highgui.hpp>
  5. #include <opencv2/imgproc/imgproc.hpp>
  6. #include <opencv2/core/core.hpp>
  7. #include <opencv2/objdetect/objdetect.hpp>

  8. #include <errno.h>
  9. #include <string>
  10. using std::string;

  11. #include <iostream>
  12. #include <vector>
  13. #include <sstream>
  14. using std::stringstream;

  15. using namespace cv;
  16. using namespace std;

  17. int ydi_absname(char *buf, uint bufsiz)
  18. {
  19.     int count = readlink( "/proc/self/exe", buf, bufsiz-1 );
  20.     if (-1 == count)
  21.         return -errno;
  22.     
  23.     buf[ count ] = '\0';
  24.     return count;
  25. }

  26. int ydi_dirname(char *buf, uint bufsiz)
  27. {
  28.     int count = ydi_absname(buf, bufsiz);
  29.     if (count > 0) {
  30.         do {
  31.             if (buf[ --count ] == '/') {
  32.                 buf[ count ] = '\0';
  33.                 break;
  34.             }
  35.         } while (count > 0);
  36.     }
  37.     return count;
  38. }

  39. static Mat frame;
  40. static CascadeClassifier cascade, nestedCascade;
  41. static double scale = 4; //近距离用 4, 远用 6

  42. int detectAndDraw( Mat& img, CascadeClassifier& cascade, CascadeClassifier& nestedCascade, double scale)
  43. {
  44.     int i = 0;
  45.     double t = 0;
  46.     //建立用于存放人脸的向量容器
  47.     vector<Rect> faces, faces2;

  48.     //定义一些颜色,用来标示不同的人脸
  49.     //*
  50.     const static Scalar colors[] = { CV_RGB(0,0,255),
  51.         CV_RGB(0,128,255),
  52.         CV_RGB(0,255,255),
  53.         CV_RGB(0,255,0),
  54.         CV_RGB(255,128,0),
  55.         CV_RGB(255,255,0),
  56.         CV_RGB(255,0,0),
  57.         CV_RGB(255,0,255)} ;
  58.     //*/
  59.     
  60.     //建立缩小的图片,加快检测速度
  61.     //nt cvRound (double value) 对一个double型的数进行四舍五入,并返回一个整型数!
  62.     Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );

  63.     //转成灰度图像,Harr特征基于灰度图
  64.     cvtColor( img, gray, CV_BGR2GRAY );
  65.     
  66.     //改变图像大小,使用双线性差值
  67.     resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
  68.     //变换后的图像进行直方图均值化处理
  69.     equalizeHist( smallImg, smallImg );

  70.     //程序开始和结束插入此函数获取时间,经过计算求得算法执行时间
  71.     t = (double)cvGetTickCount();
  72.     //检测人脸
  73.     //detectMultiScale函数中smallImg表示的是要检测的输入图像为smallImg,faces表示检测到的人脸目标序列,1.1表示
  74.     //每次图像尺寸减小的比例为1.1,2表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大
  75.     //小都可以检测到人脸),CV_HAAR_SCALE_IMAGE表示不是缩放分类器来检测,而是缩放图像,Size(30, 30)为目标的
  76.     //最小最大尺寸
  77.     cascade.detectMultiScale( smallImg, faces,
  78.         1.1, 2, 0
  79.         //|CV_HAAR_FIND_BIGGEST_OBJECT
  80.         //|CV_HAAR_DO_ROUGH_SEARCH
  81.         |CV_HAAR_SCALE_IMAGE
  82.         ,
  83.         Size(30, 30));

  84.     Mat smallImgROI;
  85.     vector<Rect> nestedObjects;
  86.     Point center;
  87.     int radius;
  88.     
  89.     for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++)
  90.     {
  91.         Scalar color = colors[i%8];
  92.         rectangle(img, cvPoint(cvRound(r->x*scale), cvRound(r->y*scale)), cvPoint(cvRound((r->x + r->width-1)*scale), cvRound((r->y + r->height -1)*scale)), color, 3, 8, 0);
  93. #if 0
  94.         if (nestedCascade.empty()) {
  95.           continue;
  96.         }
  97.         
  98.         smallImgROI = smallImg(*r);
  99.         nestedCascade.detectMultiScale(smallImgROI, nestedObjects, 1.1,2,0|CV_HAAR_SCALE_IMAGE, Size(30, 30));
  100.          
  101.         for (vector<Rect>::const_iterator nr=nestedObjects.begin(); nr != nestedObjects.end(); nr++)
  102.         {
  103.           center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);
  104.           center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);
  105.           radius = cvRound((nr->width + nr->height)*0.25*scale);
  106.           circle(img, center, radius, color, 3,8,0);
  107.         }
  108. #endif
  109.         
  110.     }

  111.     return faces.size();
  112. }


  113. gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
  114. {
  115.     return FALSE; //FALSE --> terminated application.
  116. }

  117. void destroy(GtkWidget *widget, gpointer data)
  118. {
  119.     gtk_main_quit();
  120. }

  121. static GtkWidget *window, *vbox, *drawingarea;

  122. static gboolean on_draw_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
  123. {
  124.   if (frame.total() == 640 * 480) {
  125.     cvtColor(frame, frame, CV_BGR2RGB, 3);
  126.     gdk_draw_rgb_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, 0, 640, 480, GDK_RGB_DITHER_MAX, frame.data, 640*3);
  127.   }
  128.   return 1;
  129. }

  130. static void gtk_window_init(int argc, char **argv)
  131. {
  132.   gdk_threads_init();
  133.   
  134.   gtk_disable_setlocale();
  135.   gtk_init(&argc, &argv);
  136.   
  137.   //windows
  138.   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  139.   gtk_window_set_title(GTK_WINDOW(window), "USB Camera");
  140.   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  141.   gtk_window_set_default_size(GTK_WINDOW(window), 640,480);
  142.   g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
  143.   
  144.   //vbox
  145.   vbox = gtk_vbox_new(FALSE, 0);
  146.   gtk_container_add(GTK_CONTAINER(window), vbox);
  147.   
  148.   //drawing area init
  149.   drawingarea = gtk_drawing_area_new();
  150.   gtk_box_pack_start(GTK_BOX(vbox), drawingarea, TRUE, TRUE, 0);
  151.   gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea), 640,480);
  152.   g_signal_connect(GTK_OBJECT(drawingarea), "expose-event", GTK_SIGNAL_FUNC(on_draw_expose), NULL);
  153.   
  154.   gtk_widget_show(vbox);
  155.   gtk_widget_show(drawingarea);
  156.   gtk_widget_show(window);
  157. }

  158. static void draw_thread(GtkWidget *widget)
  159. {
  160.   VideoCapture cap(0);
  161.   if (!cap.isOpened()) {
  162.     printf("camera open failed.\n");
  163.     return;
  164.   }
  165.   
  166.   for (;;) {
  167.     g_usleep(10000);
  168.     cap >> frame;
  169.     detectAndDraw(frame, cascade, nestedCascade, scale);
  170.     gdk_threads_enter();
  171.     gtk_widget_queue_draw(GTK_WIDGET(widget)); //触发 expose event
  172.     gdk_threads_leave();
  173.   }
  174. }

  175. int main(int argc, char **argv)
  176. {
  177.   char l_dir[128];
  178.   ydi_dirname(l_dir, sizeof(l_dir));
  179.     
  180.   string local_dir(l_dir) ;
  181.   string cascadeName = local_dir + "/modules/haarcascade_frontalface_alt.xml";
  182.   if( !cascade.load( cascadeName ) ) {
  183.     cout << "ERROR: Could not load classifier cascade" << endl;
  184.     return -1;
  185.   }
  186.   
  187.   string nestedcascadeName = local_dir + "/modules/haarcascade_eye_tree_eyeglasses.xml";
  188.   if( !nestedCascade.load( nestedcascadeName ) ) {
  189.     cout << "ERROR: Could not load classifier nestedCascade" << endl;
  190.     return -1;
  191.   }

  192.   gtk_window_init(argc, argv);
  193.   
  194.   GError* error = NULL;
  195.   (void)g_thread_create((GThreadFunc)draw_thread, drawingarea, FALSE, &error);
  196.   
  197.   gdk_threads_enter();
  198.   gtk_main();
  199.   gdk_threads_leave();

  200.   return 0;
  201. }

阅读(3057) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~