opencv通过图片哈希值计算汉明距离来匹配人脸
string xmlPath = "/data/data/org.opencv.samples.tutorial2/cache/lbpcascade_frontalface.xml";
//识别并截取人脸
Mat detectAndDisplay(Mat image) {
CascadeClassifier ccf;
ccf.load(xmlPath);
vector<Rect> faces;
Mat gray;
cvtColor(image, gray, CV_BGR2GRAY);
equalizeHist(gray, gray);
ccf.detectMultiScale(gray, faces, 1.1, 3, 0, Size(50, 50), Size(500, 500));
for (vector<Rect>::const_iterator iter = faces.begin(); iter != faces.end(); iter++) {
rectangle(image, *iter, Scalar(0, 0, 255), 2, 8); //画出脸部矩形
}
for (size_t i = 0; i < faces.size(); i++) {
image = image(Rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height));
}
return image;
}
//得到图片的哈希值
string HashValue(Mat &src) {
string rst(64, '\0');
Mat img;
cvtColor(src, img, CV_BGR2GRAY);
resize(img, img, Size(8, 8));
uchar *pData;
for (int i = 0; i < img.rows; i++) {
pData = img.ptr<uchar>(i);
for (int j = 0; j < img.cols; j++) {
pData[j] = pData[j] / 4;
}
}
int average = mean(img).val[0];
Mat mask = (img >= (uchar) average);
int index = 0;
for (int i = 0; i < mask.rows; i++) {
pData = mask.ptr<uchar>(i);
for (int j = 0; j < mask.cols; j++) {
if (pData[j] == 0)
rst[index++] = '0';
else
rst[index++] = '1';
}
}
return rst;
}
//求两张图片的汉明距离
int HanmingDistance(string &str1, string &str2) {
if ((str1.size() != 64) || (str2.size() != 64))
return -1;
int diff = 0;
for (int i = 0; i < 64; i++) {
if (str1[i] != str2[i])
diff++;
}
return diff;
}
void main(){
//从数据库选择,实际上如果2张判断更简单,只是一次比对而已。我数据库的是多次循环,取最优而已
Mat image1, image2;
image1 = oneMat;
string str1, str2, path2;
image1 = detectAndDisplay(image1);
str1 = HashValue(image1);
image2 = twoMat;
image2 = detectAndDisplay(image2);
image2.convertTo(dstMat, CV_8UC4);
str2 = HashValue(image2);
int dif = HanmingDistance(str1, str2);
LOGI("jason db %d %s %s", dif, str1.c_str(), str2.c_str());
}