opencv for android 感知哈希算法

2019-12-10  本文已影响0人  读书人heart

opencv 版本 4.1.2

使用方法

 /**
     * 感知哈希算法(值越低越相似)小于10 表示 是同一张图
     * 2个mat必须是统一类型 灰色图或彩图
     */
    private void haxi1(Mat imgae,Mat capture){
        Bitmap imageBitmap = Bitmap.createBitmap(imgae.width(),imgae.height(), Bitmap.Config.RGB_565);
        Bitmap captureBitmap = Bitmap.createBitmap(capture.width(),capture.height(), Bitmap.Config.RGB_565);
        //opencv自带
        Utils.matToBitmap(imgae,imageBitmap);
        Utils.matToBitmap(capture,captureBitmap);

        int v = TestUtils.test(TestUtils.getImageCode(imageBitmap),TestUtils.getImageCode(captureBitmap));
//        Log.e("test","明汉距离: " + v);
        appText(" 明汉距离: " + v);
        if (v <= 10){
            jump(imgae,capture);
        }else{
            setText("相似度太低");
        }
    }

工具类

package com.arcsoft.arcfacedemo.util;

import android.graphics.Bitmap;
import android.media.ThumbnailUtils;

public class TestUtils {


    /**
     * 简化色彩
     * @param img
     * @return
     */
    private static Bitmap convertGreyImg(Bitmap img) {
        int width = img.getWidth();         //获取位图的宽
        int height = img.getHeight();       //获取位图的高

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int alpha = 0xFF << 24;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int original = pixels[width * i + j];
                int red = ((original & 0x00FF0000) >> 16);
                int green = ((original & 0x0000FF00) >> 8);
                int blue = (original & 0x000000FF);

                int grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
                grey = alpha | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        result.setPixels(pixels, 0, width, 0, 0, width, height);
        return result;
    }

    /**
     * 计算平均值
     * @param img
     * @return
     */
    private static int getAvg(Bitmap img) {
        int width = img.getWidth();
        int height = img.getHeight();
        int[] pixels = new int[width * height];
        img.getPixels(pixels, 0, width, 0, 0, width, height);

        int avgPixel = 0;
        for (int pixel : pixels) {
            avgPixel += pixel;
        }
        return avgPixel / pixels.length;
    }

    /**
     * 比较像素的灰度
     * @param img
     * @param average
     * @return
     */
    private static String getBinary(Bitmap img, int average) {
        StringBuilder sb = new StringBuilder();

        int width = img.getWidth();
        int height = img.getHeight();
        int[] pixels = new int[width * height];

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int original = pixels[width * i + j];
                if (original >= average) {
                    pixels[width * i + j] = 1;
                } else {
                    pixels[width * i + j] = 0;
                }
                sb.append(pixels[width * i + j]);
            }
        }
        img.recycle();
        return sb.toString();
    }

    /**
     * 计算哈希值
     * @param bString
     * @return
     */
    private static String binaryString2hexString(String bString) {
        if (bString == null || bString.equals("") || bString.length() % 8 != 0)
            return null;
        StringBuilder sb = new StringBuilder();
        int iTmp;
        for (int i = 0; i < bString.length(); i += 4) {
            iTmp = 0;
            for (int j = 0; j < 4; j++) {
                iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
            }
            sb.append(Integer.toHexString(iTmp));
        }
        return sb.toString();
    }

    /**
     * 比较于10是同一张图片
     * @param s1
     * @param s2
     * @return
     */
    public static int test(String s1,String s2){
        char[] s1s = s1.toCharArray();
        char[] s2s = s2.toCharArray();
        int diffNum = 0;
        for (int i = 0; i<s1s.length; i++) {
            if (s1s[i] != s2s[i]) {
                diffNum++;
            }
        }
        return diffNum;

    }

    public static String getImageCode(Bitmap bitmapOriginal){
        Bitmap bitmap8 = ThumbnailUtils.extractThumbnail(bitmapOriginal, 8, 8);
        Bitmap bitmap7 = convertGreyImg(bitmap8);
        int avg = getAvg(bitmap7);
        bitmap8.recycle();
        return binaryString2hexString(getBinary(bitmap7,avg));

    }
}

上一篇下一篇

猜你喜欢

热点阅读