xiaolingxiao
xiaolingxiao

Reputation: 4895

Convert all white pixels in the image into black pixels

I have this image rand-walk-2.png

rand-walk-2.png

I would like to convert all the white pixels to black pixels, so that there is a picture of a red random walk over a black background, this means I cannot just invert the colors of image. My current code simply finds the white pixels and set them to black:

from PIL import Image
import PIL.ImageOps    
import numpy as np
from skimage.io import imsave
import cv2


in_path  = 'rand-walk-2.png'
out_path = 'rand-walk-trial.png'


Image = cv2.imread(in_path)
Image2 = np.array(Image, copy=True)

white_px = np.asarray([255, 255, 255])
black_px = np.asarray([0  , 0  , 0  ])

(row, col, _) = Image.shape

for r in xrange(row):
    for c in xrange(col):
        px = Image[r][c]
        if all(px == white_px):
            Image2[r][c] = black_px

imsave(out_path, Image2)

But it produces this:

rand-walk-trial.png

for some reason I cannot explain.

Upvotes: 4

Views: 9301

Answers (1)

Andriy Makukha
Andriy Makukha

Reputation: 8344

The reason is that module skimage (in your case function skimage.io.imsave) uses RGB color sequence, whereas OpenCV (in your case function cv2.imread) notoriously uses BGR color sequence. So blue and red colors become swapped with your script.

Two solutions for you would be to either convert the image to RGB directly after reading:

Image = cv2.imread(in_path)
Image = cv2.cvtColor(Image, cv2.COLOR_BGR2RGB)

Or to save the output image with cv2:

cv2.imwrite(out_path, Image2)

Result:

Red random walk on black background


Another solution, which gives much nicer output, is simply inverting your image:

Image = cv2.imread(in_path)
Image = cv2.bitwise_not(Image)
cv2.imwrite(out_path, Image)

Result:

Beautiful cyan random walk on black background

Or, if you still want red color, you could invert, remove green channel and swap blue and red:

Image = cv2.imread(in_path)
Image = cv2.bitwise_not(Image)
b,g,r = cv2.split(Image)
z = np.zeros_like(g)
Image = cv2.merge((z,z,b))
cv2.imwrite(out_path, Image)

Result:

Beautiful red random walk on black background

Upvotes: 7

Related Questions