【问题标题】:OpenCV - Confusion using calcHistOpenCV - 使用 calcHist 混淆
【发布时间】:2013-02-19 02:54:42
【问题描述】:

我已经多次阅读 calcHist() 的文档,但我认为我对 OpenCV 的缺乏经验和生疏的编程技能完全使我无法理解它。

我正在寻找 HSV 图像(色调或通道 [0])的一个通道中的像素计数,以使用 10 个根据类似的东西非常接近颜色的 bin 进行分割(让我们以此为例,我偷了网络范围外的范围-fwiw,省略紫红色似乎是错误的):

红色:0-19 & 330-360 红黄 (RY):20-49 黄色:50-69 YG: 70-84 绿色:85-170 国标:171-191 蓝色:192-264 血压:265-289 紫色:290-329

等等……

那么我该如何使用 calcHist 做到这一点?

目前为止:

#include <opencv2/opencv.hpp>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char *argv[])
{
    Mat scene, sceneHSV, dest, histo;
    int numImages = 1, histChannel[] = {0}, dims = 1, histSize[] = {10};

    float redRange[] = {0, 10};
    float roRange[] = {10, 25};
    float orangeRange[] = {25, 35};
    float oyRange[] = {35, 42};
    float yellowRange[] = {42, 85};
    float ygRange[] = {85, 96};
    float greenRange[] = {96, 132};
    float gbRange[] = {132, 145};
    float blueRange[] = {145, 160};
    float bpRange[] = {160, 165};
    float purpleRange[] = {165, 180};

    const float* ranges[] = {redRange, roRange, orangeRange, oyRange, yellowRange, ygRange, greenRange, gbRange, blueRange, bpRange, purpleRange};

    vector<Mat> channels;

    scene = imread("Apple.jpg", 1);
    if (scene.data == NULL)
    {
        cout<<"FAIL"<<endl;
        cin.get();
    }

    cvtColor(scene, sceneHSV, CV_BGR2HSV);
    dilate(sceneHSV, sceneHSV, Mat(), Point(-1, -1), 1, BORDER_CONSTANT, 1);
    pyrMeanShiftFiltering(sceneHSV, dest, 2, 50, 3);
    split(sceneHSV, channels); 

    calcHist(&scene, 1, histChannel, Mat(), histo, dims, histSize, ranges, false, false); 

    cout<<histo<<endl;

    waitKey(0);

    return 0;
}

现在呢?在这种情况下, calcHist 的参数是什么样的,输出直方图是什么样的?只是一个 1x9 数组,里面是整数?

非常感谢。

【问题讨论】:

    标签: c++ opencv image-processing image-segmentation


    【解决方案1】:

    我修改了here的代码

    您可能还想看看 cvtColor here 的文档

    请注意,我没有尝试编译或运行此代码,因此我不保证它会起作用。不过,作为参考,它可能很有用。

    Mat hist;
    int nimages = 1; // Only 1 image, that is the Mat scene.
    int channels[] = {0} // Index for hue channel
    int dims = 1 // Only 1 channel, the hue channel
    int histSize[] = {9} // 9 bins, 1 each for Red, RY, Yellow, YG etc.
    float hranges[] = { 0, 180 }; // hue varies from 0 to 179, see cvtColor
    const float *ranges[] = {hranges};
    
    // Compute the histogram.
    calcHist(&scene, 
    nimages, 
    channels, 
    Mat(), // No mask
    hist, dims, histSize, ranges, uniform=true)
    
    // Now hist will contain the counts in each bin.
    // Lets just print out the values. Note that you can output Mat using std::cout
    cout << "Histogram: " << endl << hist << endl;
    
    // To access the individual bins, you can either iterate over them
    // or use hist.at<uchar>(i, j); Note that one of the index should be 0
    // because hist is 1D histogram. Print out hist.rows and hist.cols to see if hist is a N x 1 or 1 x N matrix.
    /*
    MatIterator_<uchar> it, end;
    int binIndex = 0;
    for( it = hist.begin<uchar>(), end = hist.end<uchar>(); it != end; ++it)
    {
      printf("Count in %d bin: %d\n", binIndex, *it);
      ++binIndex;
    }
    */
    

    【讨论】:

    • 我会尝试这个,虽然还有一些其他的东西 - 我确实注意到 OpenCV 的 HSV 比例从 0 到 180,所以我只需将所有这些范围缩放一倍 -一半 - 谢谢你的提醒。
    • 另外,以上如何解释我为颜色不均匀给出的范围?
    • 我认为,如果在将矩阵传递给 cvtColor(...) 之前将矩阵转换为 CV_32F 或 CV_64F,色调将在 0 到 360 之间。为了处理不均匀间隔的范围,有有几件事要改变。首先,将“uniform”参数设置为 false。其次,将 hranges 更改为 float hranges[] = {0, 20, 20, 50, 50, 70, ..., Li, Ui, ...} 其中 hranges 包含 histSize[i]+1 个元素,即多 1 个比你的垃圾箱数量。 Li, Ui 分别是 bin i 的下(包括)和上(不包括)边界。有关更多详细信息,请参阅我在上面提供的 calcHist 链接。希望这会有所帮助。
    • 以下是我推荐的测试 calcHist 函数的方法。从某个范围内的均匀/高斯分布生成随机数,例如 0 到 255(含)。在这个 Mat 上调用 calcHist。检查输出以查看它是否看起来“正常”。如果您了解 python,则绘制直方图很容易。此外,OpenCV 的示例包含有关如何使用 calcHist 的示例代码,您可以对其进行修改以满足您的需求以及测试您对该方法的理解。
    • 尝试了我原始帖子编辑中包含的更新代码并收到此错误:OpenCV Error: Assertion Failed (ranges[i][j]
    猜你喜欢
    • 1970-01-01
    • 2011-10-11
    • 2015-05-05
    • 2013-05-27
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多