`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];
好了 今天到此为止