#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
#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
//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 ************/
//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 /*------------------------------------------*/
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);
/******************************************************************************/
+/** 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, ¢erDist);
+ 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. */
/******************************************************************************/
/** 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);
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:
/******************************************************************************/
+#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.
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);