形状匹配
本章节内容是博主网上收集的,PDF原文下载地址如下:
OpenCV-Python-Tutorial-中文版.pdf
PDF在线预览
当前系列所有demo下载地址:
https://github.com/GaoRenBao/OpenCv4-Demo
不同编程语言对应的OpenCv版本以及开发环境信息如下:
语言 | OpenCv版本 | IDE |
C# | OpenCvSharp4.4.8.0.20230708 | Visual Studio 2022 |
C++ | OpenCv-4.5.5-vc14_vc15 | Visual Studio 2022 |
Python | OpenCv-Python (4.6.0.66) | PyCharm Community Edition 2022.1.3 |
测试原图如下,官方demo里面给了一张合并了的图片,其实这个图片是要拆分成三张独立的才行。
测试结果:
A与A匹配结果:0.0
A与B匹配结果:0.45134585973551417
A与C匹配结果:3.2206591324037994
C#版本运行代码如下:
using OpenCvSharp;
using System;
namespace ConsoleApp
{
internal class Program
{
static void Main(string[] args)
{
Mat img1 = Cv2.ImRead("../../../images/star.jpg",0);
//Mat img2 = Cv2.ImRead("../../../images/star_b.jpg",0);
Mat img2 = Cv2.ImRead("../../../images/star_c.jpg",0);
Cv2.ImShow("img1", img1);
Cv2.ImShow("img2", img2);
Mat thresh1 = new Mat();
Mat thresh2 = new Mat();
Cv2.Threshold(img1, thresh1, 127, 255, ThresholdTypes.Binary);
Cv2.Threshold(img2, thresh2, 127, 255, ThresholdTypes.Binary);
Point[][] contours = new Point[][] { };
HierarchyIndex[] hierarcy;
Cv2.FindContours(thresh1, out contours, out hierarcy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone, null);
Point[] cnt1 = contours[0];
Console.WriteLine($"contours len1:{contours.Length}");
Cv2.FindContours(thresh2, out contours, out hierarcy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone, null);
Point[] cnt2 = contours[0];
Console.WriteLine($"contours len2:{contours.Length}");
double ret = Cv2.MatchShapes(cnt1, cnt2, ShapeMatchModes.I1, 0.0);
Console.WriteLine($"ret:{ret}");
Cv2.WaitKey(0);
}
}
}
C++版本运行代码如下:
#include <opencv2/opencv.hpp>
#include <opencv2/cvconfig.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <string>
#include <cmath>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img1 = cv::imread("../images/star.jpg", 0);
//Mat img2 = cv::imread("../images/star_b.jpg",0);
Mat img2 = cv::imread("../images/star_c.jpg", 0);
cv::imshow("img1", img1);
cv::imshow("img2", img2);
Mat thresh1;
Mat thresh2;
cv::threshold(img1, thresh1, 127, 255, THRESH_BINARY);
cv::threshold(img2, thresh2, 127, 255, THRESH_BINARY);
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
cv::findContours(thresh1, contours, hierarcy, RETR_CCOMP, CHAIN_APPROX_NONE, Point(0, 0));
vector<Point> cnt1 = contours[0];
cout << "contours len1:" << contours.size() << endl;
cv::findContours(thresh2, contours, hierarcy, RETR_CCOMP, CHAIN_APPROX_NONE, Point(0, 0));
vector<Point> cnt2 = contours[0];
cout << "contours len2:" << contours.size() << endl;
double ret = cv::matchShapes(cnt1, cnt2, 1, 0.0);
cout << "ret:" << ret << endl;
cv::waitKey(0);
}
Python版本运行代码如下:
import cv2
import numpy as np
img1 = cv2.imread('../images/star.jpg', 0)
img2 = cv2.imread('../images/star_b.jpg', 0)
#img2 = cv2.imread('../images/star_c.jpg', 0)
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
ret, thresh1 = cv2.threshold(img1, 127, 255, 0)
ret, thresh2 = cv2.threshold(img2, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh1, 2, 1)
cnt1 = contours[0]
print('contours len1:', len(contours))
contours, hierarchy = cv2.findContours(thresh2, 2, 1)
cnt2 = contours[0]
print('contours len2:', len(contours))
ret = cv2.matchShapes(cnt1, cnt2, 1, 0.0)
print(ret)
cv2.waitKey(0)
#Hu 矩是归一化中心矩的线性组合
# 之所以这样样做是为了能够获取到代表图像的某个特征的矩函数
# 这些矩函数对某些变化如缩放 旋转,镜像映射( 除了 h1)具有不变形。