色调反向投影找特定的内容

来源:互联网 发布:js math 编辑:程序博客网 时间:2024/06/11 19:43

这里的注意的是色调H,其在这里的取值范围为0到180,因为Note this is only done for 8-bit formats. So if you want fullprecision, you can always switch to a 32f format prior to the colorspace conversion, which will yield the full 0-360 hue range.简单来说就是这图为uchar范围在0到255,如果取全范围0到360就会超过256,所以这里用0到180来表示。

至于image.type()返回的int,如果为cv_8uc3返回为16,具体见其源文件的定义。

以下为代码:

// opencv_calcbackproject.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <opencv245.h>using namespace std;using namespace cv;class ColorHistogram  {  private:  int histSize[3];  float hranges[2];  const float* ranges[3];  int channels[3];  public:  //构造函数  ColorHistogram()  {  histSize[0]= histSize[1]= histSize[2]= 256;  hranges[0] = 0.0;  hranges[1] = 255.0;  ranges[0] = hranges;  ranges[1] = hranges;  ranges[2] = hranges;  channels[0] = 0;  channels[1] = 1;  channels[2] = 2;  }  //计算彩色图像直方图  Mat getHistogram(const Mat& image)  {  Mat hist;  //BGR直方图  hranges[0]= 0.0;      hranges[1]= 255.0;  channels[0]= 0;   channels[1]= 1;   channels[2]= 2;   //计算  calcHist(&image,1,channels,Mat(),hist,3,histSize,ranges);  return hist;  }  //计算颜色的直方图  Mat getHueHistogram(const Mat &image)  {  Mat hist;  Mat hue;  //转换到HSV空间  cvtColor(image,hue,CV_BGR2HSV);  //设置1维直方图使用的参数  hranges[0] = 0.0;  hranges[1] = 180.0;  channels[0] = 0;  //计算直方图  calcHist(&hue,1,channels,Mat(),hist,1,histSize,ranges);  return hist;  }  //减少颜色  Mat colorReduce(const Mat &image,int div = 64)  {  int n = static_cast<int>(log(static_cast<double>(div))/log(2.0));  uchar mask = 0xFF<<n;  Mat_<Vec3b>::const_iterator it = image.begin<Vec3b>();  Mat_<Vec3b>::const_iterator itend = image.end<Vec3b>();  //设置输出图像  Mat result(image.rows,image.cols,image.type());  Mat_<Vec3b>::iterator itr = result.begin<Vec3b>();  for(;it != itend;++it,++itr)  {  (*itr)[0] = ((*it)[0]&mask) + div/2;  (*itr)[1] = ((*it)[1]&mask) + div/2;  (*itr)[2] = ((*it)[2]&mask) + div/2;  }  return result;  }  };  class ContentFinder  {  private:  float hranges[2];  const float* ranges[3];  int channels[3];  float threshold;  Mat histogram;  public:  ContentFinder():threshold(-1.0f)  {  //所有通道的范围相同  ranges[0] = hranges;  ranges[1] = hranges;   ranges[2] = hranges;  }   void setThreshold(float t)  {  threshold = t;  }    float getThreshold()  {  return threshold;  }  //设置参考的直方图  void setHistogram(const Mat& h)  {  histogram = h;  normalize(histogram,histogram,1.0);  }   Mat find(const Mat& image)  {  Mat result;  hranges[0] = 0.0;  hranges[1] = 255.0;  channels[0] = 0;  channels[1] = 1;  channels[2] = 2;  calcBackProject(&image,1,channels,histogram,result,ranges,255.0);  if (threshold>0.0)  {  cv::threshold(result, result, 255*threshold, 255, cv::THRESH_BINARY);  }  return result;  }  Mat find(const Mat &image,float minValue,float maxValue,int *channels,int dim)  {  Mat result;  hranges[0] = minValue;  hranges[1] = maxValue;  for(int i = 0;i < dim;i++)  {  this->channels[i] = channels[i];  }  calcBackProject(&image,1,channels,histogram,result,ranges,255.0);  if(threshold >0.0)  cv::threshold(result,result, 255*threshold,255,THRESH_BINARY);  return result;  }  };  int _tmain(int argc, _TCHAR* argv[]){ColorHistogram hc;ContentFinder finder;Mat result1;Mat image = imread("C:\\Users\\sony\\Desktop\\cloud.jpg");Mat imageROI = image(Rect(130, 156, 32, 32));Mat imagehist = hc.getHueHistogram(imageROI);    //归一化直方图 使其在0到1之间finder.setHistogram(imagehist);/*finder.setThreshold(0.3f);*/Mat hsv;  cvtColor(image,hsv,CV_BGR2HSV);  //表示通道int ch[1] ;ch[0] = 0;result1 = finder.find(hsv, 0.0f,180.0f,ch,1);  imshow("使用色度的结果(1)",result1); waitKey(0);return 0;}

效果图如下: