程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Atitit 判斷判斷一張圖片是否包含另一張小圖片,

Atitit 判斷判斷一張圖片是否包含另一張小圖片,

編輯:JAVA綜合教程

Atitit 判斷判斷一張圖片是否包含另一張小圖片,


 

Atitit 判斷判斷一張圖片是否包含另一張小圖片 

 

1. keyword1

2.  模板匹配是在圖像中尋找目標的方法之一(切割+圖像相似度計算)1

3. 匹配效果2

4. 圖片相似度的算法(感知哈希算法”(Perceptual hash algorithm)2

5. 性能結果2

6. 如何提升性能3

6.1. 可以采用簡化的算法。二次匹配法,先大概確定區域3

6.2. 切割圖片設置一個step3

7. 參考資料3

8. ------code3

 

1. keyword

 

圖像匹配

圖片是否另外一張圖片的一部分

如果是標准圖片,模板匹配就好

 

2.  模板匹配是在圖像中尋找目標的方法之一(切割+圖像相似度計算)

。Come On, Boy.我們一起來看看模板匹配到底是怎麼回事。

模板匹配的工作方式
    模板匹配的工作方式跟直方圖的反向投影基本一樣,大致過程是這樣的:通過在輸入圖像上滑動圖像塊對實際的圖像塊和輸入圖像進行匹配。
    假設我們有一張100x100的輸入圖像,有一張10x10的模板圖像,查找的過程是這樣的:
  (1)從輸入圖像的左上角(0,0)開始,切割一塊(0,0)至(10,10)的臨時圖像;
  (2)用臨時圖像和模板圖像進行對比,對比結果記為c;
  (3)對比結果c,就是結果圖像(0,0)處的像素值;
  (4)切割輸入圖像從(0,1)至(10,11)的臨時圖像,對比,並記錄到結果圖像;
  (5)重復(1)~(4)步直到輸入圖像的右下角。
    大家可以看到,直方圖反向投影對比的是直方圖,而模板匹配對比的是圖像的像素值;模板匹配比直方圖反向投影速度要快一些,但是我個人認為直方圖反向投影的魯棒性會更好。

 

3. 匹配效果

效果不錯,基本可以確定查找到對應的區域坐標。。對於彩色圖片,可以使用色彩空間信息排除掉其他錯誤的匹配圖片,幾乎可以精確的確定一個圖片了。。

4. 圖片相似度的算法(感知哈希算法”(Perceptual hash algorithm)

感知哈希算法”(Perceptual hash algorithm),它的作用是對每張圖片生成一個“指紋”(fingerprint)字符串,然後比較不同圖片的指紋。結果越接近,就說明圖片越相似。

下面是一個最簡單的實現:

第一步,縮小尺寸。將圖片縮小到8×8的尺寸,總共64個像素。這一步的作用是去除圖片的細節,只保留結構、明暗等基本信息,摒棄不同尺寸、比例帶來的圖片差異。

第二步,簡化色彩。將縮小後的圖片,轉為64級灰度。也就是說,所有像素點總共只有64種顏色。

第三步,計算平均值。計算所有64個像素的灰度平均值。

第四步,比較像素的灰度。將每個像素的灰度,與平均值進行比較。大於或等於平均值,記為1;小於平均值,記為。

第五步,計算哈希值。將上一步的比較結果,組合在一起,就構成了一個64位的整數,這就是這張圖片的指紋。組合的次序並不重要,只要保證所有圖片都采用同樣次序就行了。

得到指紋以後,就可以對比不同的圖片,看看64位中有多少位是不一樣的。在理論上,這等同於計算“漢明距離”。如果不相同的數據位不超過5,就說明兩張圖片很相似;如果大於10,就說明這是兩張不同的圖片。

 

 

5. 性能結果

在我機子上,語言java ,純java實現。匹配變換dct算法size 8

每次移動step=5  。。使用了並行庫。。

速度大概在120s。。懶得繼續調整性能了,主要是測試思路,不過總結了思路,暫時先用著,理想的目標應該在3秒內。。

 

這個是參考文章的說法大概70秒。。語言是c#調用opencv接口

模板匹配和直方圖反向投影的效率
    總的來說,模板匹配和直方圖反向投影的效率都不高。在我的機器上,在1136*852大小的輸入圖像上匹配104*132的大小的模板圖像(都是單通道灰度圖像),大約需要700毫秒;而直方圖反向投影大約需要75000毫秒(1.25分鐘)。看來還需要繼續學習,尋找更好的處理方法

 

6. 如何提升性能

主要算法消耗在匹配小圖片上。。

6.1. 可以采用簡化的算法。二次匹配法,先大概確定區域

。首先可以大幅度的就確定幾張疑似圖像坐標。。然後對疑似圖像進行高精度算法匹配,就可以幾乎匹配到唯一的一張。。如果圖片是彩色圖片,再使用顏色信息二次匹配相似度。。以及直方圖等算法補充來匹配。。

6.2. 切割圖片設置一個step

比如要尋找的圖片大小60*60,可以設置一個20%以內的不敬step來跳躍切割,可以大幅度提升性能, 60/0.05=12.。 可以立馬提升12倍的性能。。

 

然後大概選定了區域後,在使用精確移動step來切割圖片。

 

7. 參考資料

 

如何判斷一張圖片是否包含另一張小圖片?圖像匹配?-CSDN論壇-CSDN.NET-中國最大的IT技術社區.html

模板匹配(Match Template) - Wuya - 博客園.html

算法 - JPEG的DCT壓縮原理,誰能通俗易懂解釋一下? - SegmentFault.html

作者:: 綽號:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿爾 拉帕努伊 ) 

漢字名:艾提拉(艾龍),   EMAIL:[email protected]

轉載請注明來源: http://www.cnblogs.com/attilax/

 

8. ------code

 

private void t() throws IOException {

String big = "c:\\t.jpeg";

String lit = "c:\\lit.jpg";

// diff==484

 

BufferedImage lit_img = ImageIO.read(new File(lit));

 

int w2 = lit_img.getWidth();

int h2 = lit_img.getHeight();

 

imgx imgx = new imgx();

BufferedImage img = ImageIO.read(new File(big));

int width = img.getWidth();

int h = img.getHeight();

ImagePHash imagePHash = new ImagePHash(8, 8);

ImageReader ImageReader1 = imgx.ImgReader(new File(big));

 

String ext = filex.getExtName(big);

imgx.save(lit_img, "c:\\0tmpPic\\" + filex.getUUidName() + "." + ext, ext);

ExecutorService es=Executors.newFixedThreadPool(3);

lab: for (int i = 0; i < width; i = i + 5) {

for (int j = 0; j < h; j = j + 5) {

// BufferedImage tmp =

// (BufferedImage) imgx.cutImage_retImg(big,

// i, j, w2, h2);

n++;

int x = i;

int y = j;

int nowCount=n;

Runnable ra = () -> {

 

process(lit_img, w2, h2, imgx, imagePHash, ImageReader1, nowCount,

ext, x, y);

};

es.execute(ra);

 

}

}

es.shutdown();

}

 

private int process(BufferedImage lit_img, int w2, int h2, imgx imgx,

ImagePHash imagePHash, ImageReader ImageReader1, int n, String ext,

int i, int j) {

Rectangle rect = new java.awt.Rectangle(i, j, w2, h2);

BufferedImage tmp = imgx.cutImg(rect, ImageReader1);

 

int dis = imagePHash.distance(tmp, lit_img);

 

if (dis < 5) {

log.info(" count:" + String.valueOf(n) + " dis:"

+ String.valueOf(dis) + " rect:" + String.valueOf(i) + "_"

+ String.valueOf(j));

// break lab;

}

if (dis < 10) {

String out = "c:\\0tmpPic\\" + filex.getUUidName() + "." + ext;

imgx.save(tmp, out, ext);

log.info(" count:" + String.valueOf(n) + " dis:"

+ String.valueOf(dis) + " rect:" + String.valueOf(i) + "_"

+ String.valueOf(j) + " file:" + out);

}

 

int cnt = n;

if (cnt % 100 == 0) {

String count = String.valueOf(cnt);

 

log.info(" count:" + count + " dis:" + String.valueOf(dis)

+ " rect:" + String.valueOf(i) + "_" + String.valueOf(j));

}

return n;

}

 

}

 

Atiend

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved