公司项目为了完成自动化中图片的比较校验(校验一个图片是否包含另一个图片),
1 java的实现方式
从github中的项目:https://github.com/lichao3140/Opencv_Java 中“OpenCV_20_MScaleTemplateMatch 多尺度模板匹配”的代码得到灵感,借鉴并修改一下, 完美完成。
1. 修改后的代码如下:
package com.debug;
import java.util.ArrayList;
import java.util.List;
import org.opencv.core.*;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class Debug {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat src = Imgcodecs.imread("D:/data/image/woman.jpg");// 模板图像
Mat tpl = Imgcodecs.imread("D:/data/image/face.jpg");// 输入图像
if (src.empty() || tpl.empty()) {
return;
}
List<Mat> scales = buildGoussianPyromid(src, 3);
List<Mat> templates = buildGoussianPyromid(tpl, 3);
int method = Imgproc.TM_CCOEFF_NORMED;
boolean found = false;
for (int i = 0; i < scales.size(); i++) {
// 匹配到就结束循环
if (found)
break;
for (int j = 0; j < templates.size(); j++) {
MinMaxLocResult minMaxLocResult = matchImage(scales.get(i), templates.get(j), method);
Point maxloc = minMaxLocResult.maxLoc;
Point minloc = minMaxLocResult.minLoc;
Point matchloc = null;
double matchValue = 0.0;
if (method == Imgproc.TM_SQDIFF || method == Imgproc.TM_SQDIFF_NORMED) {
matchloc = minloc;
matchValue = minMaxLocResult.minVal;
} else {
matchloc = maxloc;
matchValue = minMaxLocResult.maxVal;
}
// 如果最大值大于0.75则认为是匹配,使用Imgproc.TM_CCOEFF_NORMED模板匹配才可以
if (matchValue > 0.75) {
Mat copy_src = scales.get(i).clone();
Mat copy_tpl = templates.get(j).clone();
Imgproc.rectangle(copy_src, matchloc,
new Point(matchloc.x + copy_tpl.cols(), matchloc.y + copy_tpl.rows()),
new Scalar(0, 0, 255), 2, 8, 0);
Imgcodecs.imwrite("D:/data/image/flag.png", copy_src);
found = true;
break;
}
}
}
if(found) {
System.out.println("完全匹配");
}else {
System.out.println("fail");
}
}
/**
* 图像匹配
*
* @param src
* @param tpl
* @param method 匹配算法类型
* @return
*/
public static MinMaxLocResult matchImage(Mat src, Mat tpl, int method) {
int width = src.cols() - tpl.cols() + 1;
int height = src.rows() - tpl.rows() + 1;
Mat result = new Mat(height, width, CvType.CV_32FC1);
Imgproc.matchTemplate(src, tpl, result, method);
MinMaxLocResult minMaxLocResult = Core.minMaxLoc(result);
return minMaxLocResult;
}
/**
* 构建高斯金字塔
*
* @param image 图像
* @param level 层次
* @return
*/
public static List<Mat> buildGoussianPyromid(Mat image, int level) {
List<Mat> pyromid = new ArrayList<Mat>();
Mat copy = image.clone();
pyromid.add(image.clone());
Mat dst = new Mat();
for (int i = 0; i < level; i++) {
// Size()函数可以不加,加了是为保证两张图片大小一致
Imgproc.pyrDown(copy, dst, new Size(copy.cols() / 2, copy.rows() / 2));
dst.copyTo(copy);
pyromid.add(dst.clone());
}
return pyromid;
}
}
2 python的实现方式
待完成
github下教程:https://github.com/makelove/OpenCV-Python-Tutorial
教程
《OpenCV-Python教程》,感觉很好
http://blog.csdn.net/sunny2038/article/category/904451
视频
B站视频
python+opencv3.3视频教学 基础入门
https://www.bilibili.com/video/av24998616
OpenCV基础课程
https://www.bilibili.com/video/av29600072
基于OpenCV的图像和视频分析(Python语言)外国YouTube高手sentex,推荐
https://www.bilibili.com/video/av13924091
github下基础教程:https://github.com/ex2tron/OpenCV-Python-Tutorial