【问题标题】:opencv matrix multi channel access and fillopencv矩阵多通道访问和填充
【发布时间】:2014-02-01 16:09:56
【问题描述】:

我有一个包含 3 个通道的矩阵,但在访问和更改元素的值时遇到了问题。我有这个代码:

Mat m(4,4, CV_8UC3);   
Vec3b a;
a[0] = 255;
a[1] = 0;
a[2] = 0;
m.at<Vec3b>(0,0) = a;

当我打印矩阵 m 时,我有这个:

[255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

这很好,但是当我用imwrite 存储矩阵时得到的图像是这个:

我不明白为什么它是蓝色的,为什么我有一个方形的 2x2 蓝色,我应该只有第一个像素红色没有?

我是不是在某个地方做错了?

【问题讨论】:

    标签: c++ opencv matrix channels


    【解决方案1】:

    我不明白为什么它是蓝色的……不是红色的?

    在 OpenCV 中,图像格式由创建图像时的标志设置,例如CV_8UC3 表示 8 位像素,无符号,3 个颜色通道。在彩色图像中,像素顺序为BGR,数据按行顺序存储。同样,BGRA 对应于 CV_8UC4。所以你设置的值是蓝色而不是红色,这就是你得到蓝色的原因。

    我应该只有第一个像素...?

    原因是,对于压缩图像类型,例如JPG,他们无法保证内容准确无误。尝试 imwrite() 到未压缩的例如BMP 图像(通常)。你会得到这样的图像:

    【讨论】:

    • 非常感谢!有用!但我不明白为什么? JPG不好?
    • JPG 是一种压缩图像类型,它不会始终保持精确的内容。
    • 感谢您的解释! :)
    【解决方案2】:

    如前所述,高强度像素旁边的像素在 JPG 压缩后取非零值,因为 JPEG 是一种有损算法。事实上,JPEG 压缩会精确地丢弃具有强梯度的图像区域中的信息。

    关于你的第二个问题:你的像素是蓝色的,因为 Opencv 怪癖:颜色通道不是按 R、G、B 顺序存储,而是按 B、G、R 顺序存储:

    对于彩色图像,通道顺序通常是蓝、绿、红

    来源:http://docs.opencv.org/modules/core/doc/drawing_functions.html?highlight=green

    (这是让 Opencv 程序员的生活变得悲惨的事情之一)

    【讨论】:

    • 这不是 OpenCV 的怪癖,而是 Windows 的怪癖。如果您将 3 通道图像缓冲区按原样(作为 bmp 或 ppm)写入磁盘并在某些图片查看器中打开它,您将看到它被视为 BGR 图像而不是 RGB 图像。对于 OpenCV 来说,拥有 RGB 格式的图像意味着为每个 imread 和 imwrite 交换图像像素。在很多情况下,这只是浪费时间。
    • 好吧,BMP 和 PPM 的怪癖变成了 Opencv 的怪癖 :) 你知道在保存/读取 JPG 或 PNG 时是否交换了像素吗?
    • BMP 和 PPM 只是存储图像缓冲区而不进行任何压缩的格式的示例。如果您为图像分配 1 兆字节的内存并将其存储在硬盘上,它将占用 1 兆字节的硬盘空间。这不是 PNG 或 JPEG 的情况。这些图像会更小,这意味着它们已被压缩(PNG 的无损压缩和 JPG 的有损压缩)。因此,关于交换的问题是没有意义的,因为这些格式存储的不是像素值,而是可以从中恢复这些值的数据。
    猜你喜欢
    • 2011-09-17
    • 2017-06-02
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 2013-06-07
    • 2016-05-24
    相关资源
    最近更新 更多