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