學習|OpenCV匹配類似輪廓



學更好的別人,ios

作更好的本身。微信

——《微卡智享》app




本文長度爲2816,預計閱讀9分鐘




OpenCV匹配輪廓機器學習


其實查找類似的東西用機器學習訓練的方式處理應該是最好的,今天作的這個小練習主要是針對OpenCV的matchShapes函數的練習,正好把OpenCV的幾個函數綜合運用一下。





實現效果函數





從圖上咱們能夠看出來,經過鼠標點擊找到咱們要實現的輪廓,而後經過匹配輪廓把找到的輪廓在左邊的圖中都畫出來,其中是咱們點擊的輪廓就紅色填充,匹配的類似輪廓用的藍色填充,就是實現的一個這樣簡單的效果。


綜合練習知識點學習


# 實現的方式及用到的學習函數
1 經過點擊鼠標來選中須要匹配的輪廓,因此用到了setMouseCallback函數
2 基本圖像操做,灰度圖,高斯模糊,形態學梯度操做
3 查找輪廓findContours,獲取鼠標點擊的輪廓pointPolygonTest
4
輪廓匹配matchShapes

代碼實現測試

微卡智享flex

OpenCV的項目搭建及配置請直接看《 VS2017配置OpenCV通用屬性
整個項目中,一個main.cpp的文件,一個matchShape的類,以下圖:

main.cpp

#include<opencv2/opencv.hpp>#include<iostream>#include"matchShape.h"
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

#pragma once#include <opencv2/opencv.hpp>#include<iostream>
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

#include "matchShape.h"
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



掃描二維碼

獲取更多精彩

微卡智享




「 往期文章 」


實踐|OpenCV4.2使用DNN進行人臉檢測二(視頻篇)

實踐|OpenCV4.2使用DNN進行人臉檢測一(圖片篇)

學習|Android中JetPack中的幾個組件簡單使用







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

相關文章
相關標籤/搜索