44

How would I take an RGB image in Python and convert it to black and white? Not grayscale, I want each pixel to be either fully black (0, 0, 0) or fully white (255, 255, 255).

Is there any built-in functionality for getting it done in the popular Python image processing libraries? If not, would the best way be just to loop through each pixel, if it's closer to white set it to white, if it's closer to black set it to black?

4

8 回答 8

97

缩放为黑白

转换为灰度,然后缩放为白色或黑色(以最接近的为准)。

原来的:

喵喵绑猫

结果:

黑白猫,纯

纯枕头实现

pillow如果您还没有安装:

$ pip install pillow

Pillow(或 PIL)可以帮助您有效地处理图像。

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")

或者,您可以将Pillownumpy一起使用。

Pillow + Numpy 位掩码方法

您需要安装 numpy:

$ pip install numpy

Numpy 需要一个数组的副本来操作,但是结果是一样的。

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")

黑白使用 Pillow,带抖动

使用枕头,您可以将其直接转换为黑白。它看起来像有灰色阴影,但你的大脑在欺骗你!(黑色和白色靠近看起来像灰色)

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')

原来的:

喵喵色猫

转换:

喵喵黑白猫

黑白使用枕头,没有抖动

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')
于 2013-09-13T04:23:21.573 回答
5

我建议转换为灰度,然后简单地应用一个阈值(中间,或者平均值或中位数,如果你愿意的话)。

from PIL import Image

col = Image.open('myimage.jpg')
gry = col.convert('L')
grarray = np.asarray(gry)
bw = (grarray > grarray.mean())*255
imshow(bw)
于 2013-09-13T03:44:51.793 回答
3
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)
于 2018-11-02T10:26:45.663 回答
1

您可以使用colorsys(在标准库中)将 rgb 转换为hls并使用亮度值来确定黑/白:

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)
于 2013-09-13T17:30:40.957 回答
1

枕头,带抖动

使用枕头,您可以将其直接转换为黑白。它看起来像有灰色阴影,但你的大脑在欺骗你!(黑色和白色靠近看起来像灰色)

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')

原来的:

喵喵色猫

转换:

喵喵黑白猫

于 2013-09-13T03:50:36.780 回答
0

使用 opencv 可以轻松将 rgb 转换为二进制图像

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)
于 2018-06-06T19:29:46.513 回答
0

这是使用 opencv-python 创建二进制图像的代码:

img = cv2.imread('in.jpg',2)

ret, bw_img = cv2.threshold(img,127,255,cv2.THRESH_BINARY)

cv2.imshow("Output - Binary Image",bw_img)
于 2019-06-11T13:29:53.457 回答
0

如果您不想使用 cv 方法进行分割并了解您在做什么,请将 RGB 图像视为矩阵。

image = mpimg.imread('image_example.png') # your image
R,G,B = image[:,:,0], image[:,:,1], image[:,:,2] # the 3 RGB channels
thresh = [100, 200, 50] # example of triple threshold

# First, create an array of 0's as default value
binary_output = np.zeros_like(R)
# then screen all pixels and change the array based on RGB threshold.
binary_output[(R < thresh[0]) & (G > thresh[1]) & (B < thresh[2])] = 255

结果是基于三元组条件的 0 和 255 数组。

于 2020-05-07T10:54:01.510 回答