问题
I have this image 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:
for some reason I cannot explain.
回答1:
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:
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:
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:
来源:https://stackoverflow.com/questions/49888538/convert-all-white-pixels-in-the-image-into-black-pixels