JAVA图像相似度识别器
? ? ? ? 日前,在天貓、淘寶、百度等各大網(wǎng)站上都早已出現(xiàn)了以圖搜圖功能,其主要通過輸入的圖片與現(xiàn)有圖片進(jìn)行相似度匹配,然后顯示出圖片相似度較高的商品或者網(wǎng)頁(yè),這是一件非常神奇的事,其實(shí),我們也可以自制一個(gè)簡(jiǎn)易的圖相相似度識(shí)別器來(lái)實(shí)現(xiàn)后期的以圖搜圖功能。
一、思路分析
? ? ? ? 先展示效果圖:
? ? ? ? 實(shí)驗(yàn)一:
? ? ? ?
? ? ? ? 實(shí)驗(yàn)二:?
?
? ? ? ? 實(shí)驗(yàn)三:??
?
? ? ? ? 實(shí)驗(yàn)四 :
?
? ? ? ? ?由上述四組實(shí)驗(yàn)可知,當(dāng)加載的兩張圖像為同一張圖片時(shí)(其中一張做了處理),顯示出的相似度較高;當(dāng)加載的圖像為不同圖片時(shí),顯示出的相似度較低。
? ? ? ? 該代碼的編寫思路如下:
? ? ? ? 將加載的圖像寬度和高度方向平均 8 等分,即整幅圖像分成 64 個(gè)區(qū)域,將整幅圖像灰度化,算出平均灰度值,再計(jì)算出每個(gè)區(qū)域的平均灰度值,若該區(qū)域的平均灰度值大于整幅圖像的平均灰度值,則記為 1,若該區(qū)域的平均灰度值小于整幅圖像的平均灰度值,則記為 0,最后按一定順序把每個(gè)區(qū)域的 0 或 1 字符串連起來(lái),我們把他稱之為該圖像的指紋,判斷兩幅圖像的相似度時(shí),對(duì)比兩幅圖像的指紋相似度即可。
二、代碼
import javax.swing.*; import java.awt.*; import java.awt.event.ActionListener;public class ImagePad extends JFrame{ImageListener imagelistener = new ImageListener ();String[] btnstrs = new String[] {"加載圖片","開始匹配"};public void addButton(JFrame jf, ActionListener al){Dimension dimension = new Dimension (120, 40);for (int i = 0; i < btnstrs.length; i++) {JButton btn = new JButton (btnstrs[i]);btn.setBackground (Color.WHITE);btn.setPreferredSize (dimension);btn.addActionListener (al);jf.add(btn);}}ImagePad(){setTitle ("相似度判別");setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);setSize (1540,900);setLocationRelativeTo (null);setLayout (new FlowLayout ());addButton(this,imagelistener);setVisible (true);imagelistener.setGraphics (this.getGraphics ());}public static void main(String[] args){new ImagePad ();} } import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class ImageListener implements ActionListener{private Graphics g = null;ImageUtils imageUtils;int[][] readImagePixArray1;int[][] readImagePixArray2;// setpublic void setGraphics(Graphics g){this.g = g;}public ImageListener(){imageUtils = new ImageUtils();readImagePixArray1 = imageUtils.readImagePix ("E:/image/10.png");readImagePixArray2 = imageUtils.readImagePix ("E:/image/00.png");}@Overridepublic void actionPerformed(ActionEvent e){// 先獲取按鈕上的字符串 用來(lái)判斷調(diào)用什么代碼String btnstr = e.getActionCommand ();if (btnstr.equals ("加載圖片")) {imageUtils.drawImage_1 (g,readImagePixArray1);imageUtils.zhiwen (readImagePixArray1);imageUtils.drawImage_2 (g,readImagePixArray2);imageUtils.zhiwen (readImagePixArray2);}else if (btnstr.equals("開始匹配")) {imageUtils.xiangsidu();}} } import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException;public class ImageUtils{int[] average1 = new int[65];int[] average2 = new int[65];boolean b = false;public int[][] readImagePix(String path){// 文件對(duì)象File file = new File (path);BufferedImage readimg = null;try {readimg = ImageIO.read (file);} catch (IOException e) {e.printStackTrace ();}int width = readimg.getWidth ();int height = readimg.getHeight ();int[][] imgArray = new int[width][height];for(int i = 0; i < width; i++){for(int j = 0; j < height; j++){imgArray[i][j] = readimg.getRGB (i, j);}}return imgArray;}public int getRgbGray(int numPixels){// byte -128 127int red = (numPixels>>16)&0xFF;int green = (numPixels>>8)&255;int blue = (numPixels>>0)&255;// 灰度 -- 減少計(jì)算量 以及 更方便計(jì)算int gray = (red + green + blue) / 3;return gray;}//根據(jù)二維數(shù)組 繪制圖片public void drawImage_1(Graphics g,int[][] imgArray){BufferedImage buffimg00 = new BufferedImage (imgArray.length, imgArray[0].length, BufferedImage.TYPE_INT_ARGB);for(int i = 0; i < imgArray.length; i++){for(int j = 0; j < imgArray[i].length; j++){buffimg00.setRGB (i,j,imgArray[i][j]);}}// 一次性繪制出來(lái) 只占一次IOg.drawImage (buffimg00, 30, 100, null);b = !b;System.out.print("圖像1的指紋為:");}public void drawImage_2(Graphics g,int[][] imgArray){BufferedImage buffimg00 = new BufferedImage (imgArray.length, imgArray[0].length, BufferedImage.TYPE_INT_ARGB);for(int i = 0; i < imgArray.length; i++){for(int j = 0; j < imgArray[i].length; j++){buffimg00.setRGB (i,j,imgArray[i][j]);}}// 一次性繪制出來(lái) 只占一次IOg.drawImage (buffimg00, 774, 100, null);System.out.println(" ");b = !b;System.out.print("圖像2的指紋為:");}public void zhiwen(int[][] imgArray){int width = 8;int height = 8;int a1 = imgArray.length/width;int b1 = imgArray[0].length/height;int a2 = imgArray.length - a1 * (width-1);int b2 = imgArray[0].length - b1 * (height-1);int[][] average = new int[width][height];int sum0 = 0;for(int m = 0; m < width; m++){for(int n = 0; n < height; n++){int sum = 0;if(m != (width-1) && n != (height-1)) {for(int i = 0 + m*a1; i < a1 + m*a1; i++){for(int j = 0 + n*b1; j < b1 + n*b1; j++){int num1 = imgArray[i][j];int gray1 = getRgbGray (num1);sum += gray1;}}average[m][n] = sum/(a1 * b1);}if(m == (width-1) && n != (height-1)) {for(int i = 0 + m*a1; i < a2 + m*a1; i++){for(int j = 0 + n*b1; j < b1 + n*b1; j++){int num1 = imgArray[i][j];int gray1 = getRgbGray (num1);sum += gray1;}}average[m][n] = sum/(a2 * b1);}if(m != (width-1) && n == (height-1)) {for(int i = 0 + m*a1; i < a1 + m*a1; i++){for(int j = 0 + n*b1; j < b2 + n*b1; j++){int num1 = imgArray[i][j];int gray1 = getRgbGray (num1);sum += gray1;}}average[m][n] = sum/(a1 * b2);}if(m == (width-1) && n == (height-1)) {for(int i = 0 + m*a1; i < a2 + m*a1; i++){for(int j = 0 + n*b1; j < b2 + n*b1; j++){int num1 = imgArray[i][j];int gray1 = getRgbGray (num1);sum += gray1;}}average[m][n] = sum/(a2 * b2);}sum0 += average[m][n];}}int average0 = sum0/(width*height);for(int n = 0; n < height; n++){for(int m = 0; m < width; m++){if(average[m][n] > average0)average[m][n] = 1;else average[m][n] = 0;if(b) {average1[m+width*n] = average[m][n];}else {average2[m+width*n] = average[m][n];}System.out.print(average[m][n]);}}}public void xiangsidu(){double a=0;for(int i=0;i<64;i++) {if(average1[i] == average2[i])a=a+1.5625;}System.out.println(" ");System.out.print("兩張圖像的相似度為:"+a);}}?
?
總結(jié)
以上是生活随笔為你收集整理的JAVA图像相似度识别器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LabVIEW升级图像识别功能
- 下一篇: 第十六课:libcurl库访问人工智能平