在OpenCV C++中将RGB彩色图像转换为索引颜色图像类型

3

我想将RGB图像转换为索引颜色类型。

这是我的C++代码。它可以将图像转换为灰度图像。

我应该怎么做?

Mat black_background = imread("image_path", IMREAD_COLOR); 

Mat output;
cvtColor(black_background, output, cv::COLOR_RGB2GRAY);

imwrite("save_path", output);

也许你可以查看这个线程和这个博客 - Nayfe
2
请返回已翻译的文本:和https://dev59.com/gpTfa4cB1Zd3GeqPNjZF#35482205 - Miki
一个问题是你不能使用 imwrite 来保存这样的图像。 - Dan Mašek
2个回答

2
我认为OpenCV的imwrite()不支持写入调色板PNG。一种选择是先按任何其他格式进行编写,然后使用ImageMagick转换为调色板PNG。

ImageMagick包含在大多数Linux发行版中,并可用于macOS和Windows。

因此,在终端或Windows上的命令提示符中:
magick input.png PNG8:result.png

在 ImageMagick 的 v7 之前,这将是:"最初的回答"。
convert input.png PNG8:result.png

PNG8:前缀会强制生成调色板颜色的PNG格式图片。


如果你不想事后手动转换文件,可以使用OpenCVimwrite()将它们作为PNG文件写入文件系统,然后使用C++的system()调用ImageMagick进行转换:

#include <stdlib.h>

...

imwrite('result.png', image);

// Delegate conversion to palette image to ImageMagick
system("magick result.png PNG8:result.png');

对于更加焦虑/敏锐的读者:

  • 是的,与其他Unix工具不同,使用相同的文件作为ImageMagick的输入和输出是可以的,并且不会出现损坏的情况,因为在处理之前文件会被完整地读取,然后再写出。

  • 是的,ImageMagick将隐式处理量化,以将图像中的颜色减少为调色板版本。

  • 是的,您可以强制使用其他类型的PNG文件,例如使用其他前缀的RGB24:result.png将导致RGB888输出,RGB32:result.png将导致RGBA8888输出,RGB48:result.png将导致16位红色、16位绿色和16位蓝色输出等。


备注:对于那些想要移植到Android/iOS的人,可以使用png++或libpng :) https://stackoverflow.com/questions/61355551/how-to-create-and-write-an-indexed-png-image-in-c-or-c - ch271828n
难以置信OpenCV没有对此提供支持。applyColorMap创建3通道图像... - Pedro77

0

我为索引色图像编写了自己的编码器/解码器,通过手动对BMP和PNG格式进行编码/解码。它在我的生产环境中运行良好。

代码思路:手动查看BMP/PNG内部的块(例如png中的PLTE块)。示例代码如下,您也可以编写/修改您自己的代码。

代码的用法:

// sample usage
int main() {
  Mat image_index = ...;
  Mat palette = ...;
  vector<uchar> encoded_bytes = imencode_palette_bmp(image_index, palette);
}

完整代码(gist):https://gist.github.com/fzyzcjy/8b1736a294aab81eb86243bfb6fdc260

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接