使用OpenCV畫RGB平面的分佈圖


這隻程式會讀取你指定的圖片,產生分別顯示紅,藍,綠3個平面的強度分佈圖,

使用的方法是用plot這個函數來手動產生繪製分佈圖的image

其實在官方文件中有提到怎麼畫出分佈圖
http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html

下面的程式的結果會類似這樣



#define _CRT_SECURE_NO_WARNINGS  // disable warnings for safe : fopen
#define _USE_MATH_DEFINES

#include <iostream>
#include <opencv.hpp> // C++ version
#include <cv.h>  // C version
#include <Windows.h>
#include <sstream>

using namespace std;
using namespace cv; // from C++ version


template<typename T>
void plot(string winname, T* data, int len, Scalar color=CV_RGB(0,0,255), unsigned int plot_height = 480, unsigned int plot_width = 640)
{
  double max_val;
  double min_val;
  double h_scale_factor;
  double w_scale_factor;

  int bnd_space = 20;

  T *itr = data, *end = data+len;
  Mat img;
  Point prev_pt, curr_pt;

  if (data==NULL || len<0)
  {
    cerr << "Cannot plot the data(data=NULL or length<0)" << endl;
    exit(-1);
  }

  // prepare the figure
  img.create(plot_height, plot_width, CV_8UC3);
  img = CV_RGB(255,255,255);

  // axis y
  prev_pt.x = bnd_space-1; prev_pt.y = bnd_space;
  curr_pt.x = bnd_space-1; curr_pt.y = plot_height-bnd_space;
  line(img, prev_pt, curr_pt, CV_RGB(0,0,0));
  // axis x
  prev_pt.x = bnd_space-1;          prev_pt.y = plot_height-bnd_space+1;
  curr_pt.x = plot_width-bnd_space; curr_pt.y = plot_height-bnd_space+1;
  line(img, prev_pt, curr_pt, CV_RGB(0,0,0));

  // find min, max;
  max_val = min_val = *itr++;
  while(itr != end)
  {
    if (*itr>max_val)
      max_val = *itr;
    else if (*itr<min_val)
      min_val = *itr;
    itr++;
  }
  itr -= len;

  // plot image sizes
  plot_height -= bnd_space + bnd_space;
  plot_width  -= bnd_space + bnd_space;

  h_scale_factor = plot_height / ( max_val - min_val );
  w_scale_factor = plot_width  / double(len);

  prev_pt.x = bnd_space;
  prev_pt.y = bnd_space + plot_height - ((double)*itr-min_val) * h_scale_factor;

  while(itr != end)
  {
    curr_pt.x = bnd_space + (int)((itr-data) * w_scale_factor);
    curr_pt.y = bnd_space + plot_height - ((double)*itr-min_val) * h_scale_factor;
    line(img, prev_pt, curr_pt, color);
    prev_pt = curr_pt;
    itr++;
  }

  imshow(winname, img);
}

int main(int argc, char** argv)
{
  string img_path = "images.jpg";

  if (argc > 1)
    img_path = argv[1];

  Mat img = imread(img_path, CV_LOAD_IMAGE_COLOR);
  if (!img.data)
  {
    cerr << "Cannot read the image file path = " << img_path << endl;
    system("pause");
    return -1;
  }

  Mat planes[3];
  split(img, planes);

  int hist[3][256] = {0};
  for (int c=0 ; c<3 ; ++c)
  {
    MatIterator_<uchar> itr = planes[c].begin<uchar>();
    MatIterator_<uchar> end = planes[c].end<uchar>();
    while(itr!=end)
      hist[c][*itr++]++;
  }

  plot("Red",   hist[2], 256, CV_RGB(255,0,0), 200, 300);
  plot("Green", hist[1], 256, CV_RGB(0,255,0), 200, 300);
  plot("Blue",  hist[0], 256, CV_RGB(0,0,255), 200, 300);
  waitKey();

  return 0;
}


留言