openCV与C++的图像识别(一)——aHash

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/vivien1997/article/details/102722148
/*
开发环境Microsoft Visual Studio 10.0 C++  +   openCV 2.4.2   +   cmake

关于环境配置可以参考这篇博客  https://blog.csdn.net/qq_28584889/article/details/87914831
*/

#inclued "stdafx.h"
#include <iostream>
#include <bitset>
#include <string>
#include <iomanip>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
 
using namespace std;
using namespace cv;
 
#define hashLength 64
 
 
// 计算8*8图像的平均灰度
float calcAverage(Mat_<uchar> image, const int &size){
	float sum = 0;
	for(int i = 0 ; i < size; i++){
		for(int j = 0; j < size; j++){
			sum += image(i, j);
		}
	}
	return sum/(size*size);
}
 
/* 计算hash值
	image:8*8的灰度图像
	size: 图像大小  8*8
	ahahs:存放64位hash值
	averagePix: 灰度值的平均值
*/
void fingerPrint(Mat_<uchar> image, const int &size, bitset<hashLength> &ahash, const float &averagePix){
	for(int i = 0; i < size; i++){
		int pos = i * size;
		for(int j = 0; j < size; j++){
			ahash[pos+j] = image(i, j) >= averagePix ? 1:0;
		}
	}
}
 
/*计算汉明距离*/
int hammingDistance(const bitset<hashLength> &query, const bitset<hashLength> &target){
	int distance = 0;
	for(int i = 0; i < hashLength; i++){
		distance += (query[i] == target[i] ? 0 : 1);
	}
	return distance;
}
 
string bitTohex(const bitset<hashLength> &target){
	string str;
	for(int i = 0; i < hashLength; i=i+4){
		int sum = 0;
		string s;
		sum += target[i] + (target[i+1]<<1) + (target[i+2]<<2) + (target[i+3]<<3);
		stringstream ss;
		ss << hex <<sum;    // 以十六进制保存
		ss >> s;
		str += s;
	}
	return str;
}
 
int main(){
	Mat img = imread("F:\\www\\person.jpg", 1);
	if(!img.data){
		cout << "the image is not exist" << endl;
		return 0;
	}
	int size = 8;  // 图片缩放后大小
	
	resize(img, img, Size(size,size));      // 缩放到8*8
	cvtColor(img, img, COLOR_BGR2GRAY);       // 灰度化
	float averagePix = calcAverage(img, size);    // 计算灰度化的均值
	//cout << averagePix << endl;
	bitset<hashLength> ahash;               
	fingerPrint(img, size, ahash, averagePix);    // 得到均值hash
	//cout << ahash << endl;
	cout << bitTohex(ahash) << endl;
 
	string img_dir = "F:\\www\\";
	for(int i = 1; i <= 18; i++){
		string pos;
		stringstream ss;
		ss << i;
		ss >> pos;
		string img_name = img_dir + "person" + pos +".jpg"; 
		Mat target = imread(img_name, 1);
		if(!target.data){
			cout << "the target image" << img_name << " is not exist" << endl;
			continue;
		}
		resize(target, target, Size(size,size));
		cvtColor(target, target, COLOR_BGR2GRAY);
		float averagePix2 = calcAverage(target, size);
		bitset<hashLength> ahash2;
		fingerPrint(target, size, ahash2, averagePix2);
 
		//cout << averagePix2 << endl;
		int distance = hammingDistance(ahash, ahash2);      // 计算汉明距离
		cout <<"【" << i <<"-" <<  distance << "】 ";
	}
	cout << endl;
	system("pause");
	return 0;
	
}

总结:输出结果为汉明距离,是较为简易的图像相似度比较算法,故而精确度很低。

猜你喜欢

转载自blog.csdn.net/vivien1997/article/details/102722148
今日推荐