我是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));
答案 0 :(得分:2)
我注意到的一些事情可能有所帮助:
您声明H
如下:
Mat H = Mat::zeros(1,512,CV_8UC1);
然后你这样访问它:
H.at<uchar>(idx,1) = ...
因此,您要创建一个包含1 row
和512 columns
的矩阵,然后访问row idx
和column 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}}中。