2017-08-25 39 views
1

我剛剛找到關於Sikuli的信息,當時我正在尋找一個庫來查找較大圖像(均從文件加載)中給定圖像的匹配。 默認情況下,Sikuli只支持從文件中加載搜索到的圖片,但依賴專有類Screen來截取屏幕截圖以用作搜索的基礎...並且我希望能夠使用圖片文件。與Sikuli匹配來自文件的圖像

尋找解決方案已將我導向this question,但當您考慮到我對Sikuli沒有預先的經驗並且available documentation對我的需求不是特別有用時,答案有點模糊。

有沒有人有任何關於如何製作Screen,ScreenRegion,ImageScreen和ImageScreenLocation的定製實現的例子?即使是關於這些課程的更詳細文檔的鏈接也是一個很大的幫助。

我只想獲得另一個圖像文件中圖像匹配的座標,所以如果有另一個庫可以幫助完成這個任務,我很樂意瞭解它!

+1

你要檢查是否有另一個圖像中存在的圖像?您可以自己編寫代碼,無需使用任何外部軟件包。除非兩幅圖像的圖像質量不同,否則會更困難。 – user3437460

+0

是的,我想在更大的圖像中找到圖像的座標。最終目標是在不同尺寸/分辨率的匹配上具有靈活性。 –

+0

卡洛請看下面的答案。 – user3437460

回答

1

你可以自己用這樣的實現:

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種選擇:

  1. 掃描逐像素用一對嵌套循環來比較每個像素的RGB值。 (就像你如何比較兩個int 2D數組的相似性)

  2. 應該有可能爲2張圖像生成一個散列,然後比較散列值。

0

最後我放棄了Sikuli並用純OpenCV in my Android project:本Imgproc.matchTemplate()方法的伎倆,讓我所有的像素矩陣以「分數」爲作爲起點的似然點我的subimage。

0

Aah ... Sikuli也有這個答案...你只是沒有看起來足夠接近。 :) 答:FINDER類

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!"); 
+0

Aji,你能告訴我這個解決方案是否支持不同比例的匹配? 我使用Imgproc.matchTemplate提到的OpenCV解決方案僅在ScreenImage中查找完全相同大小的子圖像。我希望通過具有尋找一般模式的能力使其更強大,而不管ScreenImage大小/比例如何。 –

+0

嗨Marcel,Sikuli不允許這樣做。 Sikuli實際上只在內部使用openCV的Match模板功能來識別圖像。但是,我相信我已經閱讀過openCV有一個解決方案,如果您的圖像縮放,旋轉等。不幸的是,我沒有親自嘗試過這一點。抱歉。但是,對於Sikuli來說這是不可能的。 – Aji

0

隨着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>