C++ OpenCV實(shí)戰(zhàn)之形狀識(shí)別
前言
本案例通過(guò)使用OpenCV中的approxPolyDP進(jìn)行多邊形近似,進(jìn)而進(jìn)行基礎(chǔ)形狀識(shí)別(圓、三角形、矩形、星形…)。下面就一起來(lái)看看具體是如何實(shí)現(xiàn)的吧。
一、圖像預(yù)處理
原圖如圖所示:
首先第一步先進(jìn)行圖像預(yù)處理,得到二值圖像。
Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); Mat gaussian; GaussianBlur(gray, gaussian, Size(3, 3), 0); Mat thresh; threshold(gaussian, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
結(jié)果如圖所示。接下來(lái),需要對(duì)此二值圖像進(jìn)行輪廓提取,進(jìn)而識(shí)別物體形狀。
二、形狀識(shí)別
本案例使用approxPolyDP進(jìn)行形狀識(shí)別,關(guān)于approxPolyDP OpenCV給出的定義是:
void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed);
- curve:表示輸入輪廓點(diǎn)集,可以是 vector 或 Mat 類型。
- approxCurve:多邊形逼近結(jié)果,存儲(chǔ)在approxCurve數(shù)組中。curve和approxCurve應(yīng)該屬于同一類型。
- epsilon:表示逼近準(zhǔn)確度,你允許在原多邊形和最終擬合的多邊形之間存在的最大偏差。一般以其周長(zhǎng)的百分比進(jìn)行近似。
- closed:指明curve中的一系列點(diǎn)是否是一個(gè)閉合的多邊形。若設(shè)為true,則認(rèn)為曲線是閉合的。
我們通過(guò)統(tǒng)計(jì)多邊形的“邊”數(shù)來(lái)識(shí)別物體形狀。
三、源碼
#include<iostream> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; //基礎(chǔ)幾何形狀識(shí)別 bool Pattern_Recognition(Mat& src) { //圖像預(yù)處理 Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); Mat gaussian; GaussianBlur(gray, gaussian, Size(3, 3), 0); Mat thresh; threshold(gaussian, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU); //輪廓查找 vector<vector<Point>>contours;//輪廓點(diǎn)集 findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); vector<vector<Point>>conPoly(contours.size());//多邊形逼近結(jié)果,與輪廓一一對(duì)應(yīng) for (int i = 0; i < contours.size(); i++) { double area = contourArea(contours[i]); //輪廓面積 if (area > 1000) { Rect rect = boundingRect(contours[i]);//外界矩形 double ratio = double(rect.width) / double(rect.height);//長(zhǎng)寬比 double peri = arcLength(contours[i], true);//周長(zhǎng) approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);//多邊形近似 int objSize = conPoly[i].size();//折線數(shù)--通過(guò)判斷輪廓有幾條邊來(lái)識(shí)別圖形 string objName; Scalar color; if (objSize == 3) { objName = "Triangle";//三角形 color = Scalar(0, 0, 255); } if (objSize == 4) { //通過(guò)長(zhǎng)寬比判斷正方形/長(zhǎng)方形 if (ratio > 0.99 && ratio < 1.01) { objName = "Square";//正方形 color = Scalar(0, 255, 255); } else { objName = "Rectangle";//長(zhǎng)方形 color = Scalar(0, 255, 0); } } if (objSize == 8) { objName = "Circle";//圓形 color = Scalar(255, 255, 0); } if (objSize == 10) { objName = "Star";//星形 color = Scalar(255, 0, 255); } //效果繪制 rectangle(src, rect, color, 2); putText(src, objName, rect.tl(), FONT_HERSHEY_SIMPLEX, 1, color, 2); } } return true; } int main() { Mat src = imread("src.jpeg"); if (src.empty()) { cout << "No Image!" << endl; system("pause"); return -1; } if (!Pattern_Recognition(src))return false; namedWindow("test", WINDOW_NORMAL); imshow("test", src); waitKey(0); system("pause"); return 0; }
四、結(jié)果顯示
總結(jié)
本文使用OpenCV C++ 進(jìn)行基礎(chǔ)形狀識(shí)別,其實(shí)原理很簡(jiǎn)單,主要操作有以下幾點(diǎn)。
1、圖像預(yù)處理
2、物體輪廓提取
3、使用approxPolyDP進(jìn)行多邊形近似,進(jìn)而統(tǒng)計(jì)出該物體的“邊”數(shù),從而識(shí)別出物體形狀。
到此這篇關(guān)于C++ OpenCV實(shí)戰(zhàn)之形狀識(shí)別的文章就介紹到這了,更多相關(guān)C++ OpenCV形狀識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)文件編碼格式識(shí)別
在做數(shù)據(jù)導(dǎo)入導(dǎo)出的過(guò)程中,如果應(yīng)用場(chǎng)景多了,相信各位都會(huì)遇到一個(gè)問(wèn)題就是文件編碼的問(wèn)題。本文將用Qt實(shí)現(xiàn)文件編碼格式識(shí)別,感興趣的可以了解一下2022-06-06C語(yǔ)言學(xué)習(xí)之關(guān)鍵字的示例詳解
關(guān)鍵字,這名字一聽(tīng),就很關(guān)鍵。而有些關(guān)鍵字,你可能不是很了解,更別談使用。所以,這篇文章將帶你見(jiàn)識(shí)常見(jiàn)的關(guān)鍵字,一起領(lǐng)略它們的風(fēng)采吧2022-10-10C語(yǔ)言實(shí)現(xiàn)通訊錄系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通訊錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)的非遞歸后序遍歷算法
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)的非遞歸后序遍歷算法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10C++中構(gòu)造函數(shù)與析構(gòu)函數(shù)的詳解及其作用介紹
這篇文章主要介紹了C++中構(gòu)造函數(shù)與析構(gòu)函數(shù)的詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09