Scarica il sorgente database/3000-webcam_viewer-v0.01.01-main.cpp
  1. #define VERSIONE_PROGRAMMA "Webcam Viewer v0.01.01"
  2.  
  3. #include <cstdlib>
  4. #include <iostream>
  5. #include <windows.h>
  6. #include <string.h>
  7. #include <math.h>
  8. #include <time.h>
  9.  
  10. using namespace std;
  11.  
  12. //webcam
  13. #include <Vfw.h>
  14. #pragma comment(lib,"Vfw32.lib")
  15.  
  16. //gtk+
  17. #include <gtk/gtk.h>
  18. #pragma comment(lib,"atk-1.0.lib")
  19. #pragma comment(lib,"cairo.lib")
  20. #pragma comment(lib,"gio-2.0.lib")
  21. #pragma comment(lib,"glib-2.0.lib")
  22. #pragma comment(lib,"gmodule-2.0.lib")
  23. #pragma comment(lib,"gobject-2.0.lib")
  24. #pragma comment(lib,"gthread-2.0.lib")
  25. #pragma comment(lib,"gailutil.lib")
  26. #pragma comment(lib,"gdk_pixbuf-2.0.lib")
  27. #pragma comment(lib,"gdk-win32-2.0.lib")
  28. #pragma comment(lib,"gtk-win32-2.0.lib")
  29. #pragma comment(lib,"pango-1.0.lib")
  30. #pragma comment(lib,"pangocairo-1.0.lib")
  31. #pragma comment(lib,"pangoft2-1.0.lib")
  32. #pragma comment(lib,"pangowin32-1.0.lib")
  33.  
  34. //macro
  35. inline char char_conversion(int c){ return ( (c)<255) ? (c) : 255; }
  36.  
  37. //variabili
  38. GtkWidget *finestra1;
  39. GtkWidget *draw_area, *draw_area_sobel;
  40. GtkWidget *area_box;
  41. PangoLayout *testo_draw_area;
  42.  
  43. long frame_count = 0;
  44. int global_frame_width;
  45. int global_frame_row_size;
  46. char *video_text;
  47. clock_t global_time_start, global_time_current;
  48.  
  49. guchar * bit24format;
  50. guchar * bit24format_sobel;
  51. long bit24format_size;
  52. unsigned char ****tabella_yuy2_rgb;
  53.  
  54. //funzioni
  55. int webcam();
  56. gboolean expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data); //callback per drawing area
  57. LRESULT FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr); //callback per cap
  58.  
  59.  
  60. int main(int argc, char *argv[])
  61. {
  62. GError ** thread_error;
  63. thread_error = NULL;
  64.  
  65. if( ! g_thread_supported() )
  66. g_thread_init( NULL );
  67.  
  68. gtk_init (&argc, &argv);
  69. //********** FINESTRA1 *************//
  70. finestra1 = gtk_window_new(GTK_WINDOW_TOPLEVEL); //creo la finestra principale
  71. gtk_window_set_title(GTK_WINDOW(finestra1), VERSIONE_PROGRAMMA); //setto il titolo della finestra principale
  72. gtk_container_set_border_width(GTK_CONTAINER(finestra1), 3); //setto il bordo della finestra principale
  73. gtk_window_set_resizable(GTK_WINDOW(finestra1), FALSE); //rendo non resizable la finestra principale
  74. g_signal_connect(G_OBJECT(finestra1), "delete_event", G_CALLBACK(gtk_main_quit), NULL);
  75.  
  76. //box
  77. area_box = gtk_hbox_new(FALSE, 1);
  78.  
  79. draw_area = gtk_drawing_area_new();
  80. gtk_widget_set_size_request(draw_area, 640, 400);
  81. gtk_box_pack_start(GTK_BOX(area_box), draw_area, TRUE, TRUE, 0);
  82. g_signal_connect (G_OBJECT (draw_area), "expose_event", G_CALLBACK (expose_event_callback), NULL);
  83. testo_draw_area = gtk_widget_create_pango_layout(draw_area, "PangoLayout");
  84.  
  85. draw_area_sobel = gtk_drawing_area_new();
  86. gtk_widget_set_size_request(draw_area_sobel, 640, 400);
  87. gtk_box_pack_start(GTK_BOX(area_box), draw_area_sobel, TRUE, TRUE, 0);
  88. g_signal_connect (G_OBJECT (draw_area_sobel), "expose_event", G_CALLBACK (expose_event_callback), NULL);
  89.  
  90. gtk_container_add(GTK_CONTAINER(finestra1), area_box);
  91. gtk_widget_show_all(finestra1);
  92.  
  93. g_thread_create((GThreadFunc) webcam, NULL, 0, thread_error);
  94.  
  95. gtk_main();
  96. return EXIT_SUCCESS;
  97. }
  98.  
  99. int webcam(){
  100. long x,y,z,h;
  101. CAPSTATUS status;
  102.  
  103. LPBITMAPINFO video_format;
  104. DWORD dwSize;
  105.  
  106. HWND hwnd = capCreateCaptureWindow("Explorer", WS_ICONIC, 0, 0, 640, 400, NULL, 0);
  107. capDriverConnect(hwnd, 0);
  108. capPreviewRate(hwnd, 66); // rate, in milliseconds
  109. capPreview(hwnd, TRUE); // starts preview
  110. capSetCallbackOnFrame(hwnd, FrameCallbackProc);
  111.  
  112. //video format
  113. dwSize = capGetVideoFormatSize(hwnd);
  114. video_format = (LPBITMAPINFO) malloc (dwSize * sizeof(char));
  115. video_text = (char *) malloc(200 * sizeof(char));
  116. capGetVideoFormat(hwnd, video_format, dwSize);
  117.  
  118. printf("video format: bit per pixel: %d compressione: %d\n", video_format->bmiHeader.biBitCount, video_format->bmiHeader.biCompression);
  119.  
  120. if(video_format->bmiHeader.biBitCount != 16 || video_format->bmiHeader.biCompression != 844715353){
  121. printf("Video format non compatibile.\n");
  122. printf("formati supportati:\n");
  123. printf("1 - 16bit con compressione 844715353\n");
  124. return 0;
  125. }
  126.  
  127. //cap status
  128. capGetStatus(hwnd, &status, sizeof(CAPSTATUS));
  129. printf("cap status: %dx%d preview_status: %d\n", status.uiImageWidth, status.uiImageHeight, status.fLiveWindow);
  130.  
  131. bit24format_size = status.uiImageWidth*status.uiImageHeight*3;
  132. bit24format = new guchar[bit24format_size];
  133. bit24format_sobel = new guchar[bit24format_size];
  134. global_frame_width = status.uiImageWidth;
  135. global_frame_row_size = status.uiImageWidth*2;
  136.  
  137. //creazione tabella di conversione yuy2 to rgb
  138. printf("preparazione tabella yuy2 to rgb... ");
  139. tabella_yuy2_rgb = new unsigned char ***[3];
  140. for(h=0;h<3;h++){
  141. tabella_yuy2_rgb[h] = new unsigned char **[256];
  142. for(x=0;x<256;x++){
  143. tabella_yuy2_rgb[h][x] = new unsigned char *[256];
  144. for(y=0;y<256;y++)
  145. tabella_yuy2_rgb[h][x][y] = new unsigned char[256];
  146. }
  147. }
  148. for(x=0;x<256;x++)
  149. for(y=0;y<256;y++)
  150. for(z=0;z<256;z++){
  151. tabella_yuy2_rgb[0][x][y][z] = char_conversion(abs( x + 1.371*(y - 128) ));
  152. tabella_yuy2_rgb[1][x][y][z] = char_conversion(abs( x - 0.698*(y - 128) - 0.336*(z - 128) ));
  153. tabella_yuy2_rgb[2][x][y][z] = char_conversion(abs( x + 1.732*(z - 128) ));
  154. }
  155. printf("fatto!\n");
  156.  
  157. //inizio visualizzazione immagini
  158. global_time_start = clock();
  159. for(x=0;x<1000;x++){
  160. capGrabFrameNoStop(hwnd);
  161. //Sleep(5);
  162. }
  163.  
  164. capCaptureStop(hwnd);
  165. capSetCallbackOnFrame(hwnd, NULL);
  166. capDriverDisconnect(hwnd);
  167.  
  168. return 1;
  169. }
  170.  
  171. gboolean expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data)
  172. {
  173. gdk_draw_arc (widget->window,
  174. widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
  175. TRUE,
  176. 0, 0, widget->allocation.width, widget->allocation.height,
  177. 0, 64 * 360);
  178. return TRUE;
  179. }
  180.  
  181. LRESULT FrameCallbackProc(HWND hWnd, LPVIDEOHDR frame) {
  182. register long x,y=0, dietro=0;
  183. int Y1, Y2, Cb, Cr;
  184. int vsobel, hsobel;
  185. unsigned char sobel;
  186. float angolo;
  187.  
  188. global_time_current = clock()-global_time_start;
  189. sprintf(video_text, "frame count: %d\ntime: %d ms\navarage frame rate: %.2f",
  190. frame_count, global_time_current, (float)frame_count*1000/global_time_current);
  191.  
  192. for(x=0;x<bit24format_size;){ //frame->lpData[y]
  193. Y1 = frame->lpData[y++];
  194. Cb = frame->lpData[y++];
  195. Y2 = frame->lpData[y++];
  196. Cr = frame->lpData[y++];
  197.  
  198. //***** normal video part
  199. bit24format[x++] = tabella_yuy2_rgb[0][Y1][Cr][Cb]; //red
  200. bit24format[x++] = tabella_yuy2_rgb[1][Y1][Cr][Cb]; //green
  201. bit24format[x++] = tabella_yuy2_rgb[2][Y1][Cr][Cb]; //blue
  202.  
  203. bit24format[x++] = tabella_yuy2_rgb[0][Y2][Cr][Cb]; //red
  204. bit24format[x++] = tabella_yuy2_rgb[1][Y2][Cr][Cb]; //green
  205. bit24format[x++] = tabella_yuy2_rgb[2][Y2][Cr][Cb]; //blue
  206.  
  207. //****** sobel part
  208. if(y > global_frame_row_size && y < frame->dwBytesUsed-global_frame_row_size){
  209. x -= 6;
  210.  
  211. //algoritmo di sobel
  212. hsobel = (int)
  213. frame->lpData[y-6-global_frame_row_size]
  214. - frame->lpData[y-2-global_frame_row_size]
  215. + frame->lpData[y-6] + frame->lpData[y-6]
  216. - frame->lpData[y-2] - frame->lpData[y-2]
  217. + frame->lpData[y-6+global_frame_row_size]
  218. - frame->lpData[y-2+global_frame_row_size]
  219. ;
  220. vsobel = (int)
  221. frame->lpData[y-6-global_frame_row_size]
  222. + frame->lpData[y-4-global_frame_row_size] + frame->lpData[y-4-global_frame_row_size]
  223. + frame->lpData[y-2-global_frame_row_size]
  224. - frame->lpData[y-6+global_frame_row_size]
  225. - frame->lpData[y-4+global_frame_row_size] - frame->lpData[y-4+global_frame_row_size]
  226. - frame->lpData[y-2+global_frame_row_size]
  227. ;
  228. sobel = char_conversion(abs(hsobel) + abs(vsobel));
  229.  
  230. bit24format_sobel[x++] = sobel;
  231. bit24format_sobel[x++] = sobel;
  232. bit24format_sobel[x++] = sobel;
  233.  
  234.  
  235. hsobel = (int)
  236. frame->lpData[y-4-global_frame_row_size]
  237. - frame->lpData[y-global_frame_row_size]
  238. + frame->lpData[y-4] + frame->lpData[y-4]
  239. - frame->lpData[y] - frame->lpData[y]
  240. + frame->lpData[y-4+global_frame_row_size]
  241. - frame->lpData[y+global_frame_row_size]
  242. ;
  243. vsobel = (int)
  244. frame->lpData[y-4-global_frame_row_size]
  245. + frame->lpData[y-2-global_frame_row_size] + frame->lpData[y-2-global_frame_row_size]
  246. + frame->lpData[y-global_frame_row_size]
  247. - frame->lpData[y-4+global_frame_row_size]
  248. - frame->lpData[y-2+global_frame_row_size] - frame->lpData[y-2+global_frame_row_size]
  249. - frame->lpData[y+global_frame_row_size]
  250. ;
  251. sobel = char_conversion(abs(hsobel) + abs(vsobel));
  252.  
  253. bit24format_sobel[x++] = sobel;
  254. bit24format_sobel[x++] = sobel;
  255. bit24format_sobel[x++] = sobel;
  256.  
  257. }
  258. }
  259.  
  260. gdk_draw_rgb_image(draw_area->window,
  261. draw_area->style->fg_gc[GTK_WIDGET_STATE(draw_area)],
  262. 0, 0, 640, 400, GDK_RGB_DITHER_NORMAL,
  263. bit24format, 640 * 3);
  264.  
  265. gdk_draw_rgb_image(draw_area_sobel->window,
  266. draw_area_sobel->style->fg_gc[GTK_WIDGET_STATE(draw_area_sobel)],
  267. 0, 0, 640, 400, GDK_RGB_DITHER_NORMAL,
  268. bit24format_sobel, 640 * 3);
  269.  
  270. pango_layout_set_text(testo_draw_area, video_text, strlen(video_text));
  271. gdk_draw_layout(draw_area->window, draw_area->style->fg_gc[GTK_WIDGET_STATE(draw_area)], 10, 10, testo_draw_area);
  272.  
  273.  
  274. frame_count++;
  275. return (LRESULT) TRUE ;
  276. }
  277.