java实现图像模版匹配(蜗牛学院)

package com.woniu.test;

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
//java图像模版匹配
//核心思路:用一张小图片,在一张大图片里去寻找,并返回该小图片所在的坐标位置,然后将鼠标移向该处,并实施相应操作。并更据页面的反馈,进行相应的判断(断言)
//1.对需要操作的对象进行截图,得到一张小图片,并保存。
//2.对当前屏幕进行截图,获得一张大图片,保存或放在内存中
//3.利用模版匹配,在大图片中,按像素对小图片进行滑动,找到小图片所在的位置。
//4.对该坐标位置(X,Y),加上小图片高度的一半(H),宽度的一般(W),得到该小图片的中心位置,即是我们要操作的坐标(X+W,Y+H)
//5。将鼠标移向该坐标(X,Y),并进行相应操作(输入,单机,双击,右键等).
//6.继续第二轮操作,第三轮操作。直到第N轮。最后进行模版匹配,来确认是否存在和预期结果一致的小图片,进而实现断言。
//由于是基于的像素匹配,所以,如果界面风格发生变化,可能出现识别不到的情况。
public class ImageMatch {

	public static void main(String[] args) throws Exception {
		ImageMatch im = new ImageMatch();
//		BufferedImage bi = im.getScreenShot();
//		int[][] result = im.getImageRGB(bi);
//		for (int y = 0; y < result.length; y++) {
//			for (int x = 0; x < result[y].length; x++) {
//				System.out.println(result[y][x]);
//			}
//		}
		Runtime.getRuntime().exec("C:/Windows/system32/calc.exe");
		Thread.sleep(3000);

		String imageDir = System.getProperty("user.dir") + "/wincalc/";
		int[] target = im.findImage(imageDir + "3.png");
		System.out.println("找到一个点:" + target[0] + " : " + target[1]);
	}

	// 截图
	public BufferedImage getScreenShot() {
		BufferedImage bfImage = null;
		int captureWidth = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
		int captureHeight = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
		try {
			Robot robot = new Robot();
			Rectangle screenRect = new Rectangle(0,0,captureWidth,captureHeight);
			bfImage = robot.createScreenCapture(screenRect);
		} catch (AWTException e) {
			e.printStackTrace();
		}
		return bfImage;
	}

	// 获取像素点值
	public int[][] getImageRGB(BufferedImage bfImage) {
		int width = bfImage.getWidth();
		int height = bfImage.getHeight();
		int[][] result = new int[width][height];
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				// 对某个像素点的RGB编码并存入数据库
				result[x][y] = bfImage.getRGB(x, y) & 0xFFFFFF;
				//单独获取每一个像素点的Red,Green,和Blue的值。
				//int r = (bfImage.getRGB(x, y) & 0xFF0000) >> 16;
				//int g = (bfImage.getRGB(x, y) & 0xFF00) >> 8;
				//int b = bfImage.getRGB(x, y) & 0xFF;
			}
		}
		return result;
	}

	// 进行模板匹配
	public int[] findImage(String imagePath) {
		BufferedImage bigImage = this.getScreenShot();	// 当前屏幕截图
		BufferedImage smallImage = null;		// 打开预选保存的小图片
		try {
			smallImage = ImageIO.read(new File(imagePath));
		} catch (Exception e) {
			e.printStackTrace();
		}

		int bigWidth = bigImage.getWidth();
		int bigHeight = bigImage.getHeight();

		int smallWidth = smallImage.getWidth();
		int smallHeight = smallImage.getHeight();

		int[][] bigData = this.getImageRGB(bigImage);
		int[][] smallData = this.getImageRGB(smallImage);

		int[] target = {-1, -1};

		for (int y=0; y<bigHeight-smallHeight; y++) {
			for (int x=0; x<bigWidth-smallWidth; x++) {
				// 对关键点进行先期匹配,降低运算复杂度。如果关键点本身就不匹配,就没必要再去匹配小图的每一个像素点。
				if (bigData[x][y] == smallData[0][0] &&   // 左上角
					bigData[x+smallWidth-1][y] == smallData[smallWidth-1][0] &&  // 右上角
					bigData[x][y+smallHeight-1] == smallData[0][smallHeight-1] && // 左下角
					bigData[x+smallWidth-1][y+smallHeight-1] == smallData[smallWidth-1][smallHeight-1] && // 右下角
					bigData[x+smallWidth/2][y+smallHeight/2] == smallData[smallWidth/2][smallHeight/2]
					) {
					// 进行全像素匹配
					boolean isMatched = this.checkAllMatch(x, y, smallHeight, smallWidth, bigData, smallData);
					if (isMatched) {
						System.out.println("像素点X" + x + " : Y" + y + ",对应的值为:" + bigData[x][y]);
						// 获取小图的中心位置的点
						int centerX = x + smallWidth/2;
						int centerY = y + smallHeight/2;
						target[0] = centerX;
						target[1] = centerY;
						return target;
					}
				}
			}
		}

		return target;
	}

	// 全像素匹配
	public boolean checkAllMatch(int x, int y, int smallHeight, int smallWidth, int[][] bigData, int[][] smallData) {
		boolean isMatched = true;
		for (int smallY=0; smallY<smallHeight; smallY++) {
			for (int smallX=0; smallX<smallWidth; smallX++) {
				// 如果发现有一个像素点,两者的值不一样,则认为不相等,如果不相等,则没必要继续比较其它点.
				if (bigData[x+smallX][y+smallY] != smallData[smallX][smallY]) {
					isMatched = false;
					return isMatched;
				}
			}
		}
		return isMatched;
	}
}
package com.woniu.test;

