圖像顏色直方圖和HOG特徵匹配opencv3

最近做了個小東西就是匹配貓和狗

 代碼如下,用了一個map排序:


#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
#include<fstream>
#include<string>
#include<map>
using namespace cv;

using namespace std;
vector<float> getHist2(Mat &image)//RGB色彩空間的(4,4,4)模型。
{
	const int div = 64;
	const int bin_num = 256 / div;
	int nr = image.rows; // number of rows
	int nc = image.cols; // number of columns
	if (image.isContinuous()) {
		// then no padded pixels  
		nc = nc*nr;
		nr = 1;  // it is now a 1D array  
	}
	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
	int b, g, r;
	vector<float> bin_hist;
	int ord = 0;
	float a[bin_num*bin_num*bin_num] = { 0 };
	for (int j = 0; j < nr; j++) {
		const uchar* idata = image.ptr<uchar>(j);
		for (int i = 0; i < nc; i++) {
			b = ((*idata++)&mask) / div;
			g = ((*idata++)&mask) / div;
			r = ((*idata++)&mask) / div;
			ord = b * bin_num * bin_num + g * bin_num + r;
			a[ord] += 1;
		} // end of row      
	}
	float sum = 0;
	//	cout << "a[i]2:" << endl;
	for (int i = 0; i < div; i++)
	{
		sum += a[i];
		//		cout << a[i] << " ";
	}
	for (int i = 0; i < div; i++)//歸一化
	{
		a[i] = a[i] / sum;
		bin_hist.push_back(a[i]);
	}
	return bin_hist;

}


double GetCompareHist(Mat testImg1, Mat testImg2)//基於RGB色彩空間的(4,4,4)模型直方圖匹配。
{
	double start, end, cost;
	start = clock();
	vector<float> b1;
	vector<float> b2;
	//b1 = getHist1(testImg1);//採用自帶函數(Img.at<Vec3b>(r, c))取像素,時間爲:78ms
	//b2 = getHist1(testImg2);
	b1 = getHist2(testImg1);//利用指針取像素,時間爲:10ms
	b2 = getHist2(testImg2);
	double base_test = compareHist(b1, b2, 0);
	//	double base_test = compareHist(b1, b2, CV_COMP_BHATTACHARYYA);//CV_COMP_BHATTACHARYYA
	end = clock();
	cost = end - start;
	//printf("代碼執行時間爲:%f\n", cost);
	return base_test;
}


typedef pair<string, int> PAIR;
struct cmp
{
	bool operator()(const pair<string, float> &p1, const pair<string, float> &p2)
	{
		return p1.second > p2.second;
	}
};

int main(int argc, char** argv)
{
	Mat query = imread("query (1).png", 1);
	if (query.empty()) {
		printf("could not load image...\n");
		return -1;
	}

	map<string, float>mp;

	ifstream fin("list.txt");//正樣本圖片的文件名列表
	if (!fin)
	{
		cout << "Pos/Neg imglist reading failed..." << endl;
		return -1;
	}
	string ImgName;//圖片名(絕對路徑)
	//遍歷圖計算對應的顏色直方圖匹配係數
	for (int num = 0; num < 180 && getline(fin, ImgName); num++)
	{
		string s = ImgName;

		ImgName = "database//" + ImgName;//加上正樣本的路徑名
		//std::cout << "Now processing original image: " << ImgName << endl;
		Mat src = imread(ImgName,1);//讀取圖片
		if (src.empty())
			cout << "no pic" << endl;
		//cout << GetCompareHist(query, src) << endl;;
		mp.insert(make_pair(s, GetCompareHist(query, src)));
	}

	//for (map<string, float>::iterator it = mp.begin(); it != mp.end(); it++)
	//{
	//	cout << it->first << "  " << it->second << endl;
	//}

	vector<pair<string, float>>vt(mp.begin(), mp.end());
	sort(vt.begin(), vt.end(), cmp());//根據顏色直方圖匹配係數排序  從大到小
	for (vector<pair<string, float>>::iterator it = vt.begin(); it != vt.begin()+20; it++)
	{
		cout << it->first << "  " << it->second << endl;
	}
	//輸出
	//database(102).png  0.975525
	//	database(25).png  0.973826
	//	database(94).png  0.955515
	//	database(140).png  0.947915
	//	database(122).png  0.941308
	//	database(173).png  0.94036
	//	database(170).png  0.930915
	//	database(81).png  0.923826
	//	database(175).png  0.916317
	//	database(86).png  0.914248
	waitKey(0);
	getchar();
	return 0;
}

