opencv有关轮廓查找的算法

环境W10+opencv3.2+VS2017有关轮廓查找,之后按照面积进行筛选,接着排序,欢迎大家提出问题。


int my_map(float p1, float p2)
{
return p1 <  p2;
}

void Cbtw_getSpotImage::FindCornerImage() //轮廓的寻找(当其边缘线不明显,但是可以回去到胶上的斑点的时候,通过斑点判断是否存在断胶行为)

{
vector<Rect> resultRect;
Mat dealWithROIImage = ROIImage.clone();
Log("斑点查找算法:采用轮廓的寻找方法寻找", true);
// Mat dstImage = Mat::zeros(dealWithROIImage.rows, dealWithROIImage.cols, CV_8UC3);
Mat dstImage = ROIImage.clone();
//srcImage取阈值大于119的部分  
dealWithROIImage = dealWithROIImage > 220;
cvtColor(dealWithROIImage, dealWithROIImage, CV_BGRA2GRAY);
//定义轮廓和层次结构  
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
/*输入图像image必须为一个2值单通道图像
contours参数为检测的轮廓数组,每一个轮廓用一个point类型的vector表示
hiararchy参数和轮廓个数相同,每个轮廓contours[ i ]对应4个hierarchy元素hierarchy[ i ][ 0 ] ~hierarchy[ i ][ 3 ],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数。
mode表示轮廓的检索模式
CV_RETR_EXTERNAL表示只检测外轮廓
CV_RETR_LIST检测的轮廓不建立等级关系
CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
CV_RETR_TREE建立一个等级树结构的轮廓*/
//查找轮廓  
findContours(dealWithROIImage, contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//遍历所有顶层的轮廓,随机绘制颜色,绘制出每个连接组件的颜色  
int index = 0;
for (; index >= 0; index = hierarchy[index][0]) {
// Scalar color(rand() & 255, rand() & 255, rand() & 255);
Scalar color(255, 255, 255);
//计算轮廓的面积  
double g_dConArea = contourArea(contours[index]);
if ((10 <g_dConArea)  &&(g_dConArea < 300)) //轮廓大于10 到300,为寻找的轮廓
{
drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
Rect rect = boundingRect(contours[index]);//检测外轮廓  
// rectangle(dstImage, rect, Scalar(0, 0, 255), 1);//对外轮廓加矩形框 
resultRect.push_back(rect);
Log("所获到的轮廓:(x,y,wight,hight):(" + to_string(rect.x) +","+ to_string(rect.y) + ","+to_string(rect.width) +","+ to_string(rect.height)+")", false);

}
// cout << "【用轮廓面积计算函数计算出来的第" << i << "个轮廓的面积为:】" << g_dConArea << endl;
}
Log("", true);
/************************************选择排序以每个小矩形左上点x坐标大小排序*******************************************************/
for (vector <Rect>::iterator iterRect = resultRect.begin(); iterRect != resultRect.end(); ++iterRect)
{
Rect Min = (*iterRect);
Rect temp;
vector<Rect>::iterator iterIndex = iterRect;
vector<Rect>::iterator iterJadd = iterRect;
for (vector<Rect>::iterator iterJ = ++iterJadd; iterJ != resultRect.end(); ++iterJ)
{
if ((*iterJ).x < Min.x)
{
Min = (*iterJ);
iterIndex = iterJ;
}
}
temp = (*iterRect);
(*iterRect) = Min;
*iterIndex = temp;
}
bool theNumPassLeagth = false; //判断是否有断胶部分
int theLeagth = 25;
vector<Rect>::iterator iterRectTwo = resultRect.begin();
for (vector <Rect>::iterator iterRect = resultRect.begin(); iterRect != resultRect.end(); ++iterRect)
{
rectangle(dstImage, *iterRect, Scalar(255, 255, 255), 1);//对外轮廓加矩形框 

//imshow("【轮廓图】", dstImage);
//waitKey(0);

iterRectTwo++;
if (iterRectTwo != resultRect.end())
{
// cout << " 长度" << (*iterRectTwo).x - (*iterRect).x << endl;
Log("相邻的两个矩形轮廓,左上点的x坐标之差长度:" + to_string((*iterRectTwo).x - (*iterRect).x)+" ", false);


if ((((*iterRectTwo).x - (*iterRect).x)  < theLeagth) &&(((*iterRectTwo).x - (*iterRect).x) >= 0))
{
line(dstImage, Point((*iterRect).x, (*iterRect).y), Point((*iterRectTwo).x, (*iterRectTwo).y), Scalar(255, 0, 255), 2, 4, 0);
}
else if (((*iterRectTwo).x - (*iterRect).x) < 0)
{
Log("两个轮廓之间与距离小于0,长度为" + to_string(((*iterRectTwo).x - (*iterRect).x)), true);
}
else if (((*iterRectTwo).x - (*iterRect).x)  > theLeagth)
{
Log("两个轮廓之间与距离:"+ to_string(((*iterRectTwo).x - (*iterRect).x))+" 大于" + to_string(theLeagth) + "人为判断此处存在断胶",true);
    theNumPassLeagth = true;
    line(dstImage, Point((*iterRect).x, (*iterRect).y), Point((*iterRectTwo).x, (*iterRectTwo).y), Scalar(0, 0, 255), 2, 4, 0);


}


}
}
if (resultRect.size() == 0)
{
Log("轮廓查找斑点算法中,没有找到对应的斑点",true);
theNumPassLeagth = true;
}
if (theNumPassLeagth)
{
Log("轮廓查找斑点算法,通过判断斑点之间的距离,为NG", true);
getInAllResult->writeOneResult("NG");
}
else
{
Log("轮廓查找斑点算法,通过判断斑点之间的距离,为OK", true);
getInAllResult->writeOneResult("OK");

}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值