我有一个RotatedRect
,我想在旋转的区域进行一些图像处理(比如提取颜色直方图)。我怎样才能获得投资回报率?我的意思是获取区域(像素),以便我可以进行处理。
我找到this,但它使用getRotationMatrix2D
和warpAffine
更改了区域,因此它不适用于我的情况(我需要处理原始图像像素)。
然后我发现this建议使用面具,这听起来很合理,但任何人都可以教我如何将面具作为下面的绿色RotatedRect。
除了面具,有没有其他解决方案?
谢谢你的提示
答案 0 :(得分:7)
这是我的解决方案,使用面具:
我的想法是通过为我的Mat mask
分配255来构建RotatedRect ROI
。
如何知道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;
}
}
}
完成,
vancexu
答案 1 :(得分:5)
我发现以下帖子对于做同样的事情非常有用。 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);
答案 2 :(得分:1)
如果您需要超快速解决方案,我建议:
rr
的矩形。roi=Rect(Point(0,0), rr.size())
)的光照。当你需要计算组合的仿射变换时,写一点有点费时。
答案 3 :(得分:1)
如果您不关心速度并且想要为该区域的任何形状创建快速原型,您可以使用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;