java指紋識別+谷歌圖片識別技術_源代碼

java指紋識別+谷歌圖片識別技術_源代碼

 

[java] view plaincopy

  1. import java.awt.image.BufferedImage;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4.   
  5. public class SimilarImageSearch {  
  6.   
  7.     /** 
  8.      * @param args 
  9.      */  
  10.     public static void main(String[] args) {  
  11.         List<String> hashCodes = new ArrayList<String>();  
  12.           
  13.         String filename = ImageHelper.path + "\\images\\";  
  14.         String hashCode = null;  
  15.           
  16.         for (int i = 0; i < 6; i++)  
  17.         {  
  18.             hashCode = produceFingerPrint(filename + "example" + (i + 1) + ".jpg");  
  19.             hashCodes.add(hashCode);  
  20.         }          
  21.         System.out.println("Resources: ");  
  22.         System.out.println(hashCodes);  
  23.         System.out.println();  
  24.           
  25.         String sourceHashCode = produceFingerPrint(filename + "source.jpg");  
  26.         System.out.println("Source: ");  
  27.         System.out.println(sourceHashCode);  
  28.         System.out.println();  
  29.           
  30.         for (int i = 0; i < hashCodes.size(); i++)  
  31.         {  
  32.             int difference = hammingDistance(sourceHashCode, hashCodes.get(i));  
  33.             System.out.print("漢明距離:"+difference+"     ");  
  34.             if(difference==0){  
  35.                 System.out.println("source.jpg圖片跟example"+(i+1)+".jpg一樣");  
  36.             }else if(difference<=5){  
  37.                 System.out.println("source.jpg圖片跟example"+(i+1)+".jpg非常相似");  
  38.             }else if(difference<=10){  
  39.                 System.out.println("source.jpg圖片跟example"+(i+1)+".jpg有點相似");  
  40.             }else if(difference>10){  
  41.                 System.out.println("source.jpg圖片跟example"+(i+1)+".jpg完全不一樣");  
  42.             }  
  43.         }  
  44.           
  45.     }  
  46.   
  47.     /** 
  48.      * 計算"漢明距離"(Hamming distance)。 
  49.      * 如果不相同的數據位不超過5,就說明兩張圖片很相似;如果大於10,就說明這是兩張不同的圖片。 
  50.      * @param sourceHashCode 源hashCode 
  51.      * @param hashCode 與之比較的hashCode 
  52.      */  
  53.     public static int hammingDistance(String sourceHashCode, String hashCode) {  
  54.         int difference = 0;  
  55.         int len = sourceHashCode.length();  
  56.           
  57.         for (int i = 0; i < len; i++) {  
  58.             if (sourceHashCode.charAt(i) != hashCode.charAt(i)) {  
  59.                 difference ++;  
  60.             }  
  61.         }  
  62.           
  63.         return difference;  
  64.     }  
  65.   
  66.     /** 
  67.      * 生成圖片指紋 
  68.      * @param filename 文件名 
  69.      * @return 圖片指紋 
  70.      */  
  71.     public static String produceFingerPrint(String filename) {  
  72.         BufferedImage source = ImageHelper.readPNGImage(filename);// 讀取文件  
  73.   
  74.         int width = 8;  
  75.         int height = 8;  
  76.           
  77.         // 第一步,縮小尺寸。  
  78.         // 將圖片縮小到8x8的尺寸,總共64個像素。這一步的作用是去除圖片的細節,只保留結構、明暗等基本信息,摒棄不同尺寸、比例帶來的圖片差異。  
  79.         BufferedImage thumb = ImageHelper.thumb(source, width, height, false);  
  80.           
  81.         // 第二步,簡化色彩。  
  82.         // 將縮小後的圖片,轉爲64級灰度。也就是說,所有像素點總共只有64種顏色。  
  83.         int[] pixels = new int[width * height];  
  84.         for (int i = 0; i < width; i++) {  
  85.             for (int j = 0; j < height; j++) {  
  86.                 pixels[i * height + j] = ImageHelper.rgbToGray(thumb.getRGB(i, j));  
  87.             }  
  88.         }  
  89.           
  90.         // 第三步,計算平均值。  
  91.         // 計算所有64個像素的灰度平均值。  
  92.         int avgPixel = ImageHelper.average(pixels);  
  93.           
  94.         // 第四步,比較像素的灰度。  
  95.         // 將每個像素的灰度,與平均值進行比較。大於或等於平均值,記爲1;小於平均值,記爲0。  
  96.         int[] comps = new int[width * height];  
  97.         for (int i = 0; i < comps.length; i++) {  
  98.             if (pixels[i] >= avgPixel) {  
  99.                 comps[i] = 1;  
  100.             } else {  
  101.                 comps[i] = 0;  
  102.             }  
  103.         }  
  104.           
  105.         // 第五步,計算哈希值。  
  106.         // 將上一步的比較結果,組合在一起,就構成了一個64位的整數,這就是這張圖片的指紋。組合的次序並不重要,只要保證所有圖片都採用同樣次序就行了。  
  107.         StringBuffer hashCode = new StringBuffer();  
  108.         for (int i = 0; i < comps.length; i+= 4) {  
  109.             int result = comps[i] * (int) Math.pow(2, 3) + comps[i + 1] * (int) Math.pow(2, 2) + comps[i + 2] * (int) Math.pow(2, 1) + comps[i + 2];  
  110.             hashCode.append(binaryToHex(result));  
  111.         }  
  112.           
  113.         // 得到指紋以後,就可以對比不同的圖片,看看64位中有多少位是不一樣的。  
  114.         return hashCode.toString();  
  115.     }  
  116.   
  117.     /** 
  118.      * 二進制轉爲十六進制 
  119.      * @param int binary 
  120.      * @return char hex 
  121.      */  
  122.     private static char binaryToHex(int binary) {  
  123.         char ch = ' ';  
  124.         switch (binary)  
  125.         {  
  126.         case 0:  
  127.             ch = '0';  
  128.             break;  
  129.         case 1:  
  130.             ch = '1';  
  131.             break;  
  132.         case 2:  
  133.             ch = '2';  
  134.             break;  
  135.         case 3:  
  136.             ch = '3';  
  137.             break;  
  138.         case 4:  
  139.             ch = '4';  
  140.             break;  
  141.         case 5:  
  142.             ch = '5';  
  143.             break;  
  144.         case 6:  
  145.             ch = '6';  
  146.             break;  
  147.         case 7:  
  148.             ch = '7';  
  149.             break;  
  150.         case 8:  
  151.             ch = '8';  
  152.             break;  
  153.         case 9:  
  154.             ch = '9';  
  155.             break;  
  156.         case 10:  
  157.             ch = 'a';  
  158.             break;  
  159.         case 11:  
  160.             ch = 'b';  
  161.             break;  
  162.         case 12:  
  163.             ch = 'c';  
  164.             break;  
  165.         case 13:  
  166.             ch = 'd';  
  167.             break;  
  168.         case 14:  
  169.             ch = 'e';  
  170.             break;  
  171.         case 15:  
  172.             ch = 'f';  
  173.             break;  
  174.         default:  
  175.             ch = ' ';  
  176.         }  
  177.         return ch;  
  178.     }  
  179.   
  180. }  

 

 

工具類:

 

[java] view plaincopy

  1. import java.awt.AlphaComposite;  
  2. import java.awt.Color;  
  3. import java.awt.Font;  
  4. import java.awt.Graphics2D;  
  5. import java.awt.Image;  
  6. import java.awt.RenderingHints;  
  7. import java.awt.geom.AffineTransform;  
  8. import java.awt.image.BufferedImage;  
  9. import java.awt.image.ColorModel;  
  10. import java.awt.image.WritableRaster;  
  11. import java.io.File;  
  12. import java.io.FileInputStream;  
  13. import java.io.FileNotFoundException;  
  14. import java.io.FileOutputStream;  
  15. import java.io.IOException;  
  16. import java.io.InputStream;  
  17.   
  18. import javax.imageio.ImageIO;  
  19.   
  20. import com.sun.image.codec.jpeg.ImageFormatException;  
  21. import com.sun.image.codec.jpeg.JPEGCodec;  
  22. import com.sun.image.codec.jpeg.JPEGImageDecoder;  
  23. import com.sun.image.codec.jpeg.JPEGImageEncoder;  
  24.   
  25. /** 
  26.  * 圖片工具類,主要針對圖片水印處理 
  27.  *  
  28.  * @author  025079 
  29.  * @version  [版本號, 2011-11-28] 
  30.  * @see  [相關類/方法] 
  31.  * @since  [產品/模塊版本] 
  32.  */  
  33. public class ImageHelper {  
  34.   
  35.     // 項目根目錄路徑  
  36.     public static final String path = System.getProperty("user.dir");  
  37.       
  38.     /** 
  39.      * 生成縮略圖 <br/> 
  40.      * 保存:ImageIO.write(BufferedImage, imgType[jpg/png/...], File); 
  41.      *  
  42.      * @param source 
  43.      *            原圖片 
  44.      * @param width 
  45.      *            縮略圖寬 
  46.      * @param height 
  47.      *            縮略圖高 
  48.      * @param b 
  49.      *            是否等比縮放 
  50.      * */  
  51.     public static BufferedImage thumb(BufferedImage source, int width,  
  52.             int height, boolean b) {  
  53.         // targetW,targetH分別表示目標長和寬  
  54.         int type = source.getType();  
  55.         BufferedImage target = null;  
  56.         double sx = (double) width / source.getWidth();  
  57.         double sy = (double) height / source.getHeight();  
  58.   
  59.         if (b) {  
  60.             if (sx > sy) {  
  61.                 sx = sy;  
  62.                 width = (int) (sx * source.getWidth());  
  63.             } else {  
  64.                 sy = sx;  
  65.                 height = (int) (sy * source.getHeight());  
  66.             }  
  67.         }  
  68.   
  69.         if (type == BufferedImage.TYPE_CUSTOM) { // handmade  
  70.             ColorModel cm = source.getColorModel();  
  71.             WritableRaster raster = cm.createCompatibleWritableRaster(width,  
  72.                     height);  
  73.             boolean alphaPremultiplied = cm.isAlphaPremultiplied();  
  74.             target = new BufferedImage(cm, raster, alphaPremultiplied, null);  
  75.         } else  
  76.             target = new BufferedImage(width, height, type);  
  77.         Graphics2D g = target.createGraphics();  
  78.         // smoother than exlax:  
  79.         g.setRenderingHint(RenderingHints.KEY_RENDERING,  
  80.                 RenderingHints.VALUE_RENDER_QUALITY);  
  81.         g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));  
  82.         g.dispose();  
  83.         return target;  
  84.     }  
  85.   
  86.     /** 
  87.      * 圖片水印 
  88.      *  
  89.      * @param imgPath 
  90.      *            待處理圖片 
  91.      * @param markPath 
  92.      *            水印圖片 
  93.      * @param x 
  94.      *            水印位於圖片左上角的 x 座標值 
  95.      * @param y 
  96.      *            水印位於圖片左上角的 y 座標值 
  97.      * @param alpha 
  98.      *            水印透明度 0.1f ~ 1.0f 
  99.      * */  
  100.     public static void waterMark(String imgPath, String markPath, int x, int y,  
  101.             float alpha) {  
  102.         try {  
  103.             // 加載待處理圖片文件  
  104.             Image img = ImageIO.read(new File(imgPath));  
  105.   
  106.             BufferedImage image = new BufferedImage(img.getWidth(null),  
  107.                     img.getHeight(null), BufferedImage.TYPE_INT_RGB);  
  108.             Graphics2D g = image.createGraphics();  
  109.             g.drawImage(img, 0, 0, null);  
  110.   
  111.             // 加載水印圖片文件  
  112.             Image src_biao = ImageIO.read(new File(markPath));  
  113.             g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,  
  114.                     alpha));  
  115.             g.drawImage(src_biao, x, y, null);  
  116.             g.dispose();  
  117.   
  118.             // 保存處理後的文件  
  119.             FileOutputStream out = new FileOutputStream(imgPath);  
  120.             JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
  121.             encoder.encode(image);  
  122.             out.close();  
  123.         } catch (Exception e) {  
  124.             e.printStackTrace();  
  125.         }  
  126.     }  
  127.   
  128.     /** 
  129.      * 文字水印 
  130.      *  
  131.      * @param imgPath 
  132.      *            待處理圖片 
  133.      * @param text 
  134.      *            水印文字 
  135.      * @param font 
  136.      *            水印字體信息 
  137.      * @param color 
  138.      *            水印字體顏色 
  139.      * @param x 
  140.      *            水印位於圖片左上角的 x 座標值 
  141.      * @param y 
  142.      *            水印位於圖片左上角的 y 座標值 
  143.      * @param alpha 
  144.      *            水印透明度 0.1f ~ 1.0f 
  145.      */  
  146.   
  147.     public static void textMark(String imgPath, String text, Font font,  
  148.             Color color, int x, int y, float alpha) {  
  149.         try {  
  150.             Font Dfont = (font == null) ? new Font("宋體", 20, 13) : font;  
  151.   
  152.             Image img = ImageIO.read(new File(imgPath));  
  153.   
  154.             BufferedImage image = new BufferedImage(img.getWidth(null),  
  155.                     img.getHeight(null), BufferedImage.TYPE_INT_RGB);  
  156.             Graphics2D g = image.createGraphics();  
  157.   
  158.             g.drawImage(img, 0, 0, null);  
  159.             g.setColor(color);  
  160.             g.setFont(Dfont);  
  161.             g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,  
  162.                     alpha));  
  163.             g.drawString(text, x, y);  
  164.             g.dispose();  
  165.             FileOutputStream out = new FileOutputStream(imgPath);  
  166.             JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
  167.             encoder.encode(image);  
  168.             out.close();  
  169.         } catch (Exception e) {  
  170.             System.out.println(e);  
  171.         }  
  172.     }  
  173.       
  174.     /** 
  175.      * 讀取JPEG圖片 
  176.      * @param filename 文件名 
  177.      * @return BufferedImage 圖片對象 
  178.      */  
  179.     public static BufferedImage readJPEGImage(String filename)  
  180.     {  
  181.         try {  
  182.             InputStream imageIn = new FileInputStream(new File(filename));  
  183.             // 得到輸入的編碼器,將文件流進行jpg格式編碼  
  184.             JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(imageIn);  
  185.             // 得到編碼後的圖片對象  
  186.             BufferedImage sourceImage = decoder.decodeAsBufferedImage();  
  187.               
  188.             return sourceImage;  
  189.         } catch (FileNotFoundException e) {  
  190.             e.printStackTrace();  
  191.         } catch (ImageFormatException e) {  
  192.             e.printStackTrace();  
  193.         } catch (IOException e) {  
  194.             e.printStackTrace();  
  195.         }  
  196.           
  197.         return null;  
  198.     }  
  199.       
  200.     /** 
  201.      * 讀取JPEG圖片 
  202.      * @param filename 文件名 
  203.      * @return BufferedImage 圖片對象 
  204.      */  
  205.     public static BufferedImage readPNGImage(String filename)  
  206.     {  
  207.         try {  
  208.             File inputFile = new File(filename);    
  209.             BufferedImage sourceImage = ImageIO.read(inputFile);  
  210.             return sourceImage;  
  211.         } catch (FileNotFoundException e) {  
  212.             e.printStackTrace();  
  213.         } catch (ImageFormatException e) {  
  214.             e.printStackTrace();  
  215.         } catch (IOException e) {  
  216.             e.printStackTrace();  
  217.         }  
  218.           
  219.         return null;  
  220.     }  
  221.       
  222.     /** 
  223.      * 灰度值計算 
  224.      * @param pixels 像素 
  225.      * @return int 灰度值 
  226.      */  
  227.     public static int rgbToGray(int pixels) {  
  228.         // int _alpha = (pixels >> 24) & 0xFF;  
  229.         int _red = (pixels >> 16) & 0xFF;  
  230.         int _green = (pixels >> 8) & 0xFF;  
  231.         int _blue = (pixels) & 0xFF;  
  232.         return (int) (0.3 * _red + 0.59 * _green + 0.11 * _blue);  
  233.     }  
  234.       
  235.     /** 
  236.      * 計算數組的平均值 
  237.      * @param pixels 數組 
  238.      * @return int 平均值 
  239.      */  
  240.     public static int average(int[] pixels) {  
  241.         float m = 0;  
  242.         for (int i = 0; i < pixels.length; ++i) {  
  243.             m += pixels[i];  
  244.         }  
  245.         m = m / pixels.length;  
  246.         return (int) m;  
  247.     }  
  248. }  

 

原文地址:http://blog.csdn.net/yjflinchong/article/details/7469213#

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章