**android 实现感知哈希算法**

`android 实现感知哈希算法

感知哈希算法

简单说下算法的实现吧
1.首先把图片大小改成8*8的 只保留基本框架;
2.灰度化;
3.求灰度平均值;
4.把灰度值小于平均值的置0,大于置1;
5.最后对比两个数组不同点的个数;
文字说的比较不明白,看代码吧。

c++代码

#include <QDebug>
#include <iostream>
#include <vector>
#include <QApplication>
#include <QDebug>
#include <queue>
#include "opencv2/opencv.hpp"
#include <QTime>

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{

    Mat test1,test2;
    test1 = imread("C:/Users/Administrator/Desktop/test1.jpg");
    test2 = imread("C:/Users/Administrator/Desktop/test2.jpg");
    Mat dst;
    //cvSub(test1,test2,dst);


    QTime time;
    time.start();

    Mat test1Dst,test2Dst;
    resize(test1, test1Dst, Size(8, 8), 0, 0, INTER_CUBIC);
    resize(test2, test2Dst, Size(8, 8), 0, 0, INTER_CUBIC);

    cvtColor(test1Dst,test1Dst,COLOR_BGR2GRAY);
    cvtColor(test2Dst,test2Dst,COLOR_BGR2GRAY);

    int avg1 = 0,avg2 = 0;
    int arr1[64],arr2[64];

    for(int i=0;i<8;i++){

        uchar* data1 = test1Dst.ptr<uchar>(i);
        uchar* data2 = test2Dst.ptr<uchar>(i);

        int count = i * 8;
        for(int j=0; j<8; j++){
            arr1[count + j] = data1[j];
            arr2[count + j] = data2[j];

            avg1 += arr1[count];
            avg2 += arr2[count];
        }
    }

    avg1 = avg1/64;
    avg2 = avg2/64;

    for(int i=0;i<64;i++){
        arr1[i] = (arr1[i]>=avg1)?1:0;
        arr2[i] = (arr2[i]>=avg2)?1:0;
    }
    int iDiffNum = 0;
    for (int i = 0; i < 64; i++)
        if (arr1[i] != arr2[i])
            ++iDiffNum;
    printf("sum = %d\n",iDiffNum);

    qDebug()<<time.elapsed()/1000.0<<"s";
    waitKey(0);
    return 0;
}

android 代码

这才是实现我毕设例程的代码 不解释了 不咋会说话
代码如下:

package yjkim.mjpegviewer;

import android.graphics.Bitmap;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

public class judge {
    public judge(){
        matPre = new Mat();
        dstPre = new Mat();
        matCur = new Mat();
        dstCur = new Mat();
        arrCur = new int[64];
        arrPre = new int[64];
        prePic = null;
        flag = true;
        avgPre = 0;
        avgCur = 0;
        diffNum = 0;
    }
    public boolean judgePicture(Bitmap curPic) {
        if(prePic == null){
            prePic = curPic;
            Utils.bitmapToMat(prePic,matPre);
            Imgproc.resize(matPre,dstPre,new Size(8,8),0,0,Imgproc.INTER_CUBIC);
            Imgproc.cvtColor(dstPre,dstPre,Imgproc.COLOR_BGR2GRAY);
            for(int i=0;i<8;i++){
                int count = i*8;
                for(int j=0;j<8;j++){
                    double [] data = dstPre.get(i,j);
                    arrPre[count + j] = (int)data[0];
                    avgPre += arrPre[count + j];
                }
            }
            avgPre = avgPre/64;
            for(int i=0;i<64;i++){
                arrPre[i] = (arrPre[i] > avgPre)?1:0;
            }
            return false;
        }
        Utils.bitmapToMat(curPic,matCur);
        Imgproc.resize(matCur,dstCur,new Size(8,8),0,0,Imgproc.INTER_CUBIC);
        Imgproc.cvtColor(dstCur,dstCur,Imgproc.COLOR_BGR2GRAY);
        for(int i=0;i<8;i++){
            int count = 8*i;
            for(int j=0;j<8;j++){
                double [] data = dstCur.get(i,j);
                if(flag){
                    arrCur[count + j] = (int)data[0];
                    avgCur += arrCur[count + j];
                }else{
                    arrPre[count + j] = (int)data[0];
                    avgPre += arrPre[count +j];
                }
            }
        }
        if(flag){
            avgCur = avgCur/64;
        }else{
            avgPre = avgPre/64;
        }

        for(int i=0; i<64; i++){
            if(flag){
                arrCur[i] = (arrCur[i]>avgCur)?1:0;
                if(i==63){
                    avgPre = 0;
                    flag = false;
                }
            }else{
                arrPre[i] = (arrPre[i]>avgPre)?1:0;
                if(i == 63){
                    avgCur = 0;
                    flag = true;
                }
            }
        }

        for(int i=0; i<64; i++){
            if(arrPre[i] != arrCur[i]){
                diffNum++;
            }
        }

        if(diffNum < 20){
            diffNum = 0;
            return true;
        }else{
            diffNum = 0;
            return false;
        }
    }
    private Bitmap prePic;
    private int diffNum;
    private int avgPre;
    private int avgCur;
    private int [] arrPre;
    private int [] arrCur;
    private boolean flag;
    private Mat matCur;
    private Mat dstCur;
    private Mat matPre;
    private Mat dstPre;
}

第一次写 就不写注释了
可以看看java里怎么对图片操作像素
其中Mat.get();返回的是double[] 类型的数组
几个通道就是有几个 比如灰度 返回的data[0] 就是像素
彩图就是 data[0],data[1],data[2];

好了 今天到此为止

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值