现在的位置: 首页 > 综合 > 正文

感知hash算法(汉明距离)对比图片相似度算法在android中的实现

2014年02月13日 ⁄ 综合 ⁄ 共 1764字 ⁄ 字号 评论关闭
文章目录

原文地址:

http://www.cnblogs.com/technology/archive/2012/07/12/Perceptual-Hash-Algorithm.html

原文中算法是c++实现。贴一个改了的andoird/bitmap的实现

public class BitmapUtils {
    
    private static int sum = 0;

    public static String getHash(Bitmap bitmap){
        Bitmap temp = Bitmap.createScaledBitmap(bitmap, 8, 8, false);
        int[] grayValues = reduceColor(temp);
        int average = sum/grayValues.length;
        String reslut = computeBits(grayValues, average);
        return reslut;
    }

    private static String computeBits(int[] grayValues, int average) {
        char[] result = new char[grayValues.length];
        for (int i = 0; i < grayValues.length; i++)
        {
            if (grayValues[i] < average)
                result[i] = '0';
            else
                result[i] = '1';
        }
        return new String(result);
    }

    private static int[] reduceColor(Bitmap bitmap) {
        sum = 0;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Log.i("th", "scaled bitmap's width*heith:" + width + "*" + height);

        int[] grayValues = new int[width * height];
        int[] pix = new int[width * height];
        bitmap.getPixels(pix, 0, width, 0, 0, width, height);
        for (int i = 0; i < width; i++)
            for (int j = 0; j < height; j++) {
                int x = j * width + i;
                int r = (pix[x] >> 16) & 0xff;
                int g = (pix[x] >> 8) & 0xff;
                int b = pix[x] & 0xff;
                int grayValue = (r * 30 + g * 59 + b * 11) / 100;
                sum+=grayValue;
                grayValues[x] = grayValue;
            }
        return grayValues;
    }
    
    public static void saveToFile(Bitmap ...bitmaps ){
        int i=0;
        for (Bitmap bitmap : bitmaps) {
            String path = Environment.getExternalStorageDirectory().getPath();
            File file = new File(path+"/"+(i++)+".jpg");
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            bitmap.compress(CompressFormat.JPEG, 100, fos );
            try {
                fos.flush();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

但是在原算法步骤的第二步是:

第二步 转为灰度图片

         将缩小后的图片, 转为64级灰度图片.

我看了下c++的那个是实现没有做转64级灰度,只是单纯的转为了灰度图。这个估计对算法的准确度有一定影响。

现在写的andoird实现跟c++的算法一样也没有转,谁无聊了可以补充下。

结合现在做的这个项目,觉得这个算法没什么用。。。。。

有个更好的phash算法,可以去看看号称能接受20%的变形,贴上地址:

http://blog.csdn.net/luoweifu/article/details/8220992

抱歉!评论已关闭.