使用openCV绘制RGB的强度分布图

时间:2014-07-01 06:24:49

标签: c++ opencv

我是openCV的初学者。

我想为下面给出的图像绘制R,G和B的强度分布图。

我想将R,G和B值w.r.t绘制到三个不同图形中的像素位置。

到目前为止,我已经学会了如何阅读图像和显示。例如使用imread();

 Mat img = imread("Apple.bmp");

然后使用imshow(" Window",img)在屏幕上显示它;

现在我想将所有R,G和B值放在3个独立的缓冲区中; buf1,buf2,buf3并绘制这些值。

请提供一些提示或示例代码段,以帮助我理解这一点。

enter image description here

1 个答案:

答案 0 :(得分:3)

您可以使用cv::split()

将R,G和B分成单独的垫子
std::vector<Mat> planes(3);
cv::split(img, planes);
cv::Mat R = planes[2];
cv::Mat G = planes[1];
cv::Mat B = planes[0];

但是你只需要将它们分开就像这样,如果你有代码期望一个单色的泡沫垫。 不要使用at<>()作为假定的重复建议 - 如果您按顺序扫描图像,它会非常慢(但它适用于随机访问)。

您可以像这样有效地扫描图像

for(int i = 0; i < img.rows; ++i)
{
    // get pointers to each row
    cv::Vec3b* row = img.ptr<cv::Vec3b>(i);

    // now scan the row
    for(int j = 0; j < img.cols; ++j)
    {   
        cv::Vec3b pixel = row[j];
        uchar r = pixel[2];
        uchar g = pixel[1];
        uchar b = pixel[0];
        process(r, g, b);
    } 
}

最后,如果您想制作直方图,可以使用此代码。它相当陈旧,所以我认为它仍然有效。

void show_histogram_image(cv::Mat src, cv::Mat &hist_image)
{ // based on http://docs.opencv.org/2.4.4/modules/imgproc/doc/histograms.html?highlight=histogram#calchist

   int sbins = 256;
   int histSize[] = {sbins};

   float sranges[] = { 0, 256 };
   const float* ranges[] = { sranges };
   cv::MatND hist;
   int channels[] = {0};

   cv::calcHist( &src, 1, channels, cv::Mat(), // do not use mask
       hist, 1, histSize, ranges,
       true, // the histogram is uniform
       false );

   double maxVal=0;
   minMaxLoc(hist, 0, &maxVal, 0, 0);

   int xscale = 10;
   int yscale = 10;
   //hist_image.create(
   hist_image = cv::Mat::zeros(256, sbins*xscale, CV_8UC3);

   for( int s = 0; s < sbins; s++ )
   {
       float binVal = hist.at<float>(s, 0);
       int intensity = cvRound(binVal*255/maxVal);
       rectangle( hist_image, cv::Point(s*xscale, 0),
           cv::Point( (s+1)*xscale - 1, intensity),
           cv::Scalar::all(255),
           CV_FILLED );
   }
}