作者:玩玩r28g | 来源:互联网 | 2023-10-17 14:28
C++ OpenCV实战之标记点检测的实现-在实际应用中,能够直接利用霍夫圆检测这些理想方法的应用场景是非常少的,更多的是利用拟合的办法去寻找圆形。大致思路如下,首先先选择要处理的
在实际应用中,能够直接利用霍夫圆检测这些理想方法的应用场景是非常少的,更多的是利用拟合的办法去寻找圆形。
大致思路如下,首先先选择要处理的ROI部分,记录下该图的左上点在原图的坐标,如果原图过大,要先进行等比例缩放;然后利用自适应阈值和Canny边缘提取进行处理,再进行闭运算与轮廓检测,计算点集面积,通过筛选面积阈值去除杂点,最后进行轮廓检测,拟合椭圆,效果如下:
1.导入原图:
2.截取ROI
3.进行自适应阈值化与Canny边缘提取
4.进行闭运算,然后轮廓检测,然后计算点集面积,通过面积阈值去除杂点
5.再次进行轮廓检测,拟合椭圆
代码如下:
#include
#include
#include
#include
#define scale 2//图像缩放因子
#define cannythreshold 80
typedef struct _ROIStruct
{
cv::Point2d ROIPoint;
cv::Mat ROIImage;
}ROIStruct;
ROIStruct getROI(cv::Mat src,bool flag = false)
{
ROIStruct ROI_Struct;
cv::Rect2d ROIrect = selectROI(src);
ROI_Struct.ROIPoint = ROIrect.tl();//获取ROI区域左上角的点
ROI_Struct.ROIImage = src(ROIrect);
if (flag == true)
{
cv::imshow("ROI", ROI_Struct.ROIImage);
}
return ROI_Struct;
}
int main()
{
cv::Mat srcImage = cv::imread("7.jpg");//读取待处理的图片
cv::resize(srcImage, srcImage, cv::Size(srcImage.cols / scale, srcImage.rows / scale));//图像缩放,否则原来图像会在ROI时显示不下
ROIStruct ROI = getROI(srcImage);//选择ROI区域
cv::Mat DetectImage, thresholdImage;
ROI.ROIImage.copyTo(DetectImage);
cv::imshow("ROI", DetectImage);
cv::cvtColor(DetectImage, thresholdImage, CV_RGB2GRAY);
cv::adaptiveThreshold(thresholdImage, thresholdImage, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY,11,35);//自适应阈值
cv::Canny(thresholdImage, thresholdImage, cannythreshold, cannythreshold * 3, 3);
cv::imshow("thresholdImage", thresholdImage);
std::vector> contours1;
std::vector hierarchy1;
cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
cv::morphologyEx(thresholdImage, thresholdImage, cv::MORPH_CLOSE, element,cv::Point(-1,-1),2);
cv::Mat findImage = cv::Mat::zeros(thresholdImage.size(), CV_8UC3);
cv::findContours(thresholdImage, contours1, hierarchy1,CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
for (int i = 0; i > contours2;
std::vector hierarchy2;
cv::Mat resultImage(CircleImage.size(), CV_8UC3);
cv::findContours(CircleImage, contours2, hierarchy2, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
std::vector points1, points2;
cv::Mat compareImage;
DetectImage.copyTo(compareImage);
for (int j = 0; j