[英]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 row
和512 columns
的矩阵,然后访问row idx
和column 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.