繁体   English   中英

OpenCV:如何计算3D直方图?

[英]Opencv: how to compute a 3d 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会引起问题...但是我希望理解为什么我必须这样做。...但是,当我尝试使用函数at()时,代码仍然崩溃:

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

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

您声明H如下:

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

然后像这样访问它:

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

因此,您要创建一个包含1 row512 columns的矩阵,然后访问row idxcolumn 1 row idx 您需要交换指数在你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);

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

另外,我不知道您计划每个存储箱中有多少个项目,但是除非它少于256个, CV_8UC1太小了。

最后,OpenCV中的图像通常按BGR顺序排列,因此您的

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

可能倒退了。 对于速度,你可能还需要打电话at只有一次,存储在一个价值Vec3b访问各个元素之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM