opencv基于颜色直方图的图像比较
图像预处理
把图像分割,把要检测的图像分割为9个小图像。比如下图为待检索的图像,将其划分为9个小部分,分别对每部分比较最后计算平均值。
计算直方图并归一化
将图像划分为9个小部分后将图像转换为HSV空间
HSV空间的图像检索使用H(色调)和S(饱和度)分量计算直方图并比较。opencv中计算直方图调用函数calcHist,将直方图归一化要调用函数normalize。
比较相似度
在得到归一化的直方图后,要度量图像的相似度。常用的相似度度量方式有5种,分别是相关性比较(Correlation)、卡方比较(Chi-Square)、十字交叉比(Intersection)、巴氏距离(Bhattacharyya)和EMD距离。
程序选择了相关性比较和EMD距离来比较图像的相关性。
程序运行环境vs2015+opencv2.4.1
#include <opencv2/core/core.hpp>
#include "opencv2/opencv.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <vector>
#include <string>
#include <stdlib.h>
#include <io.h>
#include < fstream>
#include <algorithm>
//运行环境vs2015+opencv2.4.1
using namespace std;
using namespace cv;
//读入文件夹下指定格式的所有文件,本程序是读取文件夹下所有jpg图片
void getFiles(string path, string file_format, vector<string>& files)
{
intptr_t hFile = 0;//intptr_t和uintptr_t是什么类型:typedef long int/ typedef unsigned long int
struct _finddata_t fileinfo;
string p, file_formatName;
if (0 != strcmp(file_format.c_str(), ""))
{
file_formatName = "\\*." + file_format;
}
else
{
file_formatName = "\\*";
}
if ((hFile = _findfirst(p.assign(path).append(file_formatName).c_str(), &fileinfo)) != -1)//assign方法可以理解为先将原字符串清空,然后赋予新的值作替换。
{
do
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
//用于数组降序排列
bool hightolow(float a, float b)
{
return a>b;
}
//图像分割
void rectImage(Mat* rectImg, Mat oImg) {
int m = oImg.cols;//宽
int n = oImg.rows;//高
rectImg[1] = oImg(Rect(0, 0, m / 3, n / 3));
rectImg[2] = oImg(Rect(m / 3, 0, m / 3, n / 3));
rectImg[3] = oImg