我有一个cv::Mat
对象,
cv::Mat _a ...
...和cv::Scalar
对象,
cv::Scalar _b ...
将_b
的值设置为_a
中的像素(位置(x,y))的正确(最佳)方法是什么?
请注意,对象_a
可以包含1,2,3,4个通道,但代码应该适用于所有情况,即:
_a
有1个频道时,_b
的第一个元素应分配到相应的位置_a
有2个频道时,_b
的第一个元素应分配给第一个频道,而_b的第二个元素应分配给第二个频道,两者都位于相应的位置答案 0 :(得分:1)
cv::Mat
的重载operator=
需要cv::Scalar
。这有你想要的确切行为。不幸的是,没有直接的方法将Scalar
分配给像素值。但是,您可以创建一个感兴趣区域,其中包含坐标(x, y)
处的单个像素,并将Scalar
分配给该区域:
cv::Mat a; // contains data
cv::Scalar b(1,2,3,4);
cv::Range xr(x, x + 1);
cv::Range yr(y, y + 1);
a(xr, yr) = b;
答案 1 :(得分:0)
这不是很好或简洁,但您可以切换Mat
的{{3}}并迭代Mat
的频道来创建/分配Scalar
。像这样:
void getPixel(Mat m, int x, int y, Scalar &pixel) {
switch (m.depth()) {
case 0:
for (size_t i = 0; i < m.channels(); ++i) pixel[i] = m.at<uchar>(x, y);
break;
case 1:
for (size_t i = 0; i < m.channels(); ++i) pixel[i] = m.at<char>(x, y);
break;
case 2:
for (size_t i = 0; i < m.channels(); ++i) pixel[i] = m.at<ushort>(x, y);
break;
case 3:
for (size_t i = 0; i < m.channels(); ++i) pixel[i] = m.at<short>(x, y);
break;
case 4:
for (size_t i = 0; i < m.channels(); ++i) pixel[i] = m.at<long>(x, y);
break;
case 5:
for (size_t i = 0; i < m.channels(); ++i) pixel[i] = m.at<float>(x, y);
break;
case 6:
for (size_t i = 0; i < m.channels(); ++i) pixel[i] = m.at<double>(x, y);
break;
}
}
答案 2 :(得分:0)
我不会使用opencv中的.at函数。当你迭代一幅大图时它很慢。 为RGB图像准备好一些结构:
#pragma pack(push, 2)
struct RGB { //members are in "bgr" order!
uchar blue;
uchar green;
uchar red; };
然后创建一个指向图像扫描线的指针,如下所示:
RGB& rgb = image.ptr<RGB>(y)[x]; //y = row, x = col
然后您可以像这样分配值:
cv::Scalar(image.ptr<RGB>(y)[x].value[0], image.ptr<RGB>(y)[x].value[1], image.ptr<RGB>(y)[x].value[2]);