hog:


#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
#include<fstream>
#include<string>
#include<map>
#include <opencv2/ml/ml.hpp>

using namespace std;
using namespace cv;
using namespace cv::ml;


typedef pair<string, float> PAIR;
struct cmp
{
	bool operator()(const pair<string, float> &p1, const pair<string, float> &p2)
	{
		return p1.second > p2.second;
	}
};

int main(int argc, char** argv)
{
	Mat query = imread("query (1).png", 1);
	if (query.empty()) {
		printf("could not load image...\n");
		return -1;
	}

	map<string, float>mp;

	ifstream fin("list.txt");//正樣本圖片的文件名列表
	if (!fin)
	{
		cout << "Pos/Neg imglist reading failed..." << endl;
		return -1;
	}
	string ImgName;//圖片名(絕對路徑)
	resize(query, query, Size(128, 128), 1);
	//if (CENTRAL_CROP)
	//	src = src(Rect(16, 16, 128, 128));//將96*160的INRIA正樣本圖片剪裁爲64*128,即剪去上下左右各16個像素
	HOGDescriptor hog(Size(128, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);
	vector<float> descriptors;//HOG描述子向量
	hog.compute(query, descriptors, Size(8, 8)); 
	//遍歷圖計算對應的顏色直方圖匹配係數
	for (int num = 0; num < 180 && getline(fin, ImgName); num++)
	{
		string s = ImgName;

		ImgName = "database//" + ImgName;//加上正樣本的路徑名
		//std::cout << "Now processing original image: " << ImgName << endl;
		Mat src = imread(ImgName,1);//讀取圖片
		if (src.empty())
			cout << "no pic" << endl;
		//cout << GetCompareHist(query, src) << endl;;
		resize(src, src, Size(128, 128), 1);
		vector<float> descriptors2;//HOG描述子向量
		hog.compute(src, descriptors2, Size(8, 8));
		float distance = 0;
		for (int i = 0; i < descriptors.size(); i++)
		{
			distance += pow(descriptors[i] - descriptors2[i], 2);
		}
		mp.insert(make_pair(s, distance));
	}

	//for (map<string, float>::iterator it = mp.begin(); it != mp.end(); it++)
	//{
	//	cout << it->first << "  " << it->second << endl;
	//}

	vector<pair<string, float>>vt(mp.begin(), mp.end());
	sort(vt.begin(), vt.end(), cmp());//根據顏色直方圖匹配係數排序  從大到小
	for (vector<pair<string, float>>::iterator it = vt.begin(); it != vt.begin()+20; it++)
	{
		cout << it->first << "  " << it->second << endl;
	}
	//輸出
	//database(102).png  0.975525
	//	database(25).png  0.973826
	//	database(94).png  0.955515
	//	database(140).png  0.947915
	//	database(122).png  0.941308
	//	database(173).png  0.94036
	//	database(170).png  0.930915
	//	database(81).png  0.923826
	//	database(175).png  0.916317
	//	database(86).png  0.914248
	waitKey(0);
	getchar();
	return 0;
}

參考:

https://blog.csdn.net/dyx810601/article/details/50520243

https://www.cnblogs.com/lakeone/p/5599047.html

https://bbs.csdn.net/topics/380097605

https://bbs.csdn.net/topics/380097605

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章