国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java實現圖片對比功能

Java實現圖片對比功能

2019-11-28 14:21hebedich JAVA教程

個人從來沒有研究過圖像學,也沒看過什么論文或者相關文檔,寫這個完全是靠google和百度,自己寫了個實驗了下,測試用例也少,估計有大BUG的存在,所以看的人權當學習交流,切勿生產使用。

  之前用按鍵精靈寫過一些游戲輔助,里面有個函數叫FindPic,就上在屏幕范圍查找給定的一張圖片,返回查找到的坐標位置。

  現在,Java來實現這個函數類似的功能。

  算法描述:

屏幕截圖,得到圖A,(查找的目標圖片為圖B);
遍歷圖A的像素點,根據圖B的尺寸,得到圖B四個角映射到圖A上的四個點;
得到的四個點與圖B的四個角像素點的值比較。如果四個點一樣,執行步驟4;否則,回到步驟2繼續;
進一步對比,將映射范圍內的全部點與圖B全部的點比較。如果全部一樣,則說明圖片已找到;否則,回到步驟2繼續;
  這里,像素之間的比較是通過BufferedImage對象獲取每個像素的RGB值來比較的。如下,將BufferedImage轉換為int二維數組:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 根據BufferedImage獲取圖片RGB數組
* @param bfImage
* @return
*/
public static int[][] getImageGRB(BufferedImage bfImage) {
  int width = bfImage.getWidth();
  int height = bfImage.getHeight();
  int[][] result = new int[height][width];
  for (int h = 0; h < height; h++) {
    for (int w = 0; w < width; w++) {
      //使用getRGB(w, h)獲取該點的顏色值是ARGB,而在實際應用中使用的是RGB,所以需要將ARGB轉化成RGB,即bufImg.getRGB(w, h) & 0xFFFFFF。
      result[h][w] = bfImage.getRGB(w, h) & 0xFFFFFF;
    }
  }
  return result;
}

   比較兩個像素點的RGB值是否相同,是通過異或操作比較的(據說比==效率更高),如果異或操作后得到的值為0,說明兩個像素點的RGB一樣,否則不一樣。

  下面附上算法完整java代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package com.jebysun.test.imagefind;
 
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 java.io.IOException;
 
import javax.imageio.ImageIO;
/**
* 屏幕上查找指定圖片
* @author Jeby Sun
* @date 2014-09-13
* @website http://www.jebysun.com
*/
public class ImageFindDemo {
  
  BufferedImage screenShotImage;  //屏幕截圖
  BufferedImage keyImage;      //查找目標圖片
  
  int scrShotImgWidth;       //屏幕截圖寬度
  int scrShotImgHeight;       //屏幕截圖高度
  
  int keyImgWidth;         //查找目標圖片寬度
  int keyImgHeight;         //查找目標圖片高度
  
  int[][] screenShotImageRGBData;  //屏幕截圖RGB數據
  int[][] keyImageRGBData;     //查找目標圖片RGB數據
  
  int[][][] findImgData;      //查找結果,目標圖標位于屏幕截圖上的坐標數據
  
  
  public ImageFindDemo(String keyImagePath) {
    screenShotImage = this.getFullScreenShot();
    keyImage = this.getBfImageFromPath(keyImagePath);
    screenShotImageRGBData = this.getImageGRB(screenShotImage);
    keyImageRGBData = this.getImageGRB(keyImage);
    scrShotImgWidth = screenShotImage.getWidth();
    scrShotImgHeight = screenShotImage.getHeight();
    keyImgWidth = keyImage.getWidth();
    keyImgHeight = keyImage.getHeight();
    
    //開始查找
    this.findImage();
    
  }
  
  /**
  * 全屏截圖
  * @return 返回BufferedImage
  */
  public BufferedImage getFullScreenShot() {
    BufferedImage bfImage = null;
    int width = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    int height = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
    try {
      Robot robot = new Robot();
      bfImage = robot.createScreenCapture(new Rectangle(0, 0, width, height));
    } catch (AWTException e) {
      e.printStackTrace();
    }
    return bfImage;
  }
  
  /**
  * 從本地文件讀取目標圖片
  * @param keyImagePath - 圖片絕對路徑
  * @return 本地圖片的BufferedImage對象
  */
  public BufferedImage getBfImageFromPath(String keyImagePath) {
    BufferedImage bfImage = null;
    try {
      bfImage = ImageIO.read(new File(keyImagePath));
    } catch (IOException e) {
      e.printStackTrace();
    }
    return bfImage;
  }
  
  /**
  * 根據BufferedImage獲取圖片RGB數組
  * @param bfImage
  * @return
  */
  public int[][] getImageGRB(BufferedImage bfImage) {
    int width = bfImage.getWidth();
    int height = bfImage.getHeight();
    int[][] result = new int[height][width];
    for (int h = 0; h < height; h++) {
      for (int w = 0; w < width; w++) {
        //使用getRGB(w, h)獲取該點的顏色值是ARGB,而在實際應用中使用的是RGB,所以需要將ARGB轉化成RGB,即bufImg.getRGB(w, h) & 0xFFFFFF。
        result[h][w] = bfImage.getRGB(w, h) & 0xFFFFFF;
      }
    }
    return result;
  }
  
  
  /**
  * 查找圖片
  */
  public void findImage() {
    findImgData = new int[keyImgHeight][keyImgWidth][2];
    //遍歷屏幕截圖像素點數據
    for(int y=0; y<scrShotImgHeight-keyImgHeight; y++) {
      for(int x=0; x<scrShotImgWidth-keyImgWidth; x++) {
        //根據目標圖的尺寸,得到目標圖四個角映射到屏幕截圖上的四個點,
        //判斷截圖上對應的四個點與圖B的四個角像素點的值是否相同,
        //如果相同就將屏幕截圖上映射范圍內的所有的點與目標圖的所有的點進行比較。
        if((keyImageRGBData[0][0]^screenShotImageRGBData[y][x])==0
            && (keyImageRGBData[0][keyImgWidth-1]^screenShotImageRGBData[y][x+keyImgWidth-1])==0
            && (keyImageRGBData[keyImgHeight-1][keyImgWidth-1]^screenShotImageRGBData[y+keyImgHeight-1][x+keyImgWidth-1])==0
            && (keyImageRGBData[keyImgHeight-1][0]^screenShotImageRGBData[y+keyImgHeight-1][x])==0) {
          
          boolean isFinded = isMatchAll(y, x);
          //如果比較結果完全相同,則說明圖片找到,填充查找到的位置坐標數據到查找結果數組。
          if(isFinded) {
            for(int h=0; h<keyImgHeight; h++) {
              for(int w=0; w<keyImgWidth; w++) {
                findImgData[h][w][0] = y+h;
                findImgData[h][w][1] = x+w;
              }
            }
            return;
          }
        }
      }
    }
  }
  
  /**
  * 判斷屏幕截圖上目標圖映射范圍內的全部點是否全部和小圖的點一一對應。
  * @param y - 與目標圖左上角像素點想匹配的屏幕截圖y坐標
  * @param x - 與目標圖左上角像素點想匹配的屏幕截圖x坐標
  * @return
  */
  public boolean isMatchAll(int y, int x) {
    int biggerY = 0;
    int biggerX = 0;
    int xor = 0;
    for(int smallerY=0; smallerY<keyImgHeight; smallerY++) {
      biggerY = y+smallerY;
      for(int smallerX=0; smallerX<keyImgWidth; smallerX++) {
        biggerX = x+smallerX;
        if(biggerY>=scrShotImgHeight || biggerX>=scrShotImgWidth) {
          return false;
        }
        xor = keyImageRGBData[smallerY][smallerX]^screenShotImageRGBData[biggerY][biggerX];
        if(xor!=0) {
          return false;
        }
      }
      biggerX = x;
    }
    return true;
  }
  
  /**
  * 輸出查找到的坐標數據
  */
  private void printFindData() {
    for(int y=0; y<keyImgHeight; y++) {
      for(int x=0; x<keyImgWidth; x++) {
        System.out.print("("+this.findImgData[y][x][0]+", "+this.findImgData[y][x][1]+")");
      }
      System.out.println();
    }
  }
 
  
  public static void main(String[] args) {
    String keyImagePath = "D:/key.png";
    ImageFindDemo demo = new ImageFindDemo(keyImagePath);
    demo.printFindData();
  }
 
}

  這種算法是精確比較,只要有一個像素點有差異,就會找不到圖片。當然,如果想指定一個比較的精確度,我也有個思路,就是在算法步驟4比較映射范圍內全部像素點的時候做個統計,如果90%的點都相同,那就是說精確度是0.9。

  另外,可能還要考慮效率問題,不過,我在我的應用場景中并不太在意效率。如果有朋友看到這篇文章,對這個話題有更好的想法,請留言。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色综合久久久 | 精品护士一区二区三区 | 隔壁老王国产在线精品 | 亚洲在线日韩 | 狠狠躁躁夜夜躁波多野结依 | 中文字幕视频在线观看 | 国产黄色a级 | 亚洲精品乱码 | 91麻豆精品国产91久久久资源速度 | 一区二区三区久久久久久 | 寡妇高潮免费视频一区二区三区 | 在线观看一区二区三区视频 | 欧美日韩视频在线 | 在线精品亚洲欧美日韩国产 | 久久久亚洲精品视频 | 国产精品不卡一区 | 日本在线观看一区 | 午夜天堂精品久久久久 | 伊人五月 | 精品一区二区三区视频 | 91亚洲国产成人久久精品网站 | 亚洲成人中文字幕 | 黄色电影天堂 | 亚洲免费视频网站 | 国产乱码精品一区二区三区忘忧草 | 欧美自拍一区 | 日韩欧美综合 | 偷拍自拍第一页 | a在线看 | 亚洲一区二区在线 | 91免费在线视频 | 二区视频 | 国产精品毛片久久久久久 | 成人国产精品久久 | 国产日韩一区二区 | 欧美中文字幕在线观看 | 日本丶国产丶欧美色综合 | 日韩欧美在线免费观看 | 好看的一级毛片 | 日韩精品一区二区在线观看 | 亚洲精品在线观看网站 |