简体   繁体   中英

Convert RGB Color Image to Indexed Color Image Type in OpenCV C++

I want to convert rgb image to indexed color type.

Here is my Code C++. This is convert to gray scale.

what should I do?

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

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

imwrite("save_path", output);

I do not believe OpenCV 's imwrite() supports writing a palettised PNG. One option may be to write as any other format you like and convert to a palettised PNG with ImageMagick afterwards.

ImageMagick is included in most Linux distros and is available for macOS and Windows.

So, in Terminal, or Command Prompt on Windows:

magick input.png PNG8:result.png

Prior to v7 of ImageMagick that would be:

convert input.png PNG8:result.png

The PNG8: prefix forces a palettised result.


If you don't want to have to go around converting your files explicitly afterwards, you could write them using OpenCV 's imwrite() as PNG files in the filesystem and then use C++'s system() to get ImageMagick to convert them:

#include <stdlib.h>

...

imwrite('result.png', image);

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

For the more anxious/astute readers:

  • yes, unlike with other Unix utilities, it is ok to use the same file for input as output with ImageMagick and there is no fear of corruption because the file is read in its entirety before being processed and then written out,

  • yes, ImageMagick will implicitly take care of the quantisation necessary to reduce the colours in the image to a palette version,

  • yes, you can force other types of PNG file with other prefixes, eg RGB24:result.png will result in RGB888 output, RGB32:result.png will result in RGBA8888 output, RGB48:result.png will result in 16-bit red, 16-bit green and 16-bit blue and so on.

I write down my own encoder/decoder for indexed color image, by manually encode/decode the BMP and PNG format. It works well for me (in production environment).

The idea of the code: Manually look at the blocks inside BMP/PNG (eg the PLTE block in png). The sample code is below, and you can also write/modify to your own.

The usage of the code:

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

Full code (gist): https://gist.github.com/fzyzcjy/8b1736a294aab81eb86243bfb6fdc260

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM