C++ OpenCV實(shí)戰(zhàn)之標(biāo)記點(diǎn)檢測(cè)的實(shí)現(xiàn)
在實(shí)際應(yīng)用中,能夠直接利用霍夫圓檢測(cè)這些理想方法的應(yīng)用場(chǎng)景是非常少的,更多的是利用擬合的辦法去尋找圓形。
大致思路如下,首先先選擇要處理的ROI部分,記錄下該圖的左上點(diǎn)在原圖的坐標(biāo),如果原圖過(guò)大,要先進(jìn)行等比例縮放;然后利用自適應(yīng)閾值和Canny邊緣提取進(jìn)行處理,再進(jìn)行閉運(yùn)算與輪廓檢測(cè),計(jì)算點(diǎn)集面積,通過(guò)篩選面積閾值去除雜點(diǎn),最后進(jìn)行輪廓檢測(cè),擬合橢圓,效果如下:
1.導(dǎo)入原圖:
2.截取ROI
3.進(jìn)行自適應(yīng)閾值化與Canny邊緣提取
4.進(jìn)行閉運(yùn)算,然后輪廓檢測(cè),然后計(jì)算點(diǎn)集面積,通過(guò)面積閾值去除雜點(diǎn)
5.再次進(jìn)行輪廓檢測(cè),擬合橢圓
代碼如下:
#include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <opencv2\core\core.hpp> #include <iostream> #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區(qū)域左上角的點(diǎn) 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));//圖像縮放,否則原來(lái)圖像會(huì)在ROI時(shí)顯示不下 ROIStruct ROI = getROI(srcImage);//選擇ROI區(qū)域 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);//自適應(yīng)閾值 cv::Canny(thresholdImage, thresholdImage, cannythreshold, cannythreshold * 3, 3); cv::imshow("thresholdImage", thresholdImage); std::vector<std::vector<cv::Point>> contours1; std::vector<cv::Vec4i> 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 <contours1.size();i++) { double area = cv::contourArea(contours1[i]); //std::cout << i << "點(diǎn)集區(qū)域面積:" << area << std::endl; if (area < 120) { continue; } else { drawContours(findImage, contours1, i, cv::Scalar(255, 255, 255), -1, 8, cv::Mat(), 0, cv::Point()); } } cv::imshow("drawing", findImage); cv::Mat CircleImage(findImage.size(),CV_8UC1); findImage.copyTo(CircleImage); cv::cvtColor(CircleImage, CircleImage, CV_RGB2GRAY); std::vector<std::vector<cv::Point>> contours2; std::vector<cv::Vec4i> hierarchy2; cv::Mat resultImage(CircleImage.size(), CV_8UC3); cv::findContours(CircleImage, contours2, hierarchy2, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); std::vector<cv::Point> points1, points2; cv::Mat compareImage; DetectImage.copyTo(compareImage); for (int j = 0; j <contours2.size();j++) { cv::RotatedRect box = cv::fitEllipse(contours2[j]); points1.push_back(box.center); ellipse(resultImage, box, cv::Scalar(0, 0, 255), 1, CV_AA); ellipse(compareImage, box, cv::Scalar(0, 0, 255), 1, CV_AA); } for (int i = 0; i < points1.size(); i++) { cv::Point ans; ans.x = ROI.ROIPoint.x + points1[i].x; ans.x = ans.x*scale; ans.y = ROI.ROIPoint.y + points1[i].y; ans.y = ans.y*scale; points2.push_back(ans); } std::cout << points1 << std::endl; std::cout << ROI.ROIPoint << std::endl; std::cout << points2 << std::endl; cv::imshow("resultImage", resultImage); cv::imshow("compareImage", compareImage); cv::waitKey(0); return 0; }
到此這篇關(guān)于C++ OpenCV實(shí)戰(zhàn)之標(biāo)記點(diǎn)檢測(cè)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++ OpenCV標(biāo)記點(diǎn)檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++?opencv圖像處理實(shí)現(xiàn)圖片邊緣檢測(cè)示例
- C++ OpenCV實(shí)戰(zhàn)之網(wǎng)孔檢測(cè)的實(shí)現(xiàn)
- C++?OpenCV實(shí)戰(zhàn)之車道檢測(cè)
- C++?OpenCV實(shí)現(xiàn)二維碼檢測(cè)功能
- C++ opencv霍夫圓檢測(cè)使用案例詳解
- opencv3/C++ 實(shí)現(xiàn)SURF特征檢測(cè)
- opencv3/C++實(shí)現(xiàn)霍夫圓/直線檢測(cè)
- C++利用opencv實(shí)現(xiàn)人臉檢測(cè)
- C++利用Opencv實(shí)現(xiàn)多個(gè)圓形檢測(cè)
相關(guān)文章
C++編程中刪除運(yùn)算符與相等運(yùn)算符的使用解析
這篇文章主要介紹了C++編程中刪除運(yùn)算符與相等運(yùn)算符的使用解析,delete和==以及!=運(yùn)算符的使用是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01C++?opencv圖像處理實(shí)現(xiàn)灰度變換示例
這篇文章主要為大家介紹了C++?opencv圖像處理灰度變換的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單回聲服務(wù)器
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單回聲服務(wù)器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03詳解如何使用VSCode和CMake構(gòu)建跨平臺(tái)的C/C++開(kāi)發(fā)環(huán)境
本文主要介紹了如何使用VSCode和CMake構(gòu)建跨平臺(tái)的C/C++開(kāi)發(fā)環(huán)境,想進(jìn)行跨平臺(tái)開(kāi)發(fā)的同學(xué)們,一定要看一下2021-06-06怎么通過(guò)C語(yǔ)言自動(dòng)生成MAC地址
以下是對(duì)使用C語(yǔ)言自動(dòng)生成MAC地址的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-09-09C語(yǔ)言之包含min函數(shù)的棧實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言之包含min函數(shù)的棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-02-02OpenCV圖像特征提取之Shi-Tomasi角點(diǎn)檢測(cè)算法詳解
Harris角點(diǎn)檢測(cè)算法就是對(duì)角點(diǎn)響應(yīng)函數(shù)R進(jìn)行閾值處理,Shi-Tomasi原理幾乎和Harris一樣的,只不過(guò)最后計(jì)算角點(diǎn)響應(yīng)的公式發(fā)生了變化。本文將和大家詳細(xì)說(shuō)說(shuō)Shi-Tomasi角點(diǎn)檢測(cè)算法的原理與實(shí)現(xiàn),需要的可以參考一下2022-09-09