Convertir RGB a negro o blanco

¿Cómo tomaría una imagen RGB en Python y la convertiría a blanco o negro? No en escala de grises, quiero que cada píxel sea completamente negro (0, 0, 0) o completamente blanco (255, 255, 255).

¿Existe alguna funcionalidad incorporada para esto en las populares bibliotecas de procesamiento de imágenes de Python? Si no, ¿sería la mejor manera de recorrer cada píxel, si está más cerca del blanco, establecerlo en blanco, si está más cerca del negro, establecerlo en negro?

Escalado a blanco y negro

Convertir a escala de grises y luego escalar a blanco o negro (lo que sea más cercano).

Original:

miau miau atado gato

Resultado:

Gato blanco y negro, puro

Implementación de Pure Pillow

Instale la pillow si aún no lo ha hecho:

 $ pip install pillow 

La almohada (o PIL) puede ayudarlo a trabajar con imágenes de manera efectiva.

 from PIL import Image col = Image.open("cat-tied-icon.png") gray = col.convert('L') bw = gray.point(lambda x: 0 if x<128 else 255, '1') bw.save("result_bw.png") 

Alternativamente, puede utilizar almohada con numpy .

Almohada + Numpy Bitmasks Enfoque

Necesitarás instalar numpy:

 $ pip install numpy 

Numpy necesita una copia de la matriz para operar, pero el resultado es el mismo.

 from PIL import Image import numpy as np col = Image.open("cat-tied-icon.png") gray = col.convert('L') # Let numpy do the heavy lifting for converting pixels to pure black or white bw = np.asarray(gray).copy() # Pixel range is 0...255, 256/2 = 128 bw[bw < 128] = 0 # Black bw[bw >= 128] = 255 # White # Now we put it back in Pillow/PIL land imfile = Image.fromarray(bw) imfile.save("result_bw.png") 

Blanco y negro usando almohada, con dithering

Usando una almohada puedes convertirla directamente a blanco y negro. Parecerá que tiene tonos de gris, ¡pero tu cerebro te está engañando! (Blanco y negro cerca uno del otro se ven como gris)

 from PIL import Image image_file = Image.open("cat-tied-icon.png") # open colour image image_file = image_file.convert('1') # convert image to black and white image_file.save('/tmp/result.png') 

Original:

miau miau color gato

Convertido:

miau miau gato blanco y negro

Blanco y negro utilizando almohada, sin dithering.

 from PIL import Image image_file = Image.open("cat-tied-icon.png") # open color image image_file = image_file.convert('1', dither=Image.NONE) # convert image to black and white image_file.save('/tmp/result.png') 

Yo sugeriría convertir a escala de grises, luego simplemente aplicar un umbral (a mitad de camino, o media o meadiana, si así lo desea).

 from PIL import Image col = Image.open('myimage.jpg') gry = col.convert('L') grarray = np.asarray(gry) bw = (grarray > grarray.mean())*255 imshow(bw) 
 img_rgb = cv2.imread('image.jpg') img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) (threshi, img_bw) = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) 

Almohada, con dithering

Usando una almohada puedes convertirla directamente a blanco y negro. Parecerá que tiene tonos de gris, ¡pero tu cerebro te está engañando! (Blanco y negro cerca uno del otro se ven como gris)

 from PIL import Image image_file = Image.open("cat-tied-icon.png") # open colour image image_file = image_file.convert('1') # convert image to black and white image_file.save('/tmp/result.png') 

Original:

miau miau color gato

Convertido:

miau miau gato blanco y negro

Y puede usar colorsys (en la biblioteca estándar) para convertir rgb a hls y usar el valor de luminosidad para determinar el blanco / negro:

 import colorsys # convert rgb values from 0-255 to % r = 120/255.0 g = 29/255.0 b = 200/255.0 h, l, s = colorsys.rgb_to_hls(r, g, b) if l >= .5: # color is lighter result_rgb = (255, 255, 255) elif l < .5: # color is darker result_rgb = (0,0,0) 

Usando opencv puedes convertir fácilmente rgb a imagen binaria

 import cv2 %matplotlib inline import matplotlib.pyplot as plt from skimage import io from PIL import Image import numpy as np img = io.imread('http://www.bogotobogo.com/Matlab/images/MATLAB_DEMO_IMAGES/football.jpg') img = cv2.cvtColor(img, cv2.IMREAD_COLOR) imR=img[:,:,0] #only taking gray channel print(img.shape) plt.imshow(imR, cmap=plt.get_cmap('gray')) #Gray Image plt.imshow(imR) plt.title('my picture') plt.show() #Histogram Analyze imgg=imR hist = cv2.calcHist([imgg],[0],None,[256],[0,256]) plt.hist(imgg.ravel(),256,[0,256]) # show the plotting graph of an image plt.show() #Black And White height,width=imgg.shape for i in range(0,height): for j in range(0,width): if(imgg[i][j]>60): imgg[i][j]=255 else: imgg[i][j]=0 plt.imshow(imgg)