c++ - 如何在 OpenCV 中访问单 channel 矩阵

标签 c++ opencv image-processing

我想问一下是否可以使用img.at<T>(y, x)访问单 channel 矩阵而不是使用 img.ptr<T>(y, x)[0]

在下面的示例中,我创建了一个将图像复制到另一个的简单程序

cv::Mat inpImg = cv::imread("test.png");
cv::Mat img;  
inpImg.convertTo(img, CV_8UC1); // single channel image

cv::Mat outImg(img.rows, img.cols, CV_8UC1);

for(int a = 0; a < img.cols; a++)
    for(int b = 0; b < img.rows; b++)
        outImg.at<uchar>(b, a) = img.at<uchar>(b, a);   // This is wrong

cv::imshow("Test", outImg);

显示的结果是错误的,但是如果我把它改成

outImg.ptr<uchar>(b, a)[0] = img.ptr<uchar>(b, a)[0];

结果正确。

自从使用了img.at<T>(y, x)之后我就很疑惑了应该也可以吧。我也尝试了 32FC1 和 float,结果是相似的。

最佳答案

虽然我知道您已经找到它,但真正的原因 - 很好地隐藏在文档中 - 是 cv::convertTo忽略输出类型隐含的 channel 数,因此当您这样做时:

inpImg.convertTo(img, CV_8UC1); 

并且,假设您的输入图像具有三个 channel ,您实际上会得到一个 CV_8UC3 格式,这解释了为什么您的初始解决方法是成功的 - 实际上,您通过这样做只采用了一个 channel :

outImg.ptr<uchar>(b, a)[0]     // takes the first channel of a CV_8UC3

这只是偶然起作用,因为应该像这样访问像素:

outImg.ptr<Vec3b>(b, a)[0]     // takes the blue channel of a CV_8UC3

由于在这两种情况下数据仍然打包 uchar,有效的重新解释恰好起作用。

如您所述,您可以在加载时转换为灰度:

cv::imread("test.png", CV_LOAD_IMAGE_GRAYSCALE)

或者,您可以显式转换:

cv::cvtColor(inpImg, inpImg, CV_BGR2GRAY);

关于c++ - 如何在 OpenCV 中访问单 channel 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20876068/

相关文章:

c++ - 重新定义格式参数错误

c++ - OS X 将扩展与应用程序相关联

c++ - std::erase 和 std::remove 组合删除特定元素不适用于特定示例

c++ - 在 OpenCV 中绘制具有渐变颜色的线

php - 如何让PHP和C/C++相互交互

python - 如何使用 Python 2.7.5 使 Opencv 2.4.8 在 Windows7 Cygwin64 上运行?

visual-studio-2010 - CV_CAP_OPENNI 不适用于我

python - 从图像中的绝对点创建相对点网格

python - 使用 OpenCV 3 和 python 3 按区域对图像轮廓进行排序的最佳解决方案

python - K-means 颜色聚类 - 使用屏蔽 numpy 数组省略背景像素