//el indx dice que zona es, indx = 1...4 Point2f getAreaCenter(RotatedRect& rect, int indx){ Point2f aux(0,0); if (abs(rect.angle)<1) { aux.x = ((indx == 1 || indx == 3) ? rect.center.x-rect.size.width/4 : rect.center.x+rect.size.width/4); aux.y = ((indx == 1 || indx == 2) ? rect.center.y-rect.size.height/4 : rect.center.y+rect.size.height/4); } else { CvPoint2D32f boxPoints[4]; RotatedRect box2(rect.center,cv::Size(rect.size.width/2,rect.size.height/2),-rect.angle+90); cvBoxPoints(CvBox2D(box2), boxPoints); if (indx == 1) { aux.x = (double)boxPoints[1].x; aux.y = (double)boxPoints[1].y; } else if(indx == 2){ aux.x = (double)boxPoints[2].x; aux.y = (double)boxPoints[2].y; } else if(indx == 3){ aux.x = (double)boxPoints[0].x; aux.y = (double)boxPoints[0].y; } else if(indx == 4){ aux.x = (double)boxPoints[3].x; aux.y = (double)boxPoints[3].y; } else CV_Assert(false); } return aux; }
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void DrawBox(const cv::RotatedRect &R, cv::Scalar color, IplImage *colorop) { CvPoint2D32f Rvts[4]; cvBoxPoints(R,Rvts); int thickness=5; cvLine(colorop,R2Ipnt(Rvts[0]),R2Ipnt(Rvts[1]),color,thickness); cvLine(colorop,R2Ipnt(Rvts[1]),R2Ipnt(Rvts[2]),color,thickness); cvLine(colorop,R2Ipnt(Rvts[2]),R2Ipnt(Rvts[3]),color,thickness); cvLine(colorop,R2Ipnt(Rvts[3]),R2Ipnt(Rvts[0]),color,thickness); }
void * cvBox(CvBox2D box, IplImage *image, CvScalar color, int thickness) { CvPoint2D32f pt[4]; cvBoxPoints(box, pt); for(int i = 0; i < 4; i++) { cvLine(image, cvPointFrom32f(pt[i]), cvPointFrom32f(pt[(i+1)%4]), color, thickness); cvCircle(image, cvPointFrom32f(pt[i]), thickness, cvScalarAll((255/4)*i), -1); } }
// the function draws all the squares in the image void drawSquares(IplImage* imgSrc, CvSeq* squares) { CvSeqReader reader; IplImage* imgCopy = cvCloneImage(imgSrc); int i; // initialize reader of the sequence cvStartReadSeq(squares, &reader, 0); // read 4 sequence elements at a time (all vertices of a square) printf("Found %d rectangles in image\n", squares->total / 4); for (i = 0; i < squares->total; i += 4) { CvPoint* pntRect = gPnt; int pntCount = 4; CvSeq* seqRect = cvCreateSeq(CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), gStorage); // read 4 vertices memcpy(gPnt, reader.ptr, squares->elem_size); CV_NEXT_SEQ_ELEM(squares->elem_size, reader); cvSeqPush(seqRect, &pntRect[0]); memcpy(gPnt + 1, reader.ptr, squares->elem_size); CV_NEXT_SEQ_ELEM(squares->elem_size, reader); cvSeqPush(seqRect, &pntRect[1]); memcpy(gPnt + 2, reader.ptr, squares->elem_size); CV_NEXT_SEQ_ELEM(squares->elem_size, reader); cvSeqPush(seqRect, &pntRect[2]); memcpy(gPnt + 3, reader.ptr, squares->elem_size); CV_NEXT_SEQ_ELEM(squares->elem_size, reader); cvSeqPush(seqRect, &pntRect[3]); // draw the square as a closed polyline cvPolyLine(imgCopy, &pntRect, &pntCount, 1, 1, CV_RGB(0, 255, 0), 1, CV_AA, 0); // draw the min outter rect CvBox2D box = cvMinAreaRect2(seqRect, NULL); CvPoint2D32f ptBox[4]; cvBoxPoints(box, ptBox); for(int i = 0; i < 4; ++i) { cvLine(imgCopy, cvPointFrom32f(ptBox[i]), cvPointFrom32f(ptBox[((i+1)%4)?(i+1):0]), CV_RGB(255,0,0)); } } // show the resultant image cvShowImage(wndname, imgCopy); cvReleaseImage(&imgCopy); }
void cvMinAreaRect( CvPoint* points, int n, int, int, int, int, CvPoint2D32f* anchor, CvPoint2D32f* vect1, CvPoint2D32f* vect2 ) { CvMat mat = cvMat( 1, n, CV_32SC2, points ); CvBox2D box = cvMinAreaRect2( &mat, 0 ); CvPoint2D32f pt[4]; cvBoxPoints( box, pt ); *anchor = pt[0]; vect1->x = pt[1].x - pt[0].x; vect1->y = pt[1].y - pt[0].y; vect2->x = pt[3].x - pt[0].x; vect2->y = pt[3].y - pt[0].y; }
/* * call-seq: * points -> array(include cvpoint2d32f) * Find box vertices. Return Array contain 4 CvPoint2D32f. */ VALUE rb_points(VALUE self) { const int n = 4; CvPoint2D32f p[n]; try { cvBoxPoints(*CVBOX2D(self), p); } catch (cv::Exception& e) { raise_cverror(e); } VALUE points = rb_ary_new2(n); for (int i = 0; i < n; ++i) rb_ary_store(points, i, cCvPoint2D32f::new_object(p[i])); return points; }
//在图像srcImg上根据contour轮廓画上最小外接矩形 CvBox2D DrawMinAreaRect(IplImage *srcImg,CvSeq *contour,CvScalar color/*=CV_RGB(255,0,0)*/) { CvBox2D box=cvMinAreaRect2(contour); CvPoint2D32f box_vtx[4]; CvPoint pt0, pt; cvBoxPoints( box, box_vtx ); pt0.x = cvRound(box_vtx[3].x); pt0.y = cvRound(box_vtx[3].y); for(int i = 0; i < 4; i++ ) { pt.x = cvRound(box_vtx[i].x); pt.y = cvRound(box_vtx[i].y); cvLine(srcImg, pt0, pt, color, 1, CV_AA, 0); pt0 = pt; } return box; }
void drawRotatedRect(Mat& img, const RotatedRect& rect, CvScalar color, int thickness){ if (abs(rect.angle)<1) { rectangle(img, Point2i(rect.center.x-rect.size.width/2,rect.center.y-rect.size.height/2), Point2i(rect.center.x+rect.size.width/2,rect.center.y+rect.size.height/2), color, thickness); } else { RotatedRect box(rect.center,rect.size,-rect.angle+90); CvPoint2D32f boxPoints[4]; cvBoxPoints(CvBox2D(box), boxPoints); line(img,Point2f((int)boxPoints[0].x, (int)boxPoints[0].y), Point2f((int)boxPoints[1].x, (int)boxPoints[1].y),color,thickness); line(img,Point2f((int)boxPoints[1].x, (int)boxPoints[1].y), Point2f((int)boxPoints[2].x, (int)boxPoints[2].y),color,thickness); line(img,Point2f((int)boxPoints[2].x, (int)boxPoints[2].y), Point2f((int)boxPoints[3].x, (int)boxPoints[3].y),color,thickness); line(img,Point2f((int)boxPoints[3].x, (int)boxPoints[3].y), Point2f((int)boxPoints[0].x, (int)boxPoints[0].y),color,thickness); } }
static void draw_box(IplImage *image, CvBox2D box, double color) { CvPoint2D32f boxPoints[4]; /* CamShift seems to get this backwards */ box.angle = -box.angle; cvBoxPoints(box, boxPoints); cvLineAA(image, cvPoint((int)boxPoints[0].x, (int)boxPoints[0].y), cvPoint((int)boxPoints[1].x, (int)boxPoints[1].y), color); cvLineAA(image, cvPoint((int)boxPoints[1].x, (int)boxPoints[1].y), cvPoint((int)boxPoints[2].x, (int)boxPoints[2].y), color); cvLineAA(image, cvPoint((int)boxPoints[2].x, (int)boxPoints[2].y), cvPoint((int)boxPoints[3].x, (int)boxPoints[3].y), color); cvLineAA(image, cvPoint((int)boxPoints[3].x, (int)boxPoints[3].y), cvPoint((int)boxPoints[0].x, (int)boxPoints[0].y), color); }
IplImage* BouyBaseObject::GetMask(const IplImage * imgIn, IplImage * debugOut) const { if(imgIn == NULL) return NULL; IplImage* colormask = NULL; IplImage* gvcolormask = NULL; //IplImage* shapemask = ShapeMask(imgIn); IplImage* segmentationmask = NULL; IplImage* histogrammask = NULL; //IplImage* edgemask = EdgeMask(imgIn); IplImage* templatemask = NULL; // if(colormask == NULL || shapemask == NULL || // segmentationmask== NULL || histogrammask == NULL || // edgemask == NULL ) return NULL; //cvShowImage("colormask", colormask); //cvShowImage("channelmask", channelmask); IplImage * imgOut = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage * threshold = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); cvZero(imgOut); if(mEnableHist) { histogrammask = HistogramMask(imgIn); } if(mEnableColor) { colormask = ColorMask(imgIn); } if(mEnableSegment) { segmentationmask = SegmentationMask(imgIn); } if(mEnableGVColor) { gvcolormask = GVColorMask(imgIn); } int count = 1; if(VisionUtils::CombineMasks(imgOut,histogrammask,imgOut,count,mHistWeight)) { count++; } if(VisionUtils::CombineMasks(imgOut,colormask,imgOut, count, mColorWeight)) { count++; } if(VisionUtils::CombineMasks(imgOut,segmentationmask,imgOut,count,mSegmentWeight)) { count++; } if(VisionUtils::CombineMasks(imgOut,gvcolormask,imgOut,count,mGVColorWeight)) { count++; } //VisionUtils::CombineMasks(imgOut,edgemask,imgOut,2,1); //VisionUtils::CombineMasks(imgOut,histogrammask,imgOut,2,1); cvNormalize(imgOut,imgOut,255,0,CV_MINMAX); if(mDebug) { cvShowImage("combined", imgOut); } cvThreshold(imgOut,threshold,mMainThreshold,255,CV_THRESH_BINARY ); std::list<CvBox2D> blobList; blobList = Zebulon::Vision::VisionUtils::GetBlobBoxes(threshold,0,mMinNoiseSizePercent); for(std::list<CvBox2D>::iterator it = blobList.begin(); it != blobList.end(); it++) { CvPoint2D32f boxCorners32[4]; CvPoint boxCorners[4]; cvBoxPoints(*it,boxCorners32); for(int i = 0; i < 4; i ++) { boxCorners[i] = cvPointFrom32f(boxCorners32[i]); } cvFillConvexPoly(threshold,boxCorners,4,cvScalar(0,0,0),4); //Zebulon::Vision::VisionUtils::DrawSquare(imgOut,*it); } //shapemask = FindCircles(imgOut); imgOut = TemplateMask(imgOut, threshold, mTemplate); //VisionUtils::CombineMasks(imgOut,templatemask,imgOut); if(mDebug) { cvShowImage("clean", threshold); cvShowImage("final", imgOut); cvShowImage("color", colormask); cvShowImage("hist", histogrammask); cvShowImage("segment", segmentationmask); cvShowImage("template", templatemask); cvShowImage("gvcolor", gvcolormask); } cvReleaseImage(&colormask); //cvReleaseImage(&shapemask); cvReleaseImage(&segmentationmask); cvReleaseImage(&histogrammask); cvReleaseImage(&gvcolormask); //cvReleaseImage(&edgemask); return imgOut; }
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; }
int main( int argc, char** argv ) { IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ); #if !ARRAY CvMemStorage* storage = cvCreateMemStorage(0); #endif cvNamedWindow( "rect & circle", 1 ); for(;;) { char key; int i, count = rand()%100 + 1; CvPoint pt0, pt; CvBox2D box; CvPoint2D32f box_vtx[4]; CvPoint2D32f center; CvPoint icenter; float radius; #if !ARRAY CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage ); for( i = 0; i < count; i++ ) { pt0.x = rand() % (img->width/2) + img->width/4; pt0.y = rand() % (img->height/2) + img->height/4; cvSeqPush( ptseq, &pt0 ); } #ifndef _EiC /* unfortunately, here EiC crashes */ box = cvMinAreaRect2( ptseq, 0 ); #endif cvMinEnclosingCircle( ptseq, ¢er, &radius ); #else CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0])); CvMat pointMat = cvMat( 1, count, CV_32SC2, points ); for( i = 0; i < count; i++ ) { pt0.x = rand() % (img->width/2) + img->width/4; pt0.y = rand() % (img->height/2) + img->height/4; points[i] = pt0; } #ifndef _EiC box = cvMinAreaRect2( &pointMat, 0 ); #endif cvMinEnclosingCircle( &pointMat, ¢er, &radius ); #endif cvBoxPoints( box, box_vtx ); cvZero( img ); for( i = 0; i < count; i++ ) { #if !ARRAY pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i ); #else pt0 = points[i]; #endif cvCircle( img, pt0, 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 ); } #ifndef _EiC pt0.x = cvRound(box_vtx[3].x); pt0.y = cvRound(box_vtx[3].y); for( i = 0; i < 4; i++ ) { pt.x = cvRound(box_vtx[i].x); pt.y = cvRound(box_vtx[i].y); cvLine(img, pt0, pt, CV_RGB(0, 255, 0), 1, CV_AA, 0); pt0 = pt; } #endif icenter.x = cvRound(center.x); icenter.y = cvRound(center.y); cvCircle( img, icenter, cvRound(radius), CV_RGB(255, 255, 0), 1, CV_AA, 0 ); cvShowImage( "rect & circle", img ); key = (char) cvWaitKey(0); if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC' break; #if !ARRAY cvClearMemStorage( storage ); #else free( points ); #endif } cvDestroyWindow( "rect & circle" ); return 0; }