使用Mat mask的方式是解决特殊形状ROI的较好方法
一般需要使用支持mask的函数解决
这里是一个旋转矩形mask
opencv 不能直接绘制填充的旋转矩形,所以我使用的是填充矩形,外加旋转。
也可以用 fillPoly 绘制填充多边形
ROI操作是做直方图。
注意:calcHist函数的输入变量hranges,它的最大值范围 需要 +1
例如
// hue varies from 0 to 179, see cvtColor
float hranges[] = { 0, 180 };
// saturation varies from 0 (black-gray-white) to
// 255 (pure spectrum color)
float sranges[] = { 0, 256 };
void test_rotate_rect_contour()
{
Mat image(240, 320, CV_8U, Scalar(0));
RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i+1)%4], Scalar(255));
//画图:两个色块
rectangle(image, Rect(70, 70, 20,10), Scalar(220), CV_FILLED);
rectangle(image, Rect(110,100,10,10), Scalar(128), CV_FILLED);
//计算旋转ROI的旋转Mask
Mat mask(240, 320, CV_8U, Scalar(0));
Point p1 = rRect.center;
p1.x = p1.x - rRect.size.width/2;
p1.y = p1.y - rRect.size.height/2;
rectangle(mask, Rect(p1, rRect.size), Scalar(255), CV_FILLED);
// imshow("mask", mask);
// waitKey(0);
Mat R = getRotationMatrix2D(rRect.center, -rRect.angle, 1.0);
Mat imgR;
warpAffine(mask, imgR, R, Size(320, 240));
threshold(imgR,imgR,254,255,THRESH_BINARY); //二值化
erode(imgR,imgR, Mat(2,2,CV_8U,Scalar(1))); //小一圈,不算边缘
// imshow("maskR", imgR);
// waitKey();
//直方图分析
int histSize[1] = {32}; //32分隔
int channels[1] = {0}; //第一通道
float hranges[2]; //取值范围
const float *ranges[1] = {hranges};
double elem_min, elem_max;
Mat hist;
minMaxLoc(image, &elem_min, &elem_max, &Point(), &Point(), mask);
hranges[0] = elem_min;
hranges[1] = elem_max + 1; //最大值范围 需要 +1
cout << elem_min << "," << elem_max << endl;
calcHist(&image, 1, channels, imgR, hist, 1, histSize, ranges);
int maxNO = 0; //最大直条编号
float maxL = 0; //最大直条的内个数
for (int i = 0; i < histSize[0]; i++)
{
cout << "list" << i << " = " << hist.at<float>(i) << endl;
if (maxL < hist.at<float>(i))
{
maxL = hist.at<float>(i);
maxNO = i;
}
}
cout << ((elem_max - elem_min + 1)*(maxNO + 0.5)/histSize[0] + elem_min) << endl;
// imshow("mask", mask);
imshow("maskR", imgR);
imshow("rectangles", image);
waitKey();
}
旋转ROI 的mask
直方图统计的图像
输出结果