在我的项目中,我想从特定颜色的最大同质区域中获取大小(在下面的示例中,它是蓝天)。
我的第一个想法是转换原始图像:
到二值图像,检测天空颜色并用这个区域创建一个蒙版:
但是我怎样才能得到这些白色像素的大小和位置呢?我想要一个有效的方法,如果图片在图片的上 1/3 处有蓝天,那就是真的。有任何想法吗?我应该创建一个“全局掩码”(参见评论中的图 3)并将其与二进制图片进行比较吗?或者有没有更简单的方法?
谢谢你。
在我的项目中,我想从特定颜色的最大同质区域中获取大小(在下面的示例中,它是蓝天)。
我的第一个想法是转换原始图像:
到二值图像,检测天空颜色并用这个区域创建一个蒙版:
但是我怎样才能得到这些白色像素的大小和位置呢?我想要一个有效的方法,如果图片在图片的上 1/3 处有蓝天,那就是真的。有任何想法吗?我应该创建一个“全局掩码”(参见评论中的图 3)并将其与二进制图片进行比较吗?或者有没有更简单的方法?
谢谢你。
算法如下:
extractChannel
提取所需的通道。此外,您可以将图像转换为HSV并使用inRange检测蓝色,而不是步骤1-4 。
这是我的 C++ 实现:
Mat inMat = imread("input.jpg"), blueMat, threshMat;
cvtColor(inMat, blueMat, CV_BGR2YCrCb);//convert to YCrCb color space
extractChannel(blueMat, blueMat, 2);//get blue channel
//find max value of blue color
//or you can use histograms
//or more complex mathod
double blueMax;
minMaxIdx(blueMat, 0, &blueMax);
blueMax *= 0.8;
//make binary mask
threshold(blueMat, threshMat, blueMax, 255, THRESH_BINARY);
//finding all blue contours:
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(blueMat, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
double maxSquare = 0;
vector<Point> maxContour;
//finding contours with biggest square:
for (size_t i=0; i<contours.size(); i++)
{
double square = contourArea(contours[i]);
if (square > maxSquare)
{
maxContour = contours[i];
maxSquare = square;
}
}
//output results:
Point center = centerPolygon(maxContour);
cout << "square = " << maxSquare << endl;
cout << "position: x: " << center.x << ", y: " << center.y << endl;
这里的centerPolygon
功能:
Point centerPolygon(const vector<Point>& points)
{
int x=0, y=0;
for (size_t i=0; i<points.size(); i++)
{
x += points[i].x;
y += points[i].y;
}
return Point(x/points.size(), y/points.size());
}
程序的输出如下:
square = 263525
position: x: 318, y: 208
您可以将此代码转换为 JavaCV - 请参阅本教程。