【问题标题】:OpenCV cv::Mat 'ones' for multi-channel matrix?用于多通道矩阵的 OpenCV cv::Mat 'ones'?
【发布时间】:2012-09-02 20:18:04
【问题描述】:

在 OpenCV 中使用 1 通道(例如 CV_8UC1)Mat 对象时,这会创建一个全为 1 的 Mat:cv::Mat img = cv::Mat::ones(x,y,CV_8UC1)

但是,当我使用 3 通道图像(例如 CV_8UC3)时,事情会变得有点复杂。执行cv::Mat img = cv::Mat::ones(x,y,CV_8UC3) 会将 ones 放入通道 0,但通道 1 和 2 包含 zeros那么,如何将cv::Mat::ones() 用于多通道图像?

这里有一些代码可以帮助你理解我的意思:

void testOnes() {
 int x=2; int y=2; //arbitrary

 // 1 channel
 cv::Mat img_C1 = cv::Mat::ones(x,y,CV_8UC1);
 uchar px1 = img_C1.at<uchar>(0,0); //not sure of correct data type for px in 1-channel img
 printf("px of 1-channel img: %d \n", (int)px1); //prints 1

 // 3 channels
 cv::Mat img_C3 = cv::Mat::ones(x,y,CV_8UC3); //note 8UC3 instead of 8UC1
 cv::Vec3b px3 = img_C3.at<cv::Vec3b>(0,0);
 printf("px of 3-channel img: %d %d %d \n", (int)px3[0], (int)px3[1], (int)px3[2]); //prints 1 0 0
}

所以,我本来希望看到这个打印输出:px of 3-channel img: 1 1 1,但我看到的是这个:px of 3-channel img: 1 0 0

附:在发布这个之前我做了很多搜索。我无法通过搜索“[opencv] Mat::ones”或“[opencv] +mat +ones”来解决此问题。

【问题讨论】:

  • 旁注:对于 1 通道图像像素,我不确定是否应该使用 uchar 代替 cv::Vec3b。 OpenCV 提供了很多 2 项、3 项和 4 项向量类,但无法类比单例。 (在本页搜索Vec3bopencv.willowgarage.com/documentation/cpp/…

标签: c++ image image-processing opencv matrix


【解决方案1】:

我不使用 OpenCV,但我相信我知道这里发生了什么。您定义了一个数据类型,但您为此请求值“1”。 Mat 类似乎没有注意您拥有多通道数据类型这一事实,因此它只是将“1”转换为 3 字节无符号字符。

所以不要使用ones函数,而是使用标量构造函数:

cv::Mat img_C3( x, y, CV_8UC3, CV_RGB(1,1,1) );

【讨论】:

  • 我刚刚试用了您的解决方案。 cv::Mat img_C3 = cv::Mat::ones(x,y,CV_8UC3) * CV_RGB(1,1,1); 无法编译,因为 cv::Mat 类型没有重载运算符 *cv::Mat img_C3( x,y,CV_8UC3,CV_RGB(1,1,1) ); 编译,但它将像素的通道定义为1 0 0,就像我的问题中的ones 示例一样。我现在正在更深入地研究您的答案。
  • 哦,等等,cv::Mat img_C3( x,y,CV_8UC3,CV_RGB(1,1,1) ); 工作正常!
  • 我希望第一个解决方案能够工作,这取决于我在哪里找到它 (opencv.willowgarage.com/documentation/cpp/…),但它可能不适用于 CV_RGB 的返回类型。在偶然发现该宏之前,我最初写了 0x10101。试试看,如果可行,我会调整您建议的修改。
  • 当我这样做时:cv::Mat img_C3 = cv::Mat::ones(x,y,CV_8UC3) * CV_RGB(1,1,1);,代码打印px of 3-channel img: 255 0 0。部分问题在于,如果我们从值为 {1,0,0} 的像素开始,将图像乘以一个数字就会得到 {n,0,0}。但是,我对 * 运算符没有被重载是错误的——它在乘以原始数据类型时显然有效。感谢您跟进并为此花费大量时间。 :)
  • 不用担心。出于某种原因,您的编辑没有再次出现在我面前。无论如何,我只是删除了另一个选项。无论如何,这很愚蠢。此外,我随后读到使用 * 运算符实际上并没有当场乘法。它存储一个比例因子供以后使用。对我来说听起来很狡猾。
【解决方案2】:

你也可以这样初始化:

Mat img;

/// Lots of stuff here ...

// Need to initialize again for some reason:
img = Mat::Mat(Size(width, height), CV_8UC3, CV_RGB(255,255,255));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-17
    • 2014-06-01
    • 2021-08-11
    • 1970-01-01
    • 2012-07-17
    • 2022-01-22
    • 2017-06-02
    • 1970-01-01
    相关资源
    最近更新 更多