Opencv:如何计算3d直方图?

时间:2015-01-19 15:54:21

标签: c++ opencv image-processing histogram

我是OpenCV的新手,我将编写以下代码以计算rgb图像的量化和加权直方图。

M是权重图。这是一个与输入图像尺寸相同的Mat对象。 首先,我将所有(双)值放在[1,8]的范围内。然后,对于rgb值(1,1,1),(1,1,2),......(8,8,8)的每个三元组,我想总和相应权重的值。因此,当我找到三元组(1,2,1)时,我知道它对应于bin 9(即第9个bin)。所以我试着将M(x,y)的值加到当前的bin累加器H中,但它不起作用!

注意:在我的matlab代码中,我使用accumarray 但是,当我做

时出现问题
H.at<uchar>(idx,1) = H.at<uchar>(idx,1) + M.at<double>(Point(x, y));

如果我运行M.type(),则返回值3

Mat H = Mat::zeros(1,512,CV_8UC1);

    for (int y = 0; y < R.rows; ++y) {
        for (int x = 0; x < R.cols; ++x) {

            intensity = R.at<double>(Point(x, y));
            p = intensity[0];
            r = 1 + floor(p * 7.9999);
            cout << "R index = " << r << endl << endl;


            intensity = G.at<double>(Point(x, y));
            p = intensity[0];
            g = 1 + floor(p * 7.9999);
            cout << "G index = " << g << endl << endl;


            intensity = B.at<double>(Point(x, y));
            p = intensity[0];
            b = 1 + floor(p * 7.9999);
            cout << "B index = " << b << endl << endl;

            C.at<cv::Vec3b>(x, y)[0] = r;
            C.at<cv::Vec3b>(x, y)[1] = g;
            C.at<cv::Vec3b>(x, y)[2] = b;

            //idx = 1 +((r-1)*64  +  (g-1)*8  +  (b-1)*1 )
            //Here i don't sum 1 because in C the indices starts from 0
            idx =  (r - 1) * 64 + (g - 1) * 8 + (b - 1) * 1;

            H.at<uchar>(idx,1) = H.at<uchar>(idx,1) + M.at<double>(Point(x, y));
            cout << endl << idx;

        }
    }

修改 好的,让我在你的建议之后说一些改变,这些是C和H的初始化

cv::Mat C(doubleRed.rows, doubleRed.cols, CV_8UC3);
Mat H = Mat::zeros(1, 512, CV_16UC1);

我解决了

中发生的错误
C.at<cv::Vec3b>(x, y)[0] = r;
C.at<cv::Vec3b>(x, y)[1] = g;
C.at<cv::Vec3b>(x, y)[2] = b;

将x和y反转它们...但我希望理解为什么我必须这样做....但是当我尝试使用H的()函数时,代码仍会崩溃:

H.at<uchar>(idx, 1) = H.at<uchar>(idx, 1) + M.at<double>(Point(x, y));

1 个答案:

答案 0 :(得分:2)

我注意到的一些事情可能有所帮助:

您声明H如下:

Mat H = Mat::zeros(1,512,CV_8UC1);

然后你这样访问它:

H.at<uchar>(idx,1) = ...

因此,您要创建一个包含1 row512 columns的矩阵,然后访问row idxcolumn 1。您需要交换at中的索引:

H.at<uchar>(1,idx) = ...

修改: 索引似乎倒退的原因是at()命令参数如下:

H.at<uchar>(row,column) ... or
H.at<uchar>(y, x) ...

这与Point相反,Point2f P(column, row); or Point2f P(x, y); 命令参数如下:

CV_8UC1

http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-at

此外,我不知道您计划在每个垃圾箱中放置多少项,但除非它少于256, C.at<cv::Vec3b>(x, y)[0] = r; C.at<cv::Vec3b>(x, y)[1] = g; C.at<cv::Vec3b>(x, y)[2] = b; 太小。

最后,OpenCV中的图像通常是BGR顺序,所以你的

at

可能是倒退。对于速度,您可能还需要只调用Vec3b一次,并在访问各个元素之前将值存储在{{1}}中。