OpenCV学习笔记[4]模板匹配 Java version

OpenCV学习笔记:模板匹配 Java version

首先我要纠正一个错误的学习习惯,像OpenCV这样的大型库,按照官方教程一步一步调试的学习效率太低了,OpenCV就像字典一样,当我们需要计算机进行某些视觉特性模拟时,针对具体问题去检索库中对应的API即可。

尽管官方教程非常详细,但除了人脸识别的Demo和一套doc外,没有其他Java实例,教程中详细的实例都由C语言编写,我在测试的过程中会将对应部分按照OOP形式重写为Java模块,并在学习笔记中贴出。

官方教程可以在OpenCV库解压目录的build/doc下找到,当然,是英文的。

[简介]

模板匹配,通俗的讲,提供原始图片与其中的一部分,找出该部分在原始图片中的位置,它存在诸多限制,对模板的转置与缩放会严重影响匹配结果,但容许一定的失真。

[模板匹配]

TemplateMaching.java:

import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

public class TemplateMaching {
	private String sourcePath,dstPath;
	private Mat source,dst;
	//原图片
	public void setSource(String picPath){
		this.sourcePath = picPath;
	}
	//需要匹配的部分
	public void setDst(String picPath){
		this.dstPath = picPath;
	}
	//处理,生成结果图
	public void process(){
		//将文件读入为OpenCV的Mat格式
		source = Highgui.imread(sourcePath);
		dst = Highgui.imread(dstPath);
		//创建于原图相同的大小,储存匹配度
		Mat result = Mat.zeros(source.rows(),source.cols(),CvType.CV_32FC1);
		//调用模板匹配方法
		Imgproc.matchTemplate(source, dst, result,Imgproc.TM_SQDIFF);
		//规格化
		Core.normalize(result, result, 0, 1,Core.NORM_MINMAX, -1);
		//获得最可能点,MinMaxLocResult是其数据格式,包括了最大、最小点的位置x、y
		MinMaxLocResult mlr = Core.minMaxLoc(result);
		Point matchLoc = mlr.minLoc;
		//在原图上的对应模板可能位置画一个绿色矩形
		Core.rectangle(source, matchLoc, new Point(matchLoc.x + dst.width(),matchLoc.y + dst.height()),new Scalar(0,255,0));
		//将结果输出到对应位置
		Highgui.imwrite("./Result/TMOutPut.png",source);
	}
	public static void main(String[] args) {
		System.loadLibrary("opencv_java249");

		TemplateMaching macher = new TemplateMaching();
		//设置原图
		macher.setSource("./Data/Lession4/BK.jpg");
		//设置要匹配的图
		macher.setDst("./Data/Lession4/BK_DST_DES.jpg");

		macher.process();
	}
}

[测试图例]

原图:

匹配图(原始、转置、缩放、失真):

   

[测试结果]

[原始测试]

↑匹配

[转置测试]

↑产生偏移

[缩放测试]

↑产生偏移,大小错误

[失真测试]

↑匹配

[总结]

对于图像识别,模板映射存在着较大的限制,在今后的学习中会着重寻找特性匹配的内容。

时间: 2024-10-23 06:33:35

OpenCV学习笔记[4]模板匹配 Java version的相关文章

OpenCV 学习笔记(模板匹配)

OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够高时,就认为找到了我们的目标. 在 OpenCV 中,提供了相应的函数完成这个操作. matchTemplate 函数:在模板和输入图像之间寻找匹配,获得匹配结果图像 minMaxLoc 函数:在给定的矩阵中寻找最大和最小值,并给出它们的位置 在具体介绍这两个函数之前呢,我们还要介绍一个概念,就是如何来评价两

opencv学习记录之模板匹配

模板匹配是指在图像A中寻找与图像B最相似的部分,一般A称为输入图像,B称为模板图像 模板匹配函数 result = cv2.matchTemplate(image , temp1 , method , [,mask]) result 函数每次计算模板和输入图像的重叠区域相似度之后将结果存入映射图像result中, result图像中每个点都代表一次相似度的比较,类型是单通道32位浮点型 若输入图像的尺寸位W×H,模板图像为w×h,则返回值为(W-w+1)×(H-h+1) 模板在原始图像上遍历,左

OpenCV学习笔记[5]FLANN特征匹配

OpenCV学习笔记:FLANN特征匹配 本次给出FLANN特征匹配的Java实现. [简介] 特征匹配记录下目标图像与待匹配图像的特征点(KeyPoint),并根据特征点集合构造特征量(descriptor),对这个特征量进行比较.筛选,最终得到一个匹配点的映射集合.我们也可以根据这个集合的大小来衡量两幅图片的匹配程度. 特征匹配与模板匹配不同,由于是计算特征点集合的相关度,转置操作对匹配影响不大,但它容易受到失真.缩放的影响. [特征匹配] FeatureMatching.java: imp

OpenCV学习笔记[3]Java Demo人脸识别

OpenCV学习笔记:Java Demo人脸识别 [简介] 我记得在很久以前,CSDN似乎搞过一个活动,给一个橘子林的照片,让程序计算相片里有多少个橘子.之所以对这个问题记忆犹新,是因为在专业学习初期,相比于排序遍历搜索等简单算法而言,"图像识别"算法一直是难以理解的东西,而我偏偏又痴迷于此,不管自己多么无知,对于令我迷惑的问题总是充满着解决的渴望. 通过对OpenCV的初步了解,我发现图像识别的很多问题都可以用它方便的解决,本次将是一个来自官方的人脸识别的实例,我们提供图像,使用内置

C++ Primer 学习笔记_77_模板与泛型编程 --实例化

模板与泛型编程 --实例化 引言: 模板是一个蓝图,它本身不是类或函数.编译器使用模板产生指定的类或函数的特定版本号.产生模板的特定类型实例的过程称为实例化. 模板在使用时将进行实例化,类模板在引用实际模板类型时实例化,函数模板在调用它或用它对函数指针进行初始化或赋值时实例化. 1.类的实例化 当编写Queue<int>qi时,编译器自己主动创建名为Queue<int>的类.实际上,编译器通过又一次编写Queue模板,用类型int取代模板形參的每次出现而创建Queue<int

C++ Primer 学习笔记_84_模板与泛型编程 --模板特化

模板与泛型编程 --模板特化 引言: 我们并不总是能够写出对全部可能被实例化的类型都最合适的模板.某些情况下,通用模板定义对于某个类型可能是全然错误的,通用模板定义或许不能编译或者做错误的事情;另外一些情况下,能够利用关于类型的一些特殊知识,编写比从模板实例化来的函数更有效率的函数. compare函数和 Queue类都是这一问题的好样例:与C风格字符串一起使用进,它们都不能正确工作. compare函数模板: template <typename Type> int compare(cons

C++ Primer 学习笔记_85_模板与泛型编程 --模板特化[续]

模板与泛型编程 --模板特化[续] 三.特化成员而不特化类 除了特化整个模板之外,还可以只特化push和pop成员.我们将特化push成员以复制字符数组,并且特化pop成员以释放该副本使用的内存: template<> void Queue<const char *>::push(const char *const &val) { char *new_item = new char[sizeof(val) + 1]; strncpy(new_item,val,sizeof(

C++ Primer 学习笔记_86_模板与泛型编程 --重载与函数模板

模板与泛型编程 --重载与函数模板 引言: 函数模板可以重载:可以定义有相同名字但参数数目或类型不同的多个函数模板,也可以定义与函数模板有相同名字的普通非模板函数. 但是,声明一组重载函数模板不保证可以成功调用它们,重载的函数模板可能会导致二义性. 一.函数匹配与函数模板 如果重载函数中既有普通函数又有函数模板,确定函数调用的步骤如下: 1.为这个函数名建立候选函数集合,包括: a.与被调用函数名字相同的任意普通函数. b.任意函数模板实例化,在其中,模板实参推断发现了与调用中所用函数实参相匹配

C++ Primer 学习笔记_81_模板与泛型编程 --类模板成员[续1]

模板与泛型编程 --类模板成员[续1] 二.非类型形参的模板实参 template <int hi,int wid> class Screen { public: Screen():screen(hi * wid,'#'), cursor(hi * wid),height(hi),width(wid) {} //.. private: std::string screen; std::string::size_type cursor; std::string::size_type height