opencv 区域提取三种算法
1.轮廓查找
findContours()函数,得到轮廓的点集集合
cv::vector<cv::vector<Point>> contours;
threshold(roiMat,binImg,m_pPara.m_nMinGray,m_pPara.m_nMaxGray,THRESH_BINARY);
//膨胀处理
Mat dilaElement = getStructuringElement(MORPH_ELLIPSE, Size(m_pPara.m_nDilation, m_pPara.m_nDilation));
dilate(binImg, binImg, dilaElement);
//腐蚀处理
Mat eroElement = getStructuringElement(MORPH_ELLIPSE, Size(m_pPara.m_nErosion, m_pPara.m_nErosion));
erode(binImg, binImg, eroElement);
//计算轮廓面积
for (int k=0;k<contours.size();k++)
{
//面积筛选
dArea = contourArea(contours[k]);
//轮廓填充绘制
Mat imgBack = Mat::zeros(roiMat.size(), CV_8U);
drawContours(imgBack, contours,k,255, -1);
}
//计算轮廓中心点
Moments mu = moments(contours2[0]);
Point2f center(mu.m10/mu.m00,mu.m01/mu.m00);
//计算轮廓外接矩形
cv::Rect bRect = boundingRect(contours2[0]);
//计算轮廓旋转外接矩形
cv::RotatedRect rotRect= cv::minAreaRect(contours2[0]);
Point2f pointsArr[4];
rotRect.points(pointsArr);
检测结果如下:
2.斑点检测
SimpleBlobDetector函数
//区域检测参数设置
SimpleBlobDetector::Params params;
//二值化阈值
params.minThreshold = 100;
params.maxThreshold = 255;
//斑点颜色
params.filterByColor =false;
//斑点面积
params.filterByArea = true;
params.minArea = m_pPara.m_nMinArea;
params.maxArea = m_pPara.m_nMaxArea;
//斑点圆度
params.filterByCircularity = true;
params.minCircularity =m_pPara.m_dMinCir;
//斑点惯性率
params.filterByInertia = false;
//斑点凸度比
params.filterByConvexity = true;
params.minCircularity = m_pPara.m_dMinCon;
SimpleBlobDetector detector(params);
//得到轮廓的关键点
vector<KeyPoint> keypoints;
detector.detect(roiMat, keypoints);
KeyPoint:
Point2f pt 关键点坐标
float size 点直径大小
float angle 关键点方向
检测结果如下:
3.角点检测
goodFeaturesToTrack()函数
//存储角点位置
vector<cv::Point2f> corners;
//最小可接受的向量值
double qualityLevel = 0.03;
//两个角点之间的最小距离
double minDistance = 6;
//计算协方差矩阵的窗口大小
int blockSize = 3;
bool useHarris = false;
double k = 0.04;
//识别角点个数
int num_corners = 3;
cv::goodFeaturesToTrack(roiMat, corners, num_corners, qualityLevel, minDistance,
cv::Mat(), blockSize, useHarris, k);
//拟合亚像素角点位置
//区域大小
cv::Size winSize = cv::Size(3, 3);
//类似于winSize,但总是有较小的范围, (-1,-1)表示忽略
cv::Size zerozone = cv::Size(-1, -1);
//迭代循环结束条件,三个参数,1:结束条件,2:最大迭代次数,3:阈值
//以下TermCriteria表示同时到达最大迭代次数40与角点位置变化的最小值达到0.001则停止迭代
cv::TermCriteria tc = cv::TermCriteria(cv::TermCriteria::EPS +
cv::TermCriteria::MAX_ITER, 40, 0.001);
//计算亚像素角点位置
cv::cornerSubPix(roiMat, corners, winSize, zerozone, tc);
检测结果如下: