【问题标题】:RotatedRect ROI in OpenCVOpenCV 中的 RotatedRect ROI
【发布时间】:2012-10-16 08:10:34
【问题描述】:

我有一个RotatedRect,我想在旋转区域进行一些图像处理(比如提取颜色直方图)。我怎样才能获得投资回报率?我的意思是获取区域(像素),以便我可以进行处理。

我找到了this,但它通过使用getRotationMatrix2DwarpAffine 改变了区域,所以它不适用于我的情况(我需要处理原始图像像素)。
然后我发现this 建议使用ma​​sk,这听起来很合理,但是谁能教我如何获得下面绿色RotatedRect 的mask。

除了口罩,还有其他解决办法吗?
感谢您的任何提示

【问题讨论】:

  • this 有帮助吗?您只需要使用 fillPoly 来绘制旋转的矩形。您可以使用它的大小和角度来获得它的 4 个点。

标签: image-processing opencv mask roi


【解决方案1】:

这是我的解决方案,使用 ma​​sk
这个想法是通过将 255 分配给我的 RotatedRect ROI 来构造一个 Mat mask

如何知道 ROI 中的哪个点(应该分配给 255)?
我使用下面的函数isInROI来解决这个问题。

/** decide whether point p is in the ROI.
*** The ROI is a rotated rectange whose 4 corners are stored in roi[] 
**/
bool isInROI(Point p, Point2f roi[])
{
    double pro[4];
    for(int i=0; i<4; ++i)
    {
        pro[i] = computeProduct(p, roi[i], roi[(i+1)%4]);
    }
    if(pro[0]*pro[2]<0 && pro[1]*pro[3]<0)
    {
        return true;
    }
    return false;
}

/** function pro = kx-y+j, take two points a and b,
*** compute the line argument k and j, then return the pro value
*** so that can be used to determine whether the point p is on the left or right
*** of the line ab
**/
double computeProduct(Point p, Point2f a, Point2f b)
{
    double k = (a.y-b.y) / (a.x-b.x);
    double j = a.y - k*a.x;
    return k*p.x - p.y + j;
}

面具如何构造?
使用以下代码。

Mat mask = Mat(image.size(), CV_8U, Scalar(0));
for(int i=0; i<image.rows; ++i)
{
    for(int j=0; j<image.cols; ++j)
    {
        Point p = Point(j,i);   // pay attention to the cordination
        if(isInROI(p,vertices))
        {
            mask.at<uchar>(i,j) = 255;
        }
    }
}

完成,
范思哲

【讨论】:

  • 什么是顶点?就我而言,我将 roi 坐标作为 Point2f 的 rect_points 数组。
【解决方案2】:

如果您需要超快的解决方案,我建议:

  • 裁剪一个包含 RotatedRect rr 的 Rect。
  • 旋转+平移裁剪后的图像,使 RotatedRect 现在等效于 Rect。 (在旋转和平移 3x3 矩阵的乘积上使用 warpAffine)
  • 保留旋转后图像的 roi (roi=Rect(Point(0,0), rr.size()))。

写起来有点费时,因为你需要计算组合的仿射变换。

【讨论】:

    【解决方案3】:

    如果你不关心速度并且想为区域的任何形状创建一个快速原型,你可以使用一个 openCV 函数 pointPolygonTest() 如果里面的点返回一个正值:

    double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)
    

    简单代码:

    vector<Point2f> contour(4);
    contour[0] = Point2f(-10, -10);
    contour[1] = Point2f(-10, 10);
    contour[2] = Point2f(10, 10);
    contour[3] = Point2f(10, -10);    
    Point2f pt = Point2f(11, 11);
    an double res = pointPolygonTest(contour, pt, false);
    if (res>0)
        cout<<"inside"<<endl;
    else
        cout<<"outside"<<endl;
    

    【讨论】:

      【解决方案4】:

      我发现以下帖子非常有用。 http://answers.opencv.org/question/497/extract-a-rotatedrect-area/

      唯一需要注意的是(a)这里的“角度”假设是围绕整个图像(不是边界框)中心的旋转和(b)在下面的最后一行(我认为)“rect .center" 需要转换为旋转后的图像(通过应用旋转矩阵)。

          // rect is the RotatedRect 
          RotatedRect rect;
          // matrices we'll use
          Mat M, rotated, cropped;
          // get angle and size from the bounding box
          float angle = rect.angle;
          Size rect_size = rect.size;
          // thanks to http://felix.abecassis.me/2011/10/opencv-rotation-deskewing/
          if (rect.angle < -45.) {
              angle += 90.0;
              swap(rect_size.width, rect_size.height);
          }
          // get the rotation matrix
          M = getRotationMatrix2D(rect.center, angle, 1.0);
          // perform the affine transformation
          warpAffine(src, rotated, M, src.size(), INTER_CUBIC);
          // crop the resulting image
          getRectSubPix(rotated, rect_size, rect.center, cropped);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-12
        • 2023-03-23
        • 2012-06-01
        • 1970-01-01
        • 2011-12-18
        • 1970-01-01
        • 1970-01-01
        • 2013-08-14
        相关资源
        最近更新 更多