Android opencv 差值哈希算法,均值哈希算法,图片差异相似度识别

android上使用OpenCV,首先是要导入相应的sdk模块,这个网上都有很多了,不再多说了,要注意的一点是,Android opencv 的sdk要是3.4.7的,sdk模块的名称是openCVLibrary347。

在android上使用opencv的时候,打包成的apk会比较大,大概有80M。

接下来上代码

package com.example.agrdf.picturecompare;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

/**
 * Created by agrdf on 2022/12/9.
 */

public class example {

//    判断差异值,小于差异值,判断为相同图片,返回true,否则返回false
    public boolean path_to_judge2(String path1,String path2,double auui,double auui2){
        Mat img1=cv_read(path1);
        Mat img2=cv_read(path2);
//        判断差异值的
        return method_2(img1,img2,auui,auui2);
    }

//    从图片绝对路径得到Mat
    public Mat cv_read(String res){
        Mat img = Imgcodecs.imread(res, Imgcodecs.IMREAD_UNCHANGED);
        return img;
    }

    //  对图片的Mat进行缩放
    private void resize_to_eight_eight(Mat srcMat){
//        缩放成8*8大小,比较ahash均值哈希值
        Imgproc.resize(srcMat, srcMat,new Size(8,8) , 0, 0,  Imgproc.INTER_CUBIC);
    }
    //   缩放成8*9大小,比较dhash差值哈希算法的值
    private void resize_to_nine_eight(Mat srcMat){
        Imgproc.resize(srcMat, srcMat,new Size(9,8) , 0, 0,  Imgproc.INTER_CUBIC);
    }

//    就Mat转换为灰度图
    private Mat mat_to_gray(Mat resaa){
        Size dsize = new Size(resaa.width() , resaa.height() );
        Mat img2 = new Mat(dsize, CvType.CV_16U);
        Imgproc.cvtColor(resaa,img2,Imgproc.COLOR_BGR2GRAY);
        return img2;
    }

//    算出一个mat的均值哈希值ahash
    private double[] get_one_averg_gray(Mat dst1){
        double[][] data1 = new double[64][1];

        //iAvg 平均像素灰度值,arr像素灰度值,
        int iAvg1 = 0;
        double[] arr1 = new double[64];

        //get灰度给data,用data给arr充值,算平均灰度值iAvg。
        for (int i = 0; i < 8; i++)
        {
            int tmp = i * 8;
            for (int j = 0; j < 8; j++)
            {
                int tmp1 = tmp + j;
//                data得到1个点位的像素
                data1[tmp1] = dst1.get(i,j);
//                然后赋值到arr上储存起来
                arr1[tmp1] = data1[tmp1][0];
//                每个像素点相加,得到总灰度
                iAvg1 += arr1[tmp1];

            }
        }

//        总灰度变成平均灰度
        iAvg1 /= 64;
        //比对每个像素灰度值和平均灰度值大小,大于平均灰度的,就+1
        for (int i = 0; i < 64; i++)
        {
            arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;
        }
        return arr1;
    }


//    比较两个ahash,得到差异数量,1为差异最大
    private double dif_ahsah(double[] arr1,double[] arr2 ){
        int iDiffNum = 0;
        for (int i = 0; i < 64; i++){
            if (arr1[i] != arr2[i]){
                ++iDiffNum;
            }

        }
        return ((double)iDiffNum)/64.0;
    }


//    得到一个差值哈希值
    private String dhash(Mat src){

        double average = 0;
        String hash = "";
        int[] arr = new int[64];
        for (int i = 0; i < 8; i++) {
            int count = i*8;
            for (int j = 0; j < 8; j++) {
                double[] data = src.get(i, j);
                double[] data2 = src.get(i, j+1);

                if ((int) data[0] > (int) data2[0]){

                    hash += "0";
                }else {
                    hash += "1";
                }

            }
        }

        return hash;

    }

//    比较两个差值哈希,得到差异值
    private  double dif_dhsah(String str1,String str2){
        int num = 0;
        for (int i = 0; i < 64; i++) {
            if (str1.charAt(i) != str2.charAt(i)){
                num++;
            }
        }
        return ((double)num)/64.0;
    }

//    double ook1, double ook2分别是均值哈希和差值哈希算法的对比值
//    是差异的数量,越大,代表差异越大,是不同的图片,最大差异值为1,为完全不相同的图片
//    区别不同图片,一般设置为0.5.差异数量超过0.5,就可以认为是不同的图片。因为可能会有一些其他色素的误差。
    private boolean method_2(Mat source1, Mat source2, double ook1, double ook2){

        //    这是比较ahash的
        resize_to_eight_eight(source1);
        Mat gra1=mat_to_gray(source1);
        double[] ahash1=get_one_averg_gray(gra1);

        resize_to_eight_eight(source2);
        Mat gra2=mat_to_gray(source2);
        double[] ahash2=get_one_averg_gray(gra2);

        double judge_ahash=dif_ahsah(ahash1,ahash2);

//    接下来是比较dhash的

        resize_to_nine_eight(source1);
        Mat dhash_gra1=mat_to_gray(source1);
        String dhash1=dhash(dhash_gra1);

        resize_to_nine_eight(source2);
        Mat dhash_gra2=mat_to_gray(source2);
        String dhash2=dhash(dhash_gra2);

        double judge_dhash=dif_dhsah(dhash1,dhash2);

        if((judge_ahash<ook1)&&(judge_dhash<ook2)){

            return true;
        }else {

            return false;

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值