PageRenderTime 63ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/main_v3_SetForOpenCV.cpp

https://bitbucket.org/lokisnake/setopencv
C++ | 237 lines | 228 code | 4 blank | 5 comment | 0 complexity | a188e10f2247d16002a4553f4621d0da MD5 | raw file
  1. /*
  2. * OpenCV application
  3. *
  4. */
  5. #ifdef _WIN32
  6. #include "stdafx.h"
  7. #endif
  8. #include "cxcore.h" // basic OpenCV data structures
  9. #include "cv.h" // basic OpenCV algorithms
  10. #include "highgui.h" // OpenCV's (limited) display and event-handling routines
  11. #include <cstdio> // epic C-style I/O; feel free to change to iostream...
  12. #include <time.h> // to compute frames per second
  13. enum CAP_SOURCE { GET_IMAGES_FROM_CAMERA, GET_IMAGES_FROM_FILE, GET_IMAGES_FROM_VIDEO };
  14. using namespace std; // aargh!
  15. // GLOBALS - there's no avoiding them in OpenCV
  16. #ifdef _WIN32 /* Windows */
  17. const char* IMAGES_DIRECTORY = "..\\SetOpenCV\\setImages_v1\\";
  18. #else /* Mac OS X */
  19. const char* IMAGES_DIRECTORY = "../../setImages_v1/";
  20. #endif
  21. const char* RAW_IMAGE_NAME = "Raw Image";
  22. const char* DRAW_IMAGE_NAME = "Drawing Image";
  23. const char* BINARY_IMAGE_NAME = "Binary Image";
  24. const char* COLOR_TRACKBAR_WINDOW = "Color Thresholds";
  25. char BUFFER[1024]; // general-purpose string buffer for filenames, printing, etc.
  26. // IMAGES
  27. IplImage* source_frame = NULL;
  28. IplImage* raw_image = NULL;
  29. IplImage* draw_image = NULL;
  30. IplImage* binary_image = NULL;
  31. // STATE
  32. int IMAGE_SOURCE = GET_IMAGES_FROM_CAMERA; // GET_IMAGES_FROM_FILE, GET_IMAGES_FROM_VIDEO
  33. int rectangle_selection = 0; // 0 == no drawing, 1 == need 1st pt, 2 == need 2nd pt.
  34. int rectangle_ul[2], rectangle_lr[2]; // the opposing-corner selection pts (need not be ul/lr)
  35. // THRESHOLDS
  36. int RedLow = 100; int GreenLow = 100; int BlueLow = 100;
  37. int RedHigh = 200; int GreenHigh = 200; int BlueHigh = 200;
  38. // NETWORKING-SPECIFIC DATA
  39. enum SERVER_MESSAGES { SERVER_RUN, SERVER_QUIT };
  40. int server_control = SERVER_RUN; // global value available to control the server's state
  41. // Helper Functions
  42. #include "pixel_access.h" // get_rgb_pixel, set_rgb_pixel, get_gs_pixel, set_gs_pixel
  43. #include "image_handling.h" // ensure_image_size
  44. #include "file_handling.h" // check_for_file
  45. #ifdef _WIN32 // are we on Windows?
  46. #include "socket_handling_win.h" // start_vision_server (for windows)
  47. #else
  48. #include "socket_handling_mac.h" // start_vision_server (for Mac OS X -- maybe Linux, but haven't tested it)
  49. #endif
  50. // onMouse is the function for handling mouse events
  51. //
  52. void onMouse(int event, int x, int y, int flags, void* param) // handle mouse events
  53. {
  54. if (!rectangle_selection && event == CV_EVENT_LBUTTONDOWN) // print single-pixel data
  55. {
  56. int r,g,b,gs;
  57. get_rgb_pixel (raw_image, x, y, r, g, b); // get the pixel from raw_inage
  58. get_gs_pixel (binary_image, x, y, gs); // get the pixel from binary_inage
  59. printf ("pixel at (%d,%d) is (%3d,%3d,%3d) and in binary is %3d.\n", x, y, r, g, b, gs);
  60. }
  61. if (rectangle_selection && event == CV_EVENT_LBUTTONDOWN) // starts and ends a rectangle_selection
  62. {
  63. if (rectangle_selection == 1) { rectangle_ul[0] = x; rectangle_ul[1] = y; rectangle_selection=2; }
  64. else if (rectangle_selection == 2) { rectangle_lr[0] = x; rectangle_lr[1] = y; rectangle_selection=1; }
  65. }
  66. if (rectangle_selection == 2 && event == CV_EVENT_MOUSEMOVE) // move a rectangle_selection around
  67. {
  68. rectangle_lr[0] = x; rectangle_lr[1] = y;
  69. }
  70. return;
  71. }
  72. // main sets everything up and runs a "grab-process-show" loop
  73. //
  74. int main (int argc, char * const argv[])
  75. {
  76. // start the vision server - comment this out for no networking...
  77. server_thread();
  78. // set up all of the windows and position them
  79. cvNamedWindow (RAW_IMAGE_NAME, CV_WINDOW_AUTOSIZE); cvMoveWindow (RAW_IMAGE_NAME,20,20);
  80. cvNamedWindow (DRAW_IMAGE_NAME, CV_WINDOW_AUTOSIZE); cvMoveWindow (DRAW_IMAGE_NAME,700,20);
  81. cvNamedWindow (BINARY_IMAGE_NAME, CV_WINDOW_AUTOSIZE); cvMoveWindow (BINARY_IMAGE_NAME,20,500);
  82. cvNamedWindow (COLOR_TRACKBAR_WINDOW, CV_WINDOW_AUTOSIZE); cvMoveWindow (COLOR_TRACKBAR_WINDOW,700,500);
  83. // trackbars are great!
  84. cvCreateTrackbar ( "RedLow", COLOR_TRACKBAR_WINDOW, &RedLow, 255, NULL /* callback for motion */ );
  85. cvCreateTrackbar ( "RedHigh", COLOR_TRACKBAR_WINDOW, &RedHigh, 255, NULL /* callback for motion */ );
  86. cvCreateTrackbar ( "GreenLow", COLOR_TRACKBAR_WINDOW, &GreenLow, 255, NULL /* callback for motion */ );
  87. cvCreateTrackbar ( "GreenHigh", COLOR_TRACKBAR_WINDOW, &GreenHigh, 255, NULL /* callback for motion */ );
  88. cvCreateTrackbar ( "BlueLow", COLOR_TRACKBAR_WINDOW, &BlueLow, 255, NULL /* callback for motion */ );
  89. cvCreateTrackbar ( "BlueHigh", COLOR_TRACKBAR_WINDOW, &BlueHigh, 255, NULL /* callback for motion */ );
  90. int close_iterations = 1; // number of times to dilate before eroding for the morphological closing
  91. cvCreateTrackbar ( "Iters", COLOR_TRACKBAR_WINDOW, &close_iterations, 10, NULL /* callback for motion */ );
  92. cvSetMouseCallback (RAW_IMAGE_NAME, onMouse, NULL); // mouse events handled from the raw_image window
  93. CvCapture* source = cvCreateCameraCapture (CV_CAP_ANY); // check if there is a camera available
  94. printf ("You %s have a camera.\n", source ? "do" : "don't"); // report the results to the console...
  95. CvFont font_structure; // how OpenCV holds its fonts
  96. cvInitFont ( &font_structure, CV_FONT_HERSHEY_PLAIN, 1.0 /* hscale */, 1.0 /* vscale */ );
  97. clock_t last_clock_ticks = clock(); // previous ticks since program started
  98. clock_t clock_ticks = last_clock_ticks + 1; // current ticks since program started
  99. double fps = 1.0; // frames per second
  100. int image_index_to_view = 0; // image index to grab from IMAGES_DIRECTORY
  101. // the "grab-process-show" loop: until 'q' or ESC is pressed ...
  102. //
  103. while (true)
  104. {
  105. clock_ticks = clock(); // get the number of clock ticks
  106. fps = CLOCKS_PER_SEC/double(clock_ticks - last_clock_ticks); // compute fps
  107. last_clock_ticks = clock_ticks; // reset the old value
  108. if (source && IMAGE_SOURCE == GET_IMAGES_FROM_CAMERA) // grab source_frame from CAMERA
  109. {
  110. source_frame = cvQueryFrame (source); // grab camera frame
  111. ensure_image_size (raw_image, source_frame, 3 ); // make sure raw_image is the same size
  112. cvFlip (source_frame, raw_image, 1); // need to flip from camera to raw_image
  113. }
  114. else // grab source_frame from FILE
  115. {
  116. strcpy (BUFFER, IMAGES_DIRECTORY); // print directory name to BUFFER
  117. sprintf (BUFFER+strlen(BUFFER), // then append ...
  118. "image%05d.bmp", image_index_to_view); // ... the filename
  119. if (file_is_present (BUFFER)) // from file_handling.h
  120. source_frame = cvLoadImage( BUFFER ); // grab the file if it's present
  121. else if (source_frame != NULL)
  122. cvZero (source_frame); // no file? zero out old source_frame
  123. else
  124. source_frame = cvCreateImage( cvSize(100,100), IPL_DEPTH_8U, 3); // nothing at all? default value.
  125. ensure_image_size (raw_image, source_frame, 3 ); // make sure raw_image is the same size
  126. cvCopy ( source_frame, raw_image ); // copy into raw_image
  127. }
  128. ensure_image_size (draw_image, raw_image, 3 /* rgb */ ); // make sure draw_image is the right size
  129. ensure_image_size (binary_image, raw_image, 1 /* gs */ ); // make sure binary_image is the right size
  130. // we will start draw_image as a copy of raw_image
  131. cvCopy (raw_image, draw_image);
  132. // go through and change some pixels to all red - just to show how to access individual pixels...
  133. for (int row=draw_image->height-25 ; row < draw_image->height ; ++row ) {
  134. for (int col=draw_image->width-125 ; col < draw_image->width ; ++col ) {
  135. set_rgb_pixel (draw_image, col, row, 255 /* red */, 0 /* green */, 0 /* blue */);
  136. }
  137. }
  138. // write text on top of draw_image
  139. sprintf (BUFFER, "%4.1f", fps); // print the frames per second on the image
  140. cvPutText (draw_image, BUFFER, cvPoint(draw_image->width-100,draw_image->height-10), &font_structure, CV_RGB(255,255,0));
  141. // draw shapes on top of draw_image
  142. if (rectangle_selection == 2) // draw the selection rectangle as it's being defined
  143. {
  144. int ulx = rectangle_ul[0], uly = rectangle_ul[1], lrx = rectangle_lr[0], lry = rectangle_lr[1];
  145. printf ("Rectangle: %d, %d, %d, %d\n", ulx, uly, lrx, lry);
  146. cvRectangle (draw_image, cvPoint(ulx,uly), cvPoint(lrx,lry), CV_RGB(255,255,0), 2 /* thickness */ );
  147. }
  148. // create a binary_image
  149. CvScalar lowerb = cvScalar (BlueLow, GreenLow, RedLow); // lower-bound thresholds
  150. CvScalar upperb = cvScalar (BlueHigh, GreenHigh, RedHigh); // upper-bound thresholds
  151. cvInRangeS (raw_image, lowerb, upperb, binary_image); // this thresholds between them
  152. // erode and dilate can be done in-place (src and dst are both binary_image)
  153. cvDilate (binary_image, binary_image, NULL /* default 3x3 square mask */, close_iterations /* iterations */);
  154. cvErode (binary_image, binary_image, NULL /* default 3x3 square mask */, close_iterations /* iterations */);
  155. // show images
  156. cvShowImage (RAW_IMAGE_NAME, raw_image);
  157. cvShowImage (DRAW_IMAGE_NAME, draw_image);
  158. cvShowImage (BINARY_IMAGE_NAME, binary_image);
  159. // handle key press events - cvWaitKey is necessary to handle ALL events, as well!
  160. int key = cvWaitKey (10); // 10 milliseconds of waiting, I think
  161. //
  162. if (key == 'q' || key == 'Q' || key == 27) // quit the application, key 27 is ESC
  163. {
  164. break;
  165. }
  166. if (key == 'f' || key == 'F' ) // save the image to file
  167. {
  168. strcpy (BUFFER, IMAGES_DIRECTORY); // directory
  169. strcat (BUFFER, "img.bmp"); // plus filename
  170. cvSaveImage (BUFFER, raw_image); // saves it
  171. printf ("Image saved in %s\n", BUFFER);
  172. }
  173. if (key == 's' || key == 'S' ) // switch the image source
  174. {
  175. IMAGE_SOURCE = (GET_IMAGES_FROM_CAMERA == IMAGE_SOURCE) ? GET_IMAGES_FROM_FILE : GET_IMAGES_FROM_CAMERA;
  176. printf("Switching to IMAGE_SOURCE %d.\n", IMAGE_SOURCE);
  177. }
  178. if (key == 'c' || key == 'C' ) // print our color thresholds
  179. {
  180. printf ("Thresholds: Red: %3d -> %3d\n", RedLow, RedHigh);
  181. printf (" Green: %3d -> %3d\n", GreenLow, GreenHigh);
  182. printf (" Blue: %3d -> %3d\n", BlueLow, BlueHigh);
  183. }
  184. if (key == ' ' || key == 'B') // cycle forward (spacebar) or backward 'B' through the images
  185. {
  186. image_index_to_view += key == ' ' ? 1 : -1; // add or subtract 1
  187. if (image_index_to_view < 0) image_index_to_view = 0; // can't go less than 0
  188. }
  189. if (key == 'R') // turn on or off rectangle selection
  190. {
  191. if (rectangle_selection) { rectangle_selection = 0; /* turn off rectangle selection */ }
  192. else { rectangle_selection = 1; /* looking for first corner */ }
  193. printf("Rectangle drawing is %d.\n", rectangle_selection );
  194. }
  195. if (key == '-')
  196. {
  197. server_control = SERVER_QUIT;
  198. }
  199. } // end of the "grab-process-show" while loop
  200. // return nicely from main...
  201. return 0;
  202. }