zoukankan      html  css  js  c++  java
  • 图像检索:RGBHistogram+欧几里得距离|卡方距离

    RGBHistogram:

    分别计算把彩色图像的三个通道R、G、B的一维直方图,然后把这三个通道的颜色直方图结合起来,就是颜色的描写叙述子RGBHistogram。

    以下给出计算RGBHistogram的代码:

    <span style="font-family:Microsoft YaHei;font-size:18px;">#include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    using namespace cv;
    
    const int HISTSIZE = 8;
    int main( int, char** argv )
    {
      Mat src, dst;
    
      /// Load image
      src = imread( argv[1], 1 );
    
      if( !src.data || (src.channels() !=3))
        { return -1; }
    
      Mat rgbFeature = bgrHistogram(src);
     
      return 0;
    }
    
    Mat bgrHistogram(const Mat& src)
    {
    	//分离B、G、R通道
    	vector<Mat> bgr_planes;
    	split(src,bgr_planes);
    
    
      float range[] = { 0, 256 } ;
      const float* histRange = { range };
    
      bool uniform = true; bool accumulate = false;
    
      Mat hist1d,normHist1d,hist;
    
      for(int i = 0 ;i < 3;i++)
      {
    	  calcHist( &bgr_planes[i], 1, 0, Mat(), hist1d, 1, &HISTSIZE, &histRange, uniform, accumulate );
    	  normalize(hist1d,hist1d,1.0,0.0,CV_L1);
    	  hist.push_back(hist1d);
      }
      return hist;
    }
    </span>

    第二步:颜色描写叙述子已经计算出,选取什么样的距离。

    对于距离我们先选取两种:

    第一种:欧几里得距离

    #include<iostream>
    #include <fstream>
    #include <stdio.h>
    using namespace std;
    
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    using namespace cv;
    
    const int HISTSIZE = 16;
    Mat bgrHistogram(const Mat& src);
    double  euclideanDistance(const Mat & src1,const Mat &src2);
    int main( int, char** argv )
    {
      //定义文件流,仅仅能读取
    	ifstream inPutFile(argv[1],ios::in);
    	if(! inPutFile)
    	{
    		cerr << "File Open Erro !"<<endl;
    		return -1;
    	}
    
    	//读取文件流中的每一行。并赋值给fileName,形成查询数据库
    	string fileName ;
    	Mat image,histogram,sourceHisrogram;
    	vector<Mat> histograms;
    
    	map<int,string>index;//图像的索引
    	index.clear();
    	int  number = 0;
    	histograms.clear();
    	while(getline(inPutFile,fileName))
    	{
    		index.insert(pair<int,string>(number,fileName));
    		number++;
    		image = imread(fileName,1);
    		histogram = bgrHistogram(image);
    		histograms.push_back(histogram);
    	}
    	//待搜索的图像
    	number = 0;
    	Mat imageSource = imread(argv[2],1);
    	sourceHisrogram = bgrHistogram(imageSource);
    	vector<Mat>::iterator iter;
    	map<double,int>distance;
    	for(iter = histograms.begin();iter != histograms.end();iter++)
    	{
    		distance.insert(pair<double,int>(euclideanDistance(sourceHisrogram,*iter),number));
    		number++;
    	}
    	//显示距离最小的前五名的检索图像
    	number = 0;
    	map<double,int>::iterator mapiter;
    	for(mapiter = distance.begin();mapiter != distance.end() && number <2;mapiter++,number++)
    	{
    		string simage = index.find((*mapiter).second) ->second;
    		image = imread(simage,1);
    		namedWindow(simage,1);
    		imshow(simage,image);
    	}
    	waitKey(0);
    }
    
    Mat bgrHistogram(const Mat& src)
    {
    	//分离B、G、R通道
    	vector<Mat> bgr_planes;
    	split(src,bgr_planes);
    
    
      float range[] = { 0, 256 } ;
      const float* histRange = { range };
    
      bool uniform = true; bool accumulate = false;
    
      Mat hist1d,normHist1d,hist;
    
      for(int i = 0 ;i < 3;i++)
      {
    	  calcHist( &bgr_planes[i], 1, 0, Mat(), hist1d, 1, &HISTSIZE, &histRange, uniform, accumulate );
    	  normalize(hist1d,hist1d,1.0,0.0,CV_L1);
    	  hist.push_back(hist1d);
      }
      return hist;
    }
    
    double  euclideanDistance(const Mat & src1,const Mat &src2)
    {
    	Mat pow2;
    	pow(src1-src2,2.0,pow2);
    	return 	sqrt(sum(pow2)[0]);
    }


    搜索数据库

    执行结果:


    另外一种:卡方距离

    #include<iostream>
    #include <fstream>
    #include <stdio.h>
    using namespace std;
    
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    using namespace cv;
    
    const int HISTSIZE = 16;
    Mat bgrHistogram(const Mat& src);
    int main( int, char** argv )
    {
      //定义文件流,仅仅能读取
    	ifstream inPutFile(argv[1],ios::in);
    	if(! inPutFile)
    	{
    		cerr << "File Open Erro !"<<endl;
    		return -1;
    	}
    
    	//读取文件流中的每一行。并赋值给fileName,形成查询数据库
    	string fileName ;
    	Mat image,histogram,sourceHisrogram;
    	vector<Mat> histograms;
    
    	map<int,string>index;//图像的索引
    	index.clear();
    	int  number = 0;
    	histograms.clear();
    	while(getline(inPutFile,fileName))
    	{
    		index.insert(pair<int,string>(number,fileName));
    		number++;
    		image = imread(fileName,1);
    		histogram = bgrHistogram(image);
    		histograms.push_back(histogram);
    	}
    	//待搜索的图像
    	number = 0;
    	Mat imageSource = imread(argv[2],1);
    	sourceHisrogram = bgrHistogram(imageSource);
    	vector<Mat>::iterator iter;
    	map<double,int>distance;
    	for(iter = histograms.begin();iter != histograms.end();iter++)
    	{
    		distance.insert(pair<double,int>(compareHist(sourceHisrogram,*iter,CV_COMP_CHISQR),number));
    		number++;
    	}
    	//显示距离最小的前五名的检索图像
    	number = 0;
    	map<double,int>::iterator mapiter;
    	for(mapiter = distance.begin();mapiter != distance.end() && number <2;mapiter++,number++)
    	{
    		string simage = index.find((*mapiter).second) ->second;
    		image = imread(simage,1);
    		namedWindow(simage,1);
    		imshow(simage,image);
    	}
    	waitKey(0);
    }
    
    Mat bgrHistogram(const Mat& src)
    {
    	//分离B、G、R通道
    	vector<Mat> bgr_planes;
    	split(src,bgr_planes);
    
    
      float range[] = { 0, 256 } ;
      const float* histRange = { range };
    
      bool uniform = true; bool accumulate = false;
    
      Mat hist1d,normHist1d,hist;
    
      for(int i = 0 ;i < 3;i++)
      {
    	  calcHist( &bgr_planes[i], 1, 0, Mat(), hist1d, 1, &HISTSIZE, &histRange, uniform, accumulate );
    	  normalize(hist1d,hist1d,1.0,0.0,CV_L1);
    	  hist.push_back(hist1d);
      }
      return hist;
    }
    
    搜索图片数据库

    执行结果:(我仅仅提取前两副距离近期的图片)






  • 相关阅读:
    《软件需求十步走》读书笔记二
    《软件需求十步走》读书笔记一
    FJUTOJ-周赛2016-12-16
    FJUTOJ-周赛2016-11-25
    网络爬虫
    树链剖分讲解
    HDU 5266 pog loves szh III
    HDU 3518 Boring counting
    HDU 5929 Basic Data Structure
    HDU 1055 Color a Tree
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8414285.html
Copyright © 2011-2022 走看看