在opencv中将cv :: Scalar的值设置为cv :: Mat中的像素的正确(最佳)方法是什么?

时间:2014-06-11 18:59:18

标签: c++ opencv

我有一个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的第二个元素应分配给第二个频道,两者都位于相应的位置
  • (....)

3 个答案:

答案 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]);