public class CalcTestDemo {

	static AutoTestRobot robot = new AutoTestRobot();

	public static void main(String[] args) throws Exception {

		Runtime.getRuntime().exec("java -jar D:/Other/JavaSwingCalc.jar");
		Thread.sleep(3000);

		String imageDir = System.getProperty("user.dir") + "/javacalc/";

		robot.moveAndInput(imageDir + "numberx.png", "300");
		robot.moveAndInput(imageDir + "numbery.png", "200");
		robot.moveAndSelect(imageDir + "calctype.png", 1);
		robot.moveAndClick(imageDir + "docalc.png");

		if (robot.isExists(imageDir + "result.png")) {
			System.out.println("测试成功.");
		}
		else {
			System.out.println("测试失败.");
		}
	}

}

  

原文地址:https://www.cnblogs.com/LiTry/p/9038579.html

时间: 2024-10-16 00:44:26

java实现图像模版匹配(蜗牛学院)的相关文章

OpenCV2马拉松第13圈——模版匹配

收入囊中 在http://blog.csdn.net/abcd1992719g/article/details/25505315这里,我们已经学习了如何利用反向投影和meanshift算法来在图像中查找给定模版图片的位置.meanshift针对的是单张图像,在连续图像序列的跟踪中,camshift(Continuously Adaptive Mean-SHIFT)是一种著名的算法.但在这里,我们先不讨论camshift,而是先讨论最简单的模版匹配. 模版匹配算法 opencv normalize

单目标模版匹配

就是实现这样: 其中,能够根据模版运算,自动实时从图中找出相同模版的地方.从而能够计算出镜头的相对位移. 模板匹配的工作方式    模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配.    假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:  (1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像:  (2)用临时图像和模板图像进行对比,对比结果记为c: 

Opencv图像识别从零到精通(32)----直方图对比,模版匹配,方向投影

0.预备知识 归一化就是要把需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内. 函数原型: <span style="font-size:18px;">void normalize(InputArray src,OutputArray dst, double alpha=1,doublebeta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() ) </span>

java实现图像灰度化

/*在研究Java实现将一张图片转成字符画的时候,发现将图像转化字符串是根据照片的灰度采用不同的字符画出来,形成一个灰度表.于是就研究了下关于灰度值这个东西,于是跳了一个大坑...因为鄙人用的ubuntu,所以我的代码路径会有所不同.直接贴出原博文代码.故事的开始是这样的...*/ 1.关于Java实现将一张图片转成字符画(原文地址:http://blog.csdn.net/zhouli_05/article/details/7913263) 怎么样用Java实现将一张图片转成字符画?? 输入:

java实现串的匹配和替换

/** *测试类,测试两个功能类,MatchBrote_force类和subString_act类的功能实现*创建的类为TestMatchBrote_force *@author LZ *@vesion 6.2 */ //import com.edu.software.LZ.*; public class TestMatchBrote_force { public static void main(String[] args){ /** *新建对象调用MatchBrote_force类*得到字串

视觉SLAM之RANSAC算法用于消除图像误匹配的原理

在基于特征点的视觉SLAM中,通常情况下,在特征匹配过程中往往会存在误匹配信息,使得计算获取的位姿精度低,易产生位姿估计失败的问题,因此,剔除这些错配点有很大的必要性.常会用到RANSAC算法进行消除两两匹配图像的误匹配点,如果只停留在应用的层面上很简单,直接调用opencv函数就行,看到效果时,感觉好神奇,到底怎么实现的啊,以前一直也没弄太明白,与图像结合的博客也比较少,在查阅了一些资料后,笔者似乎明白了一点,希望笔者的总结会对您的理解有帮助. 首先先介绍一下RANSAC算法(RANdom S

java图形图像SVG转PPM程序代写 qq:928900200

Background Many image file formats encode image data as a 2-D matrix or raster of pixel colors. The amount of available color information is fixed by the image's width and height of its resolution. If the resolution is too small, you will have proble

Robotics Lab3 ——图像特征匹配、跟踪与相机运动估计

Robotics Lab3 --图像特征匹配.跟踪与相机运动估计 图像特征匹配 图像特征点 携带摄像头的机器人在运动过程中,会连续性地获取多帧图像,辅助其感知周围环境和自身运动.时间序列上相连的两幅或多幅图像,通常存在相同的景物,只是它们在图像中的位置不同.而位置的变换恰恰暗含了相机的运动,这时就需要相邻图像间的相似性匹配. 选取一大块图像区域进行运动估计是不可取的.已知图像在计算机内部是以数字矩阵的形式存储的,[如灰度图的每个元素代表了单个像素的灰度值].而对于点的提取和匹配较为方便,且和数字

Java 格式化时间 不匹配

今天获取的时间不匹配,获取的时间是现在的时间,但是现实的时候确实 1970 年, 让我拍很郁闷! 应该讲 服务器返回的时间数据 * 1000 之后才进行,解析: Time 解析工具类: package com.hades.newstyle.utils; import java.text.DateFormat; import java.util.Date; /** * 传递一个时间, * 格式化时间的工具类: * * * @author Hades * @time Nov 4, 2014 * @t