图像检索:二维直方图+EMD距离

#include<iostream>
#include<fstream>
#include<map>
#include<string>
using namespace std;

#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace cv;

Mat signature(const Mat & src);
int main(int argc,char* argv[])
{
	//定义文件流,只能读取
	ifstream inPutFile(argv[1],ios::in);
	if(! inPutFile)
	{
		cerr <<"File Open Erro !"<<endl;
		return -1;
	}

	//读取文件流中的每一行,并赋值给fileName,形成查询数据库
	string fileName;
	Mat image,imageSignature,sourceSignature;
	vector<Mat> signatures;

	map<int,string> index;//图像的索引
	index.clear();
	int number = 0;
	signatures.clear();
	while(getline(inPutFile,fileName))
	{
		index.insert(pair<int,string>(number,fileName));
		number++;
		image = imread(fileName,1);
        imageSignature =  signature(image);
		signatures.push_back(imageSignature);
	}

	//待搜索的图像
	number = 0;
	Mat imageSource = imread(argv[2],1);
	sourceSignature = signature(imageSource);
	vector<Mat>::iterator iter;
	map<float,int> distance;
	for(iter = signatures.begin();iter != signatures.end();iter ++)
	{
		distance.insert(pair<float,int>(EMD(sourceSignature,*iter,CV_DIST_L2,number),number));
		number ++;
	}
	//显示距离最小的前五名的检索图像
	number = 0;
	map<float,int>::iterator mapiter;
	for(mapiter = distance.begin();mapiter != distance.end() && number <1;mapiter++,number++)
	{
		string simage = index.find((*mapiter).second)->second;
		image = imread(simage,1);
		namedWindow(simage,1);
		imshow(simage,image);
	}
	waitKey(0);
	return 0;
}

Mat signature(const Mat & src)
{
	Mat hsv,hist,normalHist,histCol;
	//颜色空间转换
	cvtColor(src,hsv,CV_BGR2HSV);
	//二维直方图
	int hbins = 30;
	int sbins  = 16;
	int histSize[] = {hbins,sbins};
	float hranges[] = {0.0,180.0};
	float sranges[] = {0.0,256.0};
	const float* ranges[] = {hranges,sranges};

	int channels[] ={0,1};
	calcHist(&hsv,1,channels,Mat(),hist,2,histSize,ranges,true,false);
	//把直方图特征按一列来存储
	int rows = hbins*sbins;
	histCol = hist.reshape(1,rows);
	//把直方图归一化
	normalize(histCol,normalHist,1000,0,CV_L1,CV_32F);

	Mat signature(hbins*sbins,3,CV_32FC1);
	normalHist.copyTo(signature.col(0));

	//我们把bin的索引放在signature的第二列和第三列
	for(int h =0 ;h<hbins;h++)
	{
		Mat roi(signature,Rect(1,h*sbins,2,sbins));
		for(int s= 0;s<sbins;s++)
		{
			roi.at<float>(s,0) = float(h);
			roi.at<float>(s,1) =float(s);
		}
	}
		return signature;
}

图像检索:二维直方图+EMD距离

时间: 2024-11-10 15:20:31

图像检索:二维直方图+EMD距离的相关文章

图像检索:一维直方图+EMD距离

EMD距离详细介绍已经在在这里已经给出. 思路:我们把一张图像的归一化的一维直方图作为signature的权重值,把色相的值作为signature.也就是一般在比较两幅图像的EMD距离时,signature是一样,只是权重值不一样. 通过以下程序,就可以得到一幅图像的signature: #include<iostream> using namespace std; #include<opencv2\core\core.hpp> #include<opencv2\highgu

图像检索:二维直方图+flann+KNN+欧几里得距离

第一步:批处理提取图像库的二维直方图,并存在到.xml中的featureHists中 [ 第一个参数:图像的路径 目录.txt 第二个参数:图像特征   features.xml [保存到features.xml中featureHists] ] #include<iostream> #include<fstream> #include<string> using namespace std; #include<opencv2\imgproc\imgproc.hpp

matlab画二维直方图以及双y轴坐标如何修改另一边y轴的颜色

1.首先讲一下如何用hist画二维直方图 1 x=[-568179 -766698 -935586 -826865 -393971 -771826 -1529945 -1910695 -1694740 -926367 -306998 -844840 -1828334 -2062815 -2297296 -1498824 -411346 -827922 -1826636 -1844777 -1862918 -1881060 -746534 -100479 -845832 -1832756 -194

二维直方图及其比较

创建图像的HSV空间的H和S二维直方图并比较直方图相似度: 代码: #include "cv.h" #include "cxcore.h" #include "highgui.h" #include <iostream> CvHistogram* Histogram2D(IplImage* src,int HSize,int SSize) { IplImage* SrcH=cvCreateImage(cvGetSize(src),8,

【练习7.4】使用直方图陆地移动距离EMD区分不同光线条件下的图片cvCalcEMD2

提纲 题目要求 程序代码 结果图片 要言妙道 题目要求: 设计一个直方图,可以判断给定的图像是在哪种光线条件下被捕捉到的. 程序代码: 1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点. 2 // 3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg 4 5 #include "stdafx.h" 6 #include <cv.h> 7 #include <highg

【练习7.3】从直方图创建signature、计算两个直方图的EMD距离

提纲 题目要求 程序代码 结果图片 要言妙道 题目要求: 收集三种光照条件下的手的直方图,计算它们之间的EMD距离 程序代码: 1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点. 2 // 3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg 4 5 #include "stdafx.h" 6 #include <cv.h> 7 #include <highgui.h

图像检索之EMD距离(Earth Mover&#39;s Distance)

在理解EMD距离模型时,需要先对<运筹学>中运输问题,做一下了解.下面给出几个运输问题的小例子,作为补充知识: 那么,对于上述问题我们发现是一个 产量=销量=500 ,即产销平衡的问题,可以提出这样的数学模型: 假设运到物品的个数为,用代表运到单个物品的运费(在上述表格中都有),用表示产地的产量,表示销地的销量,则总运费为,使总运费最小的数学模型为: 还有令两种可能就是 产量>销量 或者 产量<销量,这里不做模型的讨论,上面三种运输问题都可以用单纯形法进行求解.因为只有当"

UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点最近的点

题目链接:点击打开链接 题意: 给定二维坐标上的4个点 问: 找一个点使得这个点距离4个点的距离和最小 输出距离和. 思路: 若4个点不是凸4边形.则一定是端点最优. 否则就是2条对角线的交点最优,可以简单证明一下. 对于凸4边形则先极角排序一下. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef do

UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点近期的点

题目链接:点击打开链接 题意: 给定二维坐标上的4个点 问: 找一个点使得这个点距离4个点的距离和最小 输出距离和. 思路: 若4个点不是凸4边形.则一定是端点最优. 否则就是2条对角线的交点最优,能够简单证明一下. 对于凸4边形则先极角排序一下. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef do