使用 Sikuli 匹配文件中的图像
Matching images from file with Sikuli
我在寻找一个库以在较大图像(均从文件加载)中查找给定图像的匹配项时,刚刚发现了 Sikuli。
默认情况下,Sikuli 仅支持从文件加载搜索图像,但依赖于专有 class 屏幕截取屏幕截图以用作搜索基础...我希望能够使用图像改为文件。
寻找解决方案导致我this question, but the answer is a bit vague when you consider that I have no prior experience with Sikuli and the available documentation对我的需求没有特别帮助。
有没有人有关于如何自定义实现 Screen、ScreenRegion、ImageScreen 和 ImageScreenLocation 的示例?即使 link 获得关于这些 class 的更详细的文档也会有很大帮助。
我只想获得另一个图像文件中图像匹配的坐标,所以如果有另一个库可以帮助完成这项任务,我会非常乐意了解它!
你可以自己实现,像这样:
class MyImage{
private BufferedImage img;
private int imgWidth;
private int imgHeight;
public MyImage(String imagePath){
try{
img = ImageIO.read(getClass().getResource(imagePath));
}catch(IOException ioe){System.out.println("Unable to open file");}
init();
}
public MyImage(BufferedImage img){
this.img = img;
init();
}
private void init(){
imgWidth = img.getWidth;
imgHeight = img.getHeight();
}
public boolean equals(BufferedImage img){
//Your algorithm for image comparison (See below desc for your choices)
}
public boolean contains(BufferedImage subImage){
int subWidth = subImage.getWidth();
int subHeight = subImage.getHeight();
if(subWidth > imgWidth || subHeight > imgHeight)
throw new IllegalArgumentException("SubImage is larger than main image");
for(int x=0; x<(imgHeight-subHeight); x++)
for(int y=0; y<(imgWidth-subWidth); y++){
BufferedImage cmpImage = img.getSumbimage(x, y, subWidth, subHeight);
if(subImage.equals(cmpImage))
return true;
}
return false;
}
}
contains 方法将从主图像抓取子图像并与给定的子图像进行比较。如果不相同,它将移动到下一个像素,直到它遍历整个图像。可能还有其他比逐像素移动更有效的方法,但这应该可行。
比较 2 张图片的相似度
您至少有 2 个选项:
使用一对嵌套循环逐像素扫描,比较每个像素的RGB值。 (就像比较两个 int 二维数组的相似性一样)
应该可以为 2 个图像生成一个哈希值,然后只比较哈希值。
最后我放弃了 Sikuli 并使用了纯 OpenCV in my Android project: Imgproc.matchTemplate() 方法成功了,给了我一个包含 "scores" 的所有像素矩阵这很可能是我的子图像的起点。
啊...Sikuli 对此也有答案...您只是看得不够仔细。 :)
答案:查找器 Class
Pattern searchImage = new Pattern("abc.png").similar((float)0.9);
String ScreenImage = "xyz.png"; //In this case, the image you want to search
Finder objFinder = null;
Match objMatch = null;
objFinder = new Finder(ScreenImage);
objFinder.find(searchImage); //searchImage is the image you want to search within ScreenImage
int counter = 0;
while(objFinder.hasNext())
{
objMatch = objFinder.next(); //objMatch gives you the matching region.
counter++;
}
if(counter!=0)
System.out.println("Match Found!");
使用 Sikuli,您可以检查一幅图像是否存在于另一幅图像中。
在这个示例代码中,图片是从文件中加载的。
此代码告诉我们第二张图片是否是第一张图片的一部分。
public static void main(String[] argv){
String img1Path = "/test/img1.png";
String img2Path = "/test/img2.png";
if ( findPictureRegion(img1Path, img2Path) == null )
System.out.println("Picture 2 was not found in picture 1");
else
System.out.println("Picture 2 is in picture 1");
}
public static ScreenRegion findPictureRegion(String refPictureName, String targetPictureName2){
Target target = new ImageTarget(new File(targetPictureName2));
target.setMinScore(0.5); // Precision of recognization from 0 to 1.
BufferedImage refPicture = loadPicture(refPictureName);
ScreenRegion screenRegion = new StaticImageScreenRegion(refPicture);
return screenRegion.find(target);
}
public static BufferedImage loadPicture(String pictureFullPath){
try {
return ImageIO.read(new File(pictureFullPath));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
为了使用 Sikuli 包,我用 Maven 添加了这个依赖:
<!-- SIKULI libraries -->
<dependency>
<groupId>org.sikuli</groupId>
<artifactId>sikuli-api</artifactId>
<version>1.1.0</version>
</dependency>
我在寻找一个库以在较大图像(均从文件加载)中查找给定图像的匹配项时,刚刚发现了 Sikuli。 默认情况下,Sikuli 仅支持从文件加载搜索图像,但依赖于专有 class 屏幕截取屏幕截图以用作搜索基础...我希望能够使用图像改为文件。
寻找解决方案导致我this question, but the answer is a bit vague when you consider that I have no prior experience with Sikuli and the available documentation对我的需求没有特别帮助。
有没有人有关于如何自定义实现 Screen、ScreenRegion、ImageScreen 和 ImageScreenLocation 的示例?即使 link 获得关于这些 class 的更详细的文档也会有很大帮助。
我只想获得另一个图像文件中图像匹配的坐标,所以如果有另一个库可以帮助完成这项任务,我会非常乐意了解它!
你可以自己实现,像这样:
class MyImage{
private BufferedImage img;
private int imgWidth;
private int imgHeight;
public MyImage(String imagePath){
try{
img = ImageIO.read(getClass().getResource(imagePath));
}catch(IOException ioe){System.out.println("Unable to open file");}
init();
}
public MyImage(BufferedImage img){
this.img = img;
init();
}
private void init(){
imgWidth = img.getWidth;
imgHeight = img.getHeight();
}
public boolean equals(BufferedImage img){
//Your algorithm for image comparison (See below desc for your choices)
}
public boolean contains(BufferedImage subImage){
int subWidth = subImage.getWidth();
int subHeight = subImage.getHeight();
if(subWidth > imgWidth || subHeight > imgHeight)
throw new IllegalArgumentException("SubImage is larger than main image");
for(int x=0; x<(imgHeight-subHeight); x++)
for(int y=0; y<(imgWidth-subWidth); y++){
BufferedImage cmpImage = img.getSumbimage(x, y, subWidth, subHeight);
if(subImage.equals(cmpImage))
return true;
}
return false;
}
}
contains 方法将从主图像抓取子图像并与给定的子图像进行比较。如果不相同,它将移动到下一个像素,直到它遍历整个图像。可能还有其他比逐像素移动更有效的方法,但这应该可行。
比较 2 张图片的相似度
您至少有 2 个选项:
使用一对嵌套循环逐像素扫描,比较每个像素的RGB值。 (就像比较两个 int 二维数组的相似性一样)
应该可以为 2 个图像生成一个哈希值,然后只比较哈希值。
最后我放弃了 Sikuli 并使用了纯 OpenCV in my Android project: Imgproc.matchTemplate() 方法成功了,给了我一个包含 "scores" 的所有像素矩阵这很可能是我的子图像的起点。
啊...Sikuli 对此也有答案...您只是看得不够仔细。 :) 答案:查找器 Class
Pattern searchImage = new Pattern("abc.png").similar((float)0.9);
String ScreenImage = "xyz.png"; //In this case, the image you want to search
Finder objFinder = null;
Match objMatch = null;
objFinder = new Finder(ScreenImage);
objFinder.find(searchImage); //searchImage is the image you want to search within ScreenImage
int counter = 0;
while(objFinder.hasNext())
{
objMatch = objFinder.next(); //objMatch gives you the matching region.
counter++;
}
if(counter!=0)
System.out.println("Match Found!");
使用 Sikuli,您可以检查一幅图像是否存在于另一幅图像中。 在这个示例代码中,图片是从文件中加载的。 此代码告诉我们第二张图片是否是第一张图片的一部分。
public static void main(String[] argv){
String img1Path = "/test/img1.png";
String img2Path = "/test/img2.png";
if ( findPictureRegion(img1Path, img2Path) == null )
System.out.println("Picture 2 was not found in picture 1");
else
System.out.println("Picture 2 is in picture 1");
}
public static ScreenRegion findPictureRegion(String refPictureName, String targetPictureName2){
Target target = new ImageTarget(new File(targetPictureName2));
target.setMinScore(0.5); // Precision of recognization from 0 to 1.
BufferedImage refPicture = loadPicture(refPictureName);
ScreenRegion screenRegion = new StaticImageScreenRegion(refPicture);
return screenRegion.find(target);
}
public static BufferedImage loadPicture(String pictureFullPath){
try {
return ImageIO.read(new File(pictureFullPath));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
为了使用 Sikuli 包,我用 Maven 添加了这个依赖:
<!-- SIKULI libraries -->
<dependency>
<groupId>org.sikuli</groupId>
<artifactId>sikuli-api</artifactId>
<version>1.1.0</version>
</dependency>