官方给出求轮廓面积的函数是contourArea(),但是实际使用时发现该值并不是区域内亮点的像素值。contourArea是根据 Green formula计算得到的,具体计算上的差别可以参考这张图,实际7个像素,计算出来是2.5
白线经过的像素是1,其余(2,1)(3,3)为0
这让用惯halcon的我有点难以接受,于是寻思着怎么得到另一种面积(区域内亮像素的个数)。
搜索了一遍发现opencv3.x的connectedComponentsWithStats()可以实现这个功能,由于之前的功能都是在2.X版本下做的,一时不好切换,还是先自己搞一搞,使用opencv3.x的童鞋可以到这里了解~
方案一:
使用findContours找到轮廓之后,以其中一个轮廓点为起点,使用广度优先算法遍历搜索相邻的像素,统计亮点个数,具体实现如下~
const int offsetX[4] = { -1, 0, 1, 0 };
const int offsetY[4] = { 0, -1, 0, 1 };
int getContourArea(Mat &binImg, Point anchorPoint)
{
/*
取轮廓上的一点anchorPoint,计算与anchorPoint连通的所有点的个数
*/
CV_Assert(binImg.type() == CV_8UC1);
int w = binImg.size().width;
int h = binImg.size().height;
Mat flag = Mat::zeros(binImg.size(), CV_8UC1);
Point tmp, currentPoint;
int count = 0;
queue<Point> v1;
v1.push(anchorPoint);
flag.ptr<uchar>(anchorPoint.y)[anchorPoint.x] = 1;
while (!v1.empty())
{
currentPoint = v1.front();
v1.pop();
count++;
for (size_t i = 0; i < 4; i++)
{
tmp.x = currentPoint.x + offsetX[i];
tmp.y = currentPoint.y + offsetY[i];
if (tmp.x >= 0
&& tmp.y >= 0
&& tmp.x < w
&& tmp.y < h //在矩形区域内计算
&&flag.ptr<uchar>(tmp.y)[tmp.x] != 1)
{
if (binImg.ptr<uchar>(tmp.y)[tmp.x]>0)//需要补充
{
//记录未处理的值
v1.push(tmp);
}
flag.ptr<uchar>(tmp.y)[tmp.x] = 1;
}
}
}
return count;
}
【待更。。】