2

Question is simple. I have lots of 3-channel RGB images. (Their colors are already grey, but you know, RGB format.) What I want is converting them to grey-scale image with 1-channel.

I tried opencv to do it. But after I save it with png format, it ruined. I think structure of png file is the reason...

Anyway, is there any nice way to do this? Recommendation for 1-channel image format will also be really appreciated.

gameon67
  • 3,981
  • 5
  • 35
  • 61
Jun
  • 135
  • 1
  • 7
  • Why do you want to do this? Are you doing this to reduce the image size? – flamelite Jan 11 '19 at 05:28
  • Umm.. there are several reasons, but main reason is following two. 1. My images are already grey, so as you mentioned I want to save my memory. 2. I will use these images for inputs of machine learning. I hope using 1-channel image as input can make my network to learn better and faster. – Jun Jan 11 '19 at 05:35
  • I found different ways of doing what you're asking here: https://stackoverflow.com/questions/12201577/how-can-i-convert-an-rgb-image-into-grayscale-in-python – Sebastien Jan 11 '19 at 06:46
  • @Sebastien I also found that and already tried. But result of conversion was not 1-channel grey image. It was just 3-channel RGB image with grey color. (Basically nothing changed in my case, because already all grey.) – Jun Jan 11 '19 at 06:56
  • Have you tried all the answers? Notably the one with `gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)` – Sebastien Jan 11 '19 at 07:21
  • 1
    Please show the code you tried and what didn't work. It would be very easy to suggest another format but that might bring new problems. You also need to say **why** you are trying to do this and also what package and whar processing you intend to use later on. Nobody wants to advise you incorrectly. – Mark Setchell Jan 11 '19 at 08:32
  • 1
    For your 2nd reason, you can convert images to gray before using for training. – Ha Bom Jan 11 '19 at 08:34
  • PNG supports grayscale (1,2,4,8,16 bpp, and also with alpha transparency at 8 and 16bpp). OpenCV will write a grayscale PNG if passed a 1 channel image (verified). Problem is likely somewhere else (but impossible to tell due to lack of provided details). – Dan Mašek Jan 11 '19 at 16:41

1 Answers1

2

If you have a few dozen images, a quick way to convert them all to single-channel, greyscale images that OpenCV can read is with ImageMagick in the Terminal - it is included in most Linux distros and is available for macOS and Windows. So, to make a single channel 8-bit PGM version of all PNGs in the current directory:

magick mogrify -format PGM -colorspace gray -depth 8 *.png

If you have many hundreds or thousands of images, use GNU Parallel as well to get all your CPU cores running in parallel:

parallel -X magick mogrify -format PGM -colorspace gray -depth 8 ::: *.png

HOWEVER, I would not advise you do that because there are many other things you need to think about:

  • if your images contain important meta-data, you need to choose a format that retains it, which is not PGM

  • if your images contain floating point pixel data, you should maybe use TIFF format

  • if your purpose is to save disk space (which seems silly in this age of nearly free storage), you should consider a compressible format

  • if your purpose is to save RAM, there may be no need at all to do any of this as you can just convert your images to single-channel on load, e.g. OpenCV imread(...cv2.IMREAD_GRAYSCALE)

So, you need to be clearer as to your data and your purposes. Note also that many people claim to want to save "memory" and they could mean disk or RAM.

Bear in mind also that PNG can save 8 or 16-bit images, colour or greyscale and with or without a palette (depending on the number of colours) that subsequent applications may or may not be able to handle.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432