學更好的別人,ios
作更好的本身。微信
——《微卡智享》app
OpenCV匹配輪廓機器學習
實現效果函數
綜合練習知識點學習
# | 實現的方式及用到的學習函數 |
---|---|
1 | 經過點擊鼠標來選中須要匹配的輪廓,因此用到了setMouseCallback函數 |
2 | 基本圖像操做,灰度圖,高斯模糊,形態學梯度操做 |
3 | 查找輪廓findContours,獲取鼠標點擊的輪廓pointPolygonTest |
4 |
輪廓匹配matchShapes |
代碼實現測試

微卡智享flex
main.cpp
using namespace cv;using namespace std;
string showsrc = "源圖";Point mPoint;Mat src, srccopy;void onMouse(int event, int x, int y, int flags, void* ustc); //鼠標回調函數
int main(int agrc, char** argv) {
src = imread("E:/DCIM/tempsrc.jpg"); namedWindow(showsrc); //設置鼠標響影事件 setMouseCallback(showsrc, onMouse);
imshow(showsrc, src);
waitKey(0); return 0;}
void onMouse(int event, int x, int y, int flags, void* ustc){ //鼠標左鍵按下擡起 if (event == EVENT_LBUTTONUP) { mPoint = Point(x, y); srccopy = src.clone(); matchShape shape = matchShape(); srccopy = shape.findmatchShape(srccopy, mPoint); imshow("res", srccopy); }}
matchShape.h
using namespace cv;using namespace std;class matchShape{private: //匹配閾值 double threshdouble = 0.3; //獲取圖像輪廓 vector<vector<Point>> getContours(Mat src); //獲取點擊的點的所在輪廓 vector<Point> getPointContour(vector<vector<Point>> contours, Point pt);public: Mat findmatchShape(Mat src, Point pt);};
matchShape.cpp
vector<vector<Point>> matchShape::getContours(Mat src){ vector<vector<Point>> contours; Mat gray,tmp; //1.灰度圖 cvtColor(src, gray, COLOR_BGR2GRAY); //2.高斯模糊 GaussianBlur(gray, gray, Size(3, 3), 0.5, 0.5); //3.二值化 threshold(gray, gray, 0, 255, THRESH_BINARY | THRESH_OTSU); //4.形態學梯度處理 Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); morphologyEx(gray, gray, MORPH_GRADIENT, kernel); //imshow("gray", gray);
//4.查找輪廓 findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
return contours;}
//獲取點所在的輪廓vector<Point> matchShape::getPointContour(vector<vector<Point>> contours, Point pt){ for (int i = 0; i < contours.size(); i++) { if (pointPolygonTest(contours[i], pt, false) >= 0) return contours[i]; } return vector<Point>();}
Mat matchShape::findmatchShape(Mat src, Point pt){ Mat dst = Mat::zeros(src.size(), CV_8UC3); //獲取輪廓 vector<vector<Point>> contours = getContours(src);
//獲取點所在的輪廓 vector<Point> ptcontour = getPointContour(contours, pt);
if (ptcontour.size() <= 0) return dst;
//獲取類似輪廓 for (int t = 0; t < contours.size(); t++) { double ret = matchShapes(ptcontour, contours[t], CONTOURS_MATCH_I3, 0.0); cout << t << "類似度:" << ret << endl; if (ret == 0) drawContours(dst, contours, t, Scalar(0, 0, 255),-1); else if (ret <= threshdouble) drawContours(dst, contours, t, Scalar(255, 0, 0),-1); }
return dst;}
測試的圖像在OpenCV的源碼sources/samples/data下,我用的是smarties.png那一張。ui

完url
掃描二維碼
獲取更多精彩
微卡智享

「 往期文章 」
本文分享自微信公衆號 - 微卡智享(VaccaeShare)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。