minAreaRect-OpenCV

来源:互联网 发布:2017科普知识网络竞赛 编辑:程序博客网 时间:2024/05/22 00:06

由于要将rRect利用仿射变换裁剪下来并旋正,需要知道rRect.point()的四个点的位置,查了一下资料,记在下面:

简介:Finds a circumscribed rectangle of the minimal area for 2D point set by building convex hull for the set and applying rotating calipers4 technique to the hull.1 建立外凸包,应用旋转卡尺技术来求2维点的最小面积包围矩形。 
API reference 
OpenCV官方例程

源码: 
OpenCV249\opencv\sources\modules\imgproc\src\contours.cpp 1910行-1916行

cv::RotatedRect cv::minAreaRect( InputArray _points ){    Mat points = _points.getMat();    CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));    CvMat _cpoints = points;    return cvMinAreaRect2(&_cpoints, 0);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

cvMinAreaRect2: 2

http://fossies.org/dox/OpenCV-2.4.4a/rotcalipers_8cpp_source.html 
截取自第347行

 347 CV_IMPL  CvBox2D  348 cvMinAreaRect2( const CvArr* array, CvMemStorage* storage )  349 {  350     cv::Ptr<CvMemStorage> temp_storage;  351     CvBox2D box;  352     cv::AutoBuffer<CvPoint2D32f> _points;  353     CvPoint2D32f* points;  354   355     memset(&box, 0, sizeof(box));  356   357     int i, n;  358     CvSeqReader reader;  359     CvContour contour_header;  360     CvSeqBlock block;  361     CvSeq* ptseq = (CvSeq*)array;  362     CvPoint2D32f out[3];  363   364     if( CV_IS_SEQ(ptseq) )  365     {  366         if( !CV_IS_SEQ_POINT_SET(ptseq) &&  367             (CV_SEQ_KIND(ptseq) != CV_SEQ_KIND_CURVE ||  368             CV_SEQ_ELTYPE(ptseq) != CV_SEQ_ELTYPE_PPOINT ))  369             CV_Error( CV_StsUnsupportedFormat,  370                 "Input sequence must consist of 2d points or pointers to 2d points" );  371         if( !storage )  372             storage = ptseq->storage;  373     }  374     else  375     {  376         ptseq = cvPointSeqFromMat( CV_SEQ_KIND_GENERIC, array, &contour_header, &block );  377     }  378   379     if( storage )  380     {  381         temp_storage = cvCreateChildMemStorage( storage );  382     }  383     else  384     {  385         temp_storage = cvCreateMemStorage(1 << 10);  386     }  387   388     ptseq = cvConvexHull2( ptseq, temp_storage, CV_CLOCKWISE, 1 );  389     n = ptseq->total;  390   391     _points.allocate(n);  392     points = _points;  393     cvStartReadSeq( ptseq, &reader );  394   395     if( CV_SEQ_ELTYPE( ptseq ) == CV_32SC2 )  396     {  397         for( i = 0; i < n; i++ )  398         {  399             CvPoint pt;  400             CV_READ_SEQ_ELEM( pt, reader );  401             points[i].x = (float)pt.x;  402             points[i].y = (float)pt.y;  403         }  404     }  405     else  406     {  407         for( i = 0; i < n; i++ )  408         {  409             CV_READ_SEQ_ELEM( points[i], reader );  410         }  411     }  412   413     if( n > 2 )  414     {  415         icvRotatingCalipers( points, n, CV_CALIPERS_MINAREARECT, (float*)out );  416         box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f;  417         box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f;  418         box.size.width = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y);  419         box.size.height = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y);  420         box.angle = (float)atan2( (double)out[1].y, (double)out[1].x );  421     }  422     else if( n == 2 )  423     {  424         box.center.x = (points[0].x + points[1].x)*0.5f;  425         box.center.y = (points[0].y + points[1].y)*0.5f;  426         double dx = points[1].x - points[0].x;  427         double dy = points[1].y - points[0].y;  428         box.size.width = (float)sqrt(dx*dx + dy*dy);  429         box.size.height = 0;  430         box.angle = (float)atan2( dy, dx );  431     }  432     else  433     {  434         if( n == 1 )  435             box.center = points[0];  436     }  437   438     box.angle = (float)(box.angle*180/CV_PI);  439     return box;  440 }  441
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

OpenCV以图像的左上角为(0,0),Point(x,y),x对应列,y对应行,

RotatedRect rRect;rRect = minAreaRect(point);Point2f vertices[4];rRect.points(vertices);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

rRect.size.widthrRect.size.heightrRect.anglevertices[0]vertices[1]vertices[2]vertices[3]如下图所示,和mine1024博客3里Cvbox2D好像不太一样,改天验证下。

这里写图片描述这里写图片描述

利用仿射变换,将该区域裁剪下来,并旋正:

    vector<Point> point;    vector<vector<Point>> contours ;    findContours( Itwe, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE );    if(!contours.size())    {        printf("No contours!\n");        return 0;    }    else    {        double maxarea = 0;        int maxareai = 0;        for (int i = 0; i<contours.size(); i++)        {            double tmparea = fabs(contourArea(contours[i]));            if(tmparea > maxarea)            {tmparea = tmparea;            maxareai = i;}          }        vector<Point> contourspoint = contours[maxareai];    }    RotatedRect rRect;    rRect = minAreaRect(point);    int dstw,dsth;    Point2f vertices[4];    Point2f verdst[4];    if(rRect.size.width>rRect.size.height)    {        //rRect.size.width += 100;  //宽度增加100,以防定位偏差        rRect.points(vertices);        dstw = rRect.size.width;        dsth = rRect.size.height;        verdst[0] = Point2f(0,dsth);        verdst[1] = Point2f(0,0);        verdst[2] = Point2f(dstw,0);        verdst[3] = Point2f(dstw,dsth);     }    else     {        //rRect.size.height += 100;        rRect.points(vertices);        dstw = rRect.size.height;        dsth = rRect.size.width;        verdst[0] = Point2f(dstw,dsth);        verdst[1] = Point2f(0,dsth);        verdst[2] = Point2f(0,0);        verdst[3] = Point2f(dstw,0);    }    Mat Idst = Mat(dsth,dstw,CV_8UC1);    Mat warpMatrix = getPerspectiveTransform(vertices, verdst);    warpPerspective(Isrc, Idst, warpMatrix, Idst.size(), INTER_LINEAR, BORDER_CONSTANT); 
0 0
原创粉丝点击