1. 图像二值化。也就是得到质量良好的截面区域。使用带有上下限(需根据场景手动设置)的二值化方法,去除深色背景( Threshhold1 )和除钢管阴影以外的亮区域( Threshhold2 )对 ROI (感兴趣) 区域的干扰。
2. 提取目标连通区域轮廓。 经形态学开运算处理后,去除噪声点和独立小点特大区域的干扰, 分割出目标连通区域后, 提取所有连通区域的边界点。 其中连通区域的面积选择根
据经验设置。
3. 统计连通区域的圆特性。以连通区域的最小外接圆半径作为期望没计算轮廓上个点到圆心距离的方差来确定是否为类圆。 方差可信度的范围根据图像的效果进行手动设置。
下面是实现的代码:
// selectshape.cpp : 选择轮廓
//二值化的结果是识别的关键,提取出所有圆形区域,后面通过调节类圆的方差阈值,连通区域的大小可以提高识别率
#include "stdafx.h"
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
#define VP vector<Point> //用VP符号代替 vector<point>
RNG rng(12345);
//带有上下限的threshold
void threshold2(Mat gray,Mat& thresh,int minvalue,int maxvalue)
{
Mat thresh1;
Mat thresh2;
//二值化 阈值为43
//THRESH_BINARY 当前点值大于阈值时,取Maxval,否则设置为0
threshold(gray,thresh1,43,255, THRESH_BINARY);
//?
//THRESH_BINARY_INV 当前点值大于阈值时,设置为0,否则设置为Maxval
threshold(gray,thresh2,111,255,THRESH_BINARY_INV);
thresh = thresh1 & thresh2;
}
//寻找并绘制出联通区域-----------------------------------------------------------------------此处出现大部分错误联通区域导致圆识别失败
vector<VP> connection2(Mat src,Mat& draw)
{
draw = Mat