最近做了個小東西就是匹配貓和狗
代碼如下,用了一個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