// Rotates the box and the underlying blob. void BLOBNBOX::rotate(FCOORD rotation) { cblob_ptr->rotate(rotation); rotate_box(rotation); compute_bounding_box(); }
ColorChecker find_colorchecker(CvSeq * quads, CvSeq * boxes, CvMemStorage *storage, IplImage *image, IplImage *original_image) { CvPoint2D32f box_corners[4]; bool passport_box_flipped = false; bool rotated_box = false; CvMat* points = cvCreateMat( boxes->total , 1, CV_32FC2 ); for(int i = 0; i < boxes->total; i++) { CvBox2D box = (*(CvBox2D*)cvGetSeqElem(boxes, i)); cvSet1D(points, i, cvScalar(box.center.x,box.center.y)); } CvBox2D passport_box = cvMinAreaRect2(points,storage); fprintf(stderr,"Box:\n\tCenter: %f,%f\n\tSize: %f,%f\n\tAngle: %f\n",passport_box.center.x,passport_box.center.y,passport_box.size.width,passport_box.size.height,passport_box.angle); if(passport_box.angle < 0.0) { passport_box_flipped = true; } cvBoxPoints(passport_box, box_corners); // for(int i = 0; i < 4; i++) // { // fprintf(stderr,"Box corner %d: %d,%d\n",i,cvPointFrom32f(box_corners[i]).x,cvPointFrom32f(box_corners[i]).y); // } // cvBox(passport_box, image, cvScalarAll(128), 10); if(euclidean_distance(cvPointFrom32f(box_corners[0]),cvPointFrom32f(box_corners[1])) < euclidean_distance(cvPointFrom32f(box_corners[1]),cvPointFrom32f(box_corners[2]))) { fprintf(stderr,"Box is upright, rotating\n"); rotate_box(box_corners); rotated_box = true && passport_box_flipped; } double horizontal_spacing = euclidean_distance( cvPointFrom32f(box_corners[0]),cvPointFrom32f(box_corners[1]))/(double)(MACBETH_WIDTH-1); double vertical_spacing = euclidean_distance( cvPointFrom32f(box_corners[1]),cvPointFrom32f(box_corners[2]))/(double)(MACBETH_HEIGHT-1); double horizontal_slope = (box_corners[1].y - box_corners[0].y)/(box_corners[1].x - box_corners[0].x); double horizontal_mag = sqrt(1+pow(horizontal_slope,2)); double vertical_slope = (box_corners[3].y - box_corners[0].y)/(box_corners[3].x - box_corners[0].x); double vertical_mag = sqrt(1+pow(vertical_slope,2)); double horizontal_orientation = box_corners[0].x < box_corners[1].x ? -1 : 1; double vertical_orientation = box_corners[0].y < box_corners[3].y ? -1 : 1; fprintf(stderr,"Spacing is %f %f\n",horizontal_spacing,vertical_spacing); fprintf(stderr,"Slope is %f %f\n", horizontal_slope,vertical_slope); int average_size = 0; for(int i = 0; i < boxes->total; i++) { CvBox2D box = (*(CvBox2D*)cvGetSeqElem(boxes, i)); CvRect rect = contained_rectangle(box); average_size += MIN(rect.width, rect.height); } average_size /= boxes->total; fprintf(stderr,"Average contained rect size is %d\n", average_size); CvMat * this_colorchecker = cvCreateMat(MACBETH_HEIGHT, MACBETH_WIDTH, CV_32FC3); CvMat * this_colorchecker_points = cvCreateMat( MACBETH_HEIGHT, MACBETH_WIDTH, CV_32FC2 ); // calculate the averages for our oriented colorchecker for(int x = 0; x < MACBETH_WIDTH; x++) { for(int y = 0; y < MACBETH_HEIGHT; y++) { CvPoint2D32f row_start; if ( ((image->origin == IPL_ORIGIN_BL) || !rotated_box) && !((image->origin == IPL_ORIGIN_BL) && rotated_box) ) { row_start.x = box_corners[0].x + vertical_spacing * y * (1 / vertical_mag); row_start.y = box_corners[0].y + vertical_spacing * y * (vertical_slope / vertical_mag); } else { row_start.x = box_corners[0].x - vertical_spacing * y * (1 / vertical_mag); row_start.y = box_corners[0].y - vertical_spacing * y * (vertical_slope / vertical_mag); } CvRect rect = cvRect(0,0,average_size,average_size); rect.x = row_start.x - horizontal_spacing * x * ( 1 / horizontal_mag ) * horizontal_orientation; rect.y = row_start.y - horizontal_spacing * x * ( horizontal_slope / horizontal_mag ) * vertical_orientation; cvSet2D(this_colorchecker_points, y, x, cvScalar(rect.x,rect.y)); rect.x = rect.x - average_size / 2; rect.y = rect.y - average_size / 2; // cvRectangle( // image, // cvPoint(rect.x,rect.y), // cvPoint(rect.x+rect.width, rect.y+rect.height), // cvScalarAll(0), // 10 // ); CvScalar average_color = rect_average(rect, original_image); cvSet2D(this_colorchecker,y,x,average_color); } } double orient_1_error = check_colorchecker(this_colorchecker); cvFlip(this_colorchecker,NULL,-1); double orient_2_error = check_colorchecker(this_colorchecker); fprintf(stderr,"Orientation 1: %f\n",orient_1_error); fprintf(stderr,"Orientation 2: %f\n",orient_2_error); if(orient_1_error < orient_2_error) { cvFlip(this_colorchecker,NULL,-1); } else { cvFlip(this_colorchecker_points,NULL,-1); } // draw_colorchecker(this_colorchecker,this_colorchecker_points,image,average_size); ColorChecker found_colorchecker; found_colorchecker.error = MIN(orient_1_error,orient_2_error); found_colorchecker.values = this_colorchecker; found_colorchecker.points = this_colorchecker_points; found_colorchecker.size = average_size; return found_colorchecker; }