-1

I want to greyscale my images that will be uploaded into django. So I found two ways, either opencv or imagemagick. And within imagemagick, imagemagickWand might be better because it's reduced.

From the tutorials I think openCV is easier to implement.

Any ideas?

klaus ruprecht
  • 127
  • 1
  • 2
  • 10
  • 2
    Do you actually want the images to be converted to grayscale, or just *displayed* that way (which you can do with CSS)? – jonrsharpe Jul 28 '15 at 20:39
  • no I want them converted, cnavas would be another option but I want to do it in python thanks! – klaus ruprecht Jul 28 '15 at 20:43
  • 1
    This has nothing to do with django. [Here's a relevant question](http://stackoverflow.com/a/12201744/168775) that discusses converting an image to grayscale. – eykanal Jul 28 '15 at 21:03
  • possible duplicate of [How can I convert an RGB image into grayscale in Python?](http://stackoverflow.com/questions/12201577/how-can-i-convert-an-rgb-image-into-grayscale-in-python) – eykanal Jul 28 '15 at 21:03
  • No, I'm looking for advantages and disadvantages with the different methods, PIL is another one thanks – klaus ruprecht Jul 28 '15 at 21:11

2 Answers2

6

You can get nicer results if you convert to linear light first.

An sRGB image will have a gamma of about 2.4 applied to it, that is, there is more range in the bright areas than the dark. If you do 0.2 r + 0.7 g + 0.1 b directly on an sRGB image it can distort lightness relationships, for example:

enter image description here

From the left, those are the original image, a greyscale made by a simple recombination of sRGB, a greyscale made by a very fancy local adaptive algorithm, and a greyscale made in linear light. The linear light version keeps the red-blue difference better than the non-linear, though it doesn't look quite as nice as the adaptive version. You can read about the adaptive algorithm here.

Conversion to linear light can be done by a simple ungamma, if you are sure you have sRGB, or, better, by converting to XYZ using an ICC profile. pyvips has a linear-light greyscale conversion built in, try:

import pyvips

image = pyvips.Image.new_from_file("/home/john/pics/k2.jpg", access="sequential") 
image = image.colourspace("b-w")
image.write_to_file("x.jpg")

The advantages for vips over PIL or imagemagick would be better quality, faster, and much lower memory use. For a 10,000 x 10,000 pixel RGB JPEG, I see:

$ time ./magickwand.py 
real    0m2.613s
user    0m2.084s
sys 0m0.500s
peak RES 840MB
$ time ./vips.py
real    0m1.722s
user    0m5.716s
sys 0m0.116s
peak RES 54MB

That's on a two-core laptop.

jcupitt
  • 10,213
  • 2
  • 23
  • 39
  • Thank you so much! That is awesome! Exactly what I was looking for ! – klaus ruprecht Aug 18 '15 at 16:06
  • That seems like a cool library I can't import it though. I used `sudo apt-get install libvips` but I still get an error cannot import Vips – Tom Aug 29 '15 at 05:48
  • What version of vips is this? The current Python binding appears in v7.42 and later. Before then there was a simpler Python interface based on SWIG which you imported with `from vipsCC import *`. – jcupitt Aug 29 '15 at 19:41
  • I updated the sample code for the new libvips Python binding. You can install with just `pip install pyvips` now, and it should work on Windows, macOS and Linux. – jcupitt Sep 24 '17 at 20:57
  • Thank you for pointing out Adaptive Greyscale, might there be an open source Python implementation? – Jonathan May 01 '18 at 16:07
1

What's the best way to greyscale in python/django?

Take your pick.

ImageMagick's wand library

from wand.image import Image
with Image(filename='logo:') as img:
    img.colorspace = 'gray'
    img.save(filename='logo_gray.jpg')

Or CV2

import cv2
img = cv2.imread('example.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite('example_gray.jpg',gray)

Both projects are mature, stable, and have a large community base. Try installing both libraries, and experimenting.

In the end grayscale is just (from wikipedia).

Y = 0.2126 * RED + 0.7152 * GREEN + 0.0722 * BLUE

Both do this well, and depend on delegates (i.e. libjpeg) to read & write image formats.

emcconville
  • 23,800
  • 4
  • 50
  • 66
  • @klausruprecht I think the bulk of PIL folks have moved to pillow. But if I give an example, it would be the same 4 lines as above. Import, read, gray, write. – emcconville Jul 28 '15 at 21:30
  • Are you sure it is img.colorspace = 'gray'; and not img.type = 'grayscale'; ? – Tom Jul 31 '15 at 19:18
  • @PaulBernhardWagner Both work, but with different internal dynamics. OP did not specify context of grayscale. – emcconville Jul 31 '15 at 19:41
  • Ok, thanks! how can you manually adjust the grayscaling? Everytime when I use wand it turns pngs with transparent background into black background? – Tom Jul 31 '15 at 21:11