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));
}
}
网友评论