]> rtime.felk.cvut.cz Git - eurobot/public.git/commitdiff
Image mode added - used on PC to process just one image from file (does not use camer...
authorPetr Kubiznak <kubizpet@fel.cvut.cz>
Sat, 29 May 2010 10:25:49 +0000 (12:25 +0200)
committerPetr Kubiznak <kubizpet@fel.cvut.cz>
Sat, 29 May 2010 10:25:49 +0000 (12:25 +0200)
Threshold correction.

src/camera/rozkuk/rozkuk.cxx

index 1b478ed56960b574952476a2789828fede223573..7bee1f94c7f7d41d01b7c75177498c1b72ed242e 100644 (file)
@@ -39,13 +39,14 @@ extern "C" {
 #define MODE_REALTIME     0x02
 #define MODE_RECOGNIZE    0x04
 #define MODE_WAIT         0x08
+#define MODE_IMAGE                             0x10
 
 // mask of all modes / errors
-#define MASK_MODES        0x0F
+#define MASK_MODES        0x1F
 #define MASK_ERRORS       (~MASK_MODES)
 
 // errors
-#define ERR_MASK_READ_FAILURE 0x10
+#define ERR_MASK_READ_FAILURE 0x20
 
 // default mode in standard session (i.e. on ppc)
 #define START_MODE        MODE_WAIT
@@ -73,6 +74,8 @@ extern "C" {
 #define KEY_r             0x72
 #define KEY_s             0x73
 #define KEY_w             0x77
+#define KEY_PLUS         -0x55
+#define KEY_MINUS        -0x53
 
 // number of frames passed in rozkuk mode before refresh
 #define PASS_FRAMES       0
@@ -82,7 +85,7 @@ extern "C" {
 //default threshold and saturation
 #define THRESHOLD         70      //not used
 #define SATURATION        1.0
-#define THRESHOLD_SHIFT   -10     //improves the automatic threshold by shifting by this value
+#define THRESHOLD_SHIFT   -25     //improves the automatic threshold by shifting by this value
 
 //mask filename pattern
 #ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
@@ -106,7 +109,7 @@ extern "C" {
 
 //camera control system (if true, rozkuk recognizes, else it waits)
 #ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
-#define ORTE_CAMERA_CONTROL camera_control_on
+#define ORTE_CAMERA_CONTROL 1
 #else                     /******************** PPC *******************/
 #define ORTE_CAMERA_CONTROL camera_control_on
 #endif                    /*------------------------------------------*/
@@ -120,11 +123,13 @@ void drawPauseText(IplImage *img);
 void displayProduct(const CvMat *floatMat, int sideConfig, int centerConfig);
 void displayMasksSum(const CvMat *mat1, const CvMat *mat2, const char *windowName);
 void displayFloatMat(const CvMat *floatMat, const char *windowName);
+int getParamI(int argc, char *argv[], char *imgFilename);
+int modeImage(char *imageFilename);
 int modeRealtime(CvCapture* capture);
 #endif                    /*----------- DEBUG SESSION ONLY -----------*/
 int modeRecognize(CvCapture* capture, CORBA_octet currentColor);
 int modeWait(CvCapture *capture);
-int modeManager(int defaultMode);
+int modeManager(int defaultMode, char *paramC=NULL);
 int countThreshold(const IplImage *frame);
 int recognize(const CvMat *frame, CvMat **masks, int masksCnt, double *resDist=NULL);
 int loadMask(const char *filename, CvMat **mask);
@@ -233,6 +238,61 @@ void displayFloatMat(const CvMat *floatMat, const char *windowName) {
 
 /******************************************************************************/
 
+/** Simulates MODE_RECOGNIZE over one specified image filename.
+  * @return Code of mode to switch to. */
+int modeImage(char *imageFilename) {
+       int thr_change = 0;
+       IplImage *frame = NULL;                               // frame from camera
+       IplImage *thresFrame = cvCreateImage(cvSize(FRAME_WIDTH,FRAME_HEIGHT),IPL_DEPTH_8U,1);    //thresholded frame
+       CvMat *floatMat = NULL;                               // float <-1,1> image of the frame
+       int sideConfig, centerConfig;                         // indices of recognized configurations
+       double sideDist, centerDist;                          // distances between the best and second best results
+       
+       frame = cvLoadImage(imageFilename);
+       if(!frame) {
+               fprintf(stderr, "File %s cannot be loaded as image.\n", imageFilename);
+               return MODE_QUIT;
+       }
+
+       while(1) {
+               int threshold = countThreshold(frame) + THRESHOLD_SHIFT + thr_change;
+               if(threshold<0) threshold=0;
+               clr2float(frame, &floatMat, threshold, SATURATION, thresFrame);
+               //recognize side and center configurations
+               sideConfig = recognize(floatMat, sideMasks, SIDEMASKSCNT, &sideDist);
+               centerConfig = recognize(floatMat, centerMasks, CENTERMASKSCNT, &centerDist);
+               fprintf(stderr, "SINGLE:   thr: %3d (thr_change %d), side: %d (%.2f), center: %d (%.2f)\n", threshold, thr_change, sideConfig, sideDist, centerConfig, centerDist);
+
+               displayProduct(floatMat, sideConfig, centerConfig);
+               cvShowImage(WINDOW_ORIG, frame);                    // show image (! Do not release the frame !)
+               cvShowImage(WINDOW_THRES, thresFrame);
+               displayMasksSum(sideMasks[sideConfig], centerMasks[centerConfig], WINDOW_MASK);  // display selected mask
+               cvReleaseMat(&floatMat);
+
+               /* keyboard events handeling */
+               switch((char)(cvWaitKey(0) & 0xFF)) {               // wait infinitely for an event
+               // increment threshold
+               case KEY_PLUS:
+                       thr_change++;
+                       break;
+               // decrement threshold
+               case KEY_MINUS:
+                       thr_change--;
+                       break;
+               // quit
+               case KEY_ESC:
+                       goto QUIT;
+                       break;
+               }
+       }
+QUIT:
+       cvReleaseImage(&thresFrame);
+       cvReleaseImage(&frame);
+       return MODE_QUIT;
+}
+
+/******************************************************************************/
+
 /** Displays a real video in a window (only for DEBUG session).
  * @param capture Pointer to a camera capture.
  * @return Code of mode to switch to. */
@@ -430,15 +490,16 @@ int modeWait(CvCapture *capture) {
 /******************************************************************************/
 
 /** Switches between modes of the program.
- * @param defaultMode The first mode to run. */
-int modeManager(int defaultMode) {
+ * @param defaultMode The first mode to run. 
+ * @param paramC Used only in MODE_IMAGE mode. */
+int modeManager(int defaultMode, char *paramC) {
        int mode=defaultMode;
        int ret;
        CvCapture* capture;
        CORBA_octet color;
 
        // connect to a camera
-       while(!((capture=cvCaptureFromCAM(0)) || (capture=cvCaptureFromCAM(1)))) {
+       while(!((capture=cvCaptureFromCAM(0)) || (capture=cvCaptureFromCAM(1)) || (defaultMode==MODE_IMAGE))) {
                fprintf(stderr, "NULL capture (is camera connected?)\n");
                orte.camera_result.error |= camera_ERR_NO_VIDEO;
                ORTEPublicationSend(orte.publication_camera_result);
@@ -462,6 +523,20 @@ int modeManager(int defaultMode) {
                        cvDestroyWindow(WINDOW_THRES);
                        mode = modeRealtime(capture);
                        break;
+                       
+               case MODE_IMAGE:
+                       cvNamedWindow(WINDOW_THRES, CV_WINDOW_AUTOSIZE);
+                       cvMoveWindow(WINDOW_THRES, cvQueryFrame(capture)->width, 0);
+                       cvNamedWindow(WINDOW_MASK, CV_WINDOW_AUTOSIZE);
+                       cvMoveWindow(WINDOW_MASK, 0, cvQueryFrame(capture)->height+50);
+                       cvNamedWindow(WINDOW_PROD, CV_WINDOW_AUTOSIZE);
+                       cvMoveWindow(WINDOW_PROD, cvQueryFrame(capture)->width, cvQueryFrame(capture)->height+50);
+                       //load masks and run recognition mode, then free masks (they are in memory only while in recognition mode)
+                       color = robot_switches_color;
+                       if((ret=loadMasks((color==BLUE ? clBLUE : clYELLOW)))) return ret;
+                       mode = modeImage(paramC);
+                       freeMasks();
+                       break;
 #endif                    /*----------- DEBUG SESSION ONLY -----------*/
 
                case MODE_RECOGNIZE:
@@ -532,6 +607,32 @@ int recognize(const CvMat *frame, CvMat **masks, int masksCnt, double *resDist)
 
 /******************************************************************************/
 
+#ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
+/** If "-i filename" is in argv, filename is stored to imgFilename.
+  * @return True if "-i filename" specified, else false. */
+int getParamI(int argc, char *argv[], char *imgFilename) {
+       char opt;
+       
+       // scan for program arguments
+       while((opt = getopt(argc, argv, "i:")) != -1) {
+               switch (opt) {
+               case 'i':
+                       if(optarg) sprintf(imgFilename, "%s", optarg);    //image filename
+                       else {
+                               fprintf(stderr, "Specify image filename to process: rozkuk -i filename\n");
+                               return -1;
+                       }
+                       return 1;
+                       break;
+               }
+       }
+
+       return 0;
+}
+#endif                    /*----------- DEBUG SESSION ONLY -----------*/
+
+/******************************************************************************/
+
 /** Loads binary (float) data to *mask from file.
  * @param filename Path to file to read.
  * @param mask Address of array, where to alloc memory and store the data.
@@ -674,6 +775,12 @@ int main(int argc, char *argv[]) {
        robottype_subscriber_camera_control_create(&orte, rcv_cmr_ctrl_cb, &orte);
        robottype_subscriber_robot_switches_create(&orte, rcv_robot_switches_cb, &orte);
        
+#ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
+       // if "-i filename" specified, program processes only the one image and terminates
+       char imgFilename[100];
+       if(getParamI(argc, argv, imgFilename)) return modeManager(MODE_IMAGE, imgFilename);
+#endif                    /*----------- DEBUG SESSION ONLY -----------*/
+
        modeManager(START_MODE);
 
        ret = robottype_roboorte_destroy(&orte);