Opencv java模板匹配-角点检测(11)

函数

在opencv中有模板匹配的方法, Imgproc.matchTemplate(src, template, result, Imgproc.TM_CCOEFF);

这个方法输入的参数分别是:

src 标识输入的原图

template标识模板图片

result 匹配的结果

Imgproc.TM_CCOEFF 标识匹配的方法

例子:

String filename = "D:\\svnp\\MyYan\\res\\drawable\\lena.png";
		Mat src = Imgcodecs.imread(filename);
		Mat dst = new Mat();
		Mat dst1 = new Mat();
		Mat dst2 = new Mat();

	    Rect rect=new Rect(new Point(200,200),new Point(300,300));
	    Mat template=new Mat(src, rect);
	    
	    Imgcodecs.imwrite("D:\\svnp\\MyYan\\res\\drawable\\lena2.png", template);
	    
	    Mat result=new Mat();
	    
	    int method=Imgproc.TM_CCOEFF;
	    
	    Imgproc.matchTemplate(src, template, result, Imgproc.TM_CCOEFF);
		
	    Core.MinMaxLocResult result_m = Core.minMaxLoc(result);//取最大值和最小值
		
	    
	    Point maxloc = result_m.maxLoc;
	    Point minloc = result_m.minLoc;
	    
	    
	    //获取坐标
	    Point p1 ;
	    //如果是平方不同或者归一化平方不同,那么就取最小值
	    p1 = (method == Imgproc.TM_SQDIFF || method == Imgproc.TM_SQDIFF_NORMED) ? minloc : maxloc;

	    Point p2 = new Point(p1.x+template.cols(),p1.y+template.rows());

	    //绘制
	    Imgproc.rectangle(src,p1,p2,new Scalar(0,0,255));  
	    
	    HighGui.imshow("原图",src);
	    HighGui.imshow("模板",template);
	    HighGui.waitKey(10);
	    

分析

上面我们通过一个简单的例子来演示了 matchTemplate

里面的method 可以选的项目有这些:

    // C++: enum TemplateMatchModes
    public static final int
            TM_SQDIFF = 0,
            TM_SQDIFF_NORMED = 1,
            TM_CCORR = 2,
            TM_CCORR_NORMED = 3,
            TM_CCOEFF = 4,
            TM_CCOEFF_NORMED = 5;
  • TM_SQDIFF = 0: 平方不同
  • TM_SQDIFF_NORMED = 1:归一化平方不同
  • TM_CCORR = 2:相关性
  • TM_CCORR_NORMED = 3:归一化相关性
  • TM_CCOEFF = 4:相关因子
  • TM_CCOEFF_NORMED = 5:归一化相关因子

上面我们用的是相关因子,我们用相关因子归一

两种方法之间看不出来什么区别

不管那么多了,只要记住这个函数是模板匹配就行了

如果原图灰度化了能匹配吗:

如果原图进行了灰度化,那么模板也要进行灰度化,否则会出现下面的问题

Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: OpenCV(4.4.0) D:\opencv\opencv-4.4.0\modules\imgproc\src\templmatch.cpp:1163: error: (-215:Assertion failed) (depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2 in function 'cv::matchTemplate'
]
	at org.opencv.imgproc.Imgproc.matchTemplate_1(Native Method)
	at org.opencv.imgproc.Imgproc.matchTemplate(Imgproc.java:7523)
	at org.opencv.test.MatTestWdg.main(MatTestWdg.java:54)

角点检测

效果:

代码:

		String filename = "D:\\svnp\\MyYan\\res\\drawable\\lena.png";
		Mat src = Imgcodecs.imread(filename);
		Mat dst = new Mat();
		Mat dst1 = new Mat();
		Mat dst2 = new Mat();
	    Mat gray=new Mat();
	    Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
	    
	    Imgproc.threshold(gray, dst2,160 ,255,Imgproc.THRESH_TRIANGLE);
	    Imgproc.cornerHarris(dst2, dst, 2, 3, 0.04);
	    
	    
	 System.out.println(dst.cols()+"***********"+dst.rows());
	    
	  //绘制角点
	    float[] floats = new float[dst.cols()];
	    for (int i = 0; i < dst.rows() ; i++) {
	    	dst.get(i,0,floats);
	        for (int j = 0; j < floats.length; j++) {
	            if (floats[j] > 0.01){//越接近于角点数值越大
	                System.out.println(floats[j] );
	                Imgproc.circle(src,new Point(j,i),5,new Scalar(255,0,255));
	            }
	        }
	    }
	    
	    
	    HighGui.imshow("原图",src);
	    HighGui.imshow("灰度化",gray);
	    HighGui.imshow("阀值化",dst2);
	    HighGui.waitKey(0);

Imgproc.cornerHarris(src, dst2, blockSize, ksize, k);

src 输入图像

dst2 检测结果 不可以显示

blockSize:根据特征向量计算矩阵M的大小,常见取值为2

ksize:Sobel算子梯度计算 一般取值3

k:系数大小,取值范围为0.02-0.04

图片上绘制文字

中文文字目前java的没找到相关的接口 ,如果各位大佬实现了中文字符的putText希望能评论一下

Imgproc.putText(src, "helloWorld", new Point(src.rows()/3,src.cols()/3),Imgproc.FONT_HERSHEY_SIMPLEX, 2, new Scalar(0.9));

Imgproc.putText(img, text, org, fontFace, fontScale, color);

img 标识图片

text 标识输入的文本

org 文本写入点的位置

fontface 字体类型

fontScale字体大小

color 字体的颜色

上面是对Opencv java的一个简单的应用,写到这个地方感觉感触很多,学习opencv,我们像是在学习一个工具,这个工具可以帮助我们做一些图像处理,无论我们在这个工具上做出什么样的花样,但是工具的本质并没有变化,而且我们的性质也没有变化,我们程序员不是创造者,而是一个工具使用者,我总是想摆脱这样的困境,但是发现自己的脑力不够用,我总希望自己能够做出点不同的的东西,但是发现自己不过是一个工具的使用者,但是真正的创造者在工具的后面,他们给出什么样子的功能我们才可以使用什么样子的功能,我们改如何改变这样的困局,是否真的是我们需要把基础打好,慢慢的提高自己的地基,就像是金字塔,我们什么时候能走到顶峰,下面是一片海洋。。。。

希望对你有所帮助,希望不做工具人

 


版权声明:本文为datouniao1原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。