使用 openCV 绘制 RGB 的强度配置文件

Posted

技术标签:

【中文标题】使用 openCV 绘制 RGB 的强度配置文件【英文标题】:Drawing intensity profile for RGB using openCV 【发布时间】:2014-07-01 06:24:49 【问题描述】:

我是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 并绘制这些值。

请给我一些提示或示例代码 sn-p 以帮助我理解这一点。

【问题讨论】:

你想要histogram 吗? 没有。我只想沿任意轴扫描并绘制 R(比如说)的变化。 @berak 你能告诉我如何提取 R、G 和 B 值并放入三个不同的数组吗?我会休息的。谢谢 Accessing certain pixel RGB value in openCV的可能重复 @GPPK,这是怎么复制的? 【参考方案1】:

您可以使用 cv::split() 将 R、G 和 B 分成单独的 Mats

std::vector<Mat> planes(3);
cv::split(img, planes);
cv::Mat R = planes[2];
cv::Mat G = planes[1];
cv::Mat B = planes[0];

但是,如果您的代码期望 Mat 具有单色通道,则只需像这样将它们分开即可。 不要像假设的重复建议那样使用at&lt;&gt;() - 如果您按顺序扫描图像,它真的很慢(但它有利于随机访问)。

你可以像这样高效地扫描图像

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 );
   

【讨论】:

你能告诉我在哪里可以得到你使用的 process() 的定义吗? 哦,也许你的意思是我必须编写自己的函数来处理这些数据。 B 的号角又来了 .. ;) @B... 感谢代码 sn-p。但是,我想将 r、g、b 收集在三个不同的数组中,而不是像你展示的那样在每次循环迭代中被覆盖的字符。 @berak 抱歉英语不好。为了进一步澄清,我问了这个问题Saving Mats to int arrays in opencv

以上是关于使用 openCV 绘制 RGB 的强度配置文件的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV - 浮点数据类型和强度范围在 0-255 内的 RGB 通道

OpenCV里的颜色空间

OpenCV RGB直方图计算与绘制----calcHist()函数normalize()函数

将 RGB 图像转换为 3 个 HSI 输出

OpenCV开发环境配置(配人脸识别源码测试)

python-opencv轮廓基本绘制