美文网首页
opencv for android 感知哈希算法

opencv for android 感知哈希算法

作者: 读书人heart | 来源:发表于2019-12-10 21:12 被阅读0次

    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));
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:opencv for android 感知哈希算法

          本文链接:https://www.haomeiwen.com/subject/cjpggctx.html