2012-02-29 69 views
32

Tôi đang sử dụng Thư viện hình ảnh Python cho thao tác hình ảnh rất đơn giản, tuy nhiên tôi gặp sự cố khi chuyển đổi hình ảnh màu xám sang đơn sắc (đen và trắng)) hình ảnh. Nếu tôi lưu sau khi thay đổi hình ảnh thành thang độ xám (chuyển đổi ('L')) thì hình ảnh sẽ hiển thị như bạn mong đợi. Tuy nhiên, nếu tôi chuyển đổi hình ảnh thành đơn sắc, hình ảnh một băng tần sẽ cho tôi biết tiếng ồn như bạn thấy trong hình bên dưới. Có một cách đơn giản để có một hình ảnh png màu sắc cho một hình ảnh màu đen và trắng tinh khiết bằng cách sử dụng PIL/python?Sử dụng python PIL để biến hình ảnh RGB thành hình ảnh đen trắng tinh khiết

from PIL import Image 
import ImageEnhance 
import ImageFilter 
from scipy.misc import imsave 
image_file = Image.open("convert_image.png") # open colour image 
image_file= image_file.convert('L') # convert image to monochrome - this works 
image_file= image_file.convert('1') # convert image to black and white 
imsave('result_col.png', image_file) 

Original Image Converted Image

+0

Từ [tài liệu PIL] ("http://.pythonware.com/library/pil/handbook/image.htm):" "" Khi chuyển đổi sang hình ảnh hai chiều (chế độ "1"), hình ảnh nguồn đầu tiên được chuyển thành màu đen và trắng. Giá trị kết quả lớn hơn 127 được đặt thành màu trắng và hình ảnh được hoà sắc. Để sử dụng các ngưỡng khác, hãy sử dụng phương pháp điểm. "" " Điều này nghe có liên quan, nhưng tôi ' m không quen thuộc với PIL và thao tác hình ảnh. – Darthfett

Trả lời

48
from PIL import Image 
image_file = Image.open("convert_image.png") # open colour image 
image_file = image_file.convert('1') # convert image to black and white 
image_file.save('result.png') 

sản lượng

enter image description here

+0

Cảm ơn vì điều này, tôi đã sử dụng imsave từ một đoạn mã khác - tôi đã không nhận ra đó sẽ là nguồn gốc của một vấn đề. – user714852

3

Xét xử của các kết quả thu được bằng cách unutbu tôi kết luận của scipy imsave mà không hiểu đơn sắc (mode 1) hình ảnh.

+0

Tôi nghi ngờ bạn là chính xác - rất lạ. – user714852

13

Một tùy chọn khác (đó là ví dụ hữu ích cho các mục đích khoa học khi bạn cần làm việc với mặt nạ Phân khúc) chỉ đơn giản là áp dụng một ngưỡng:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

"""Binarize (make it black and white) an image with Python.""" 

from PIL import Image 
from scipy.misc import imsave 
import numpy 


def binarize_image(img_path, target_path, threshold): 
    """Binarize an image.""" 
    image_file = Image.open(img_path) 
    image = image_file.convert('L') # convert image to monochrome 
    image = numpy.array(image) 
    image = binarize_array(image, threshold) 
    imsave(target_path, image) 


def binarize_array(numpy_array, threshold=200): 
    """Binarize a numpy array.""" 
    for i in range(len(numpy_array)): 
     for j in range(len(numpy_array[0])): 
      if numpy_array[i][j] > threshold: 
       numpy_array[i][j] = 255 
      else: 
       numpy_array[i][j] = 0 
    return numpy_array 


def get_parser(): 
    """Get parser object for script xy.py.""" 
    from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter 
    parser = ArgumentParser(description=__doc__, 
          formatter_class=ArgumentDefaultsHelpFormatter) 
    parser.add_argument("-i", "--input", 
         dest="input", 
         help="read this file", 
         metavar="FILE", 
         required=True) 
    parser.add_argument("-o", "--output", 
         dest="output", 
         help="write binarized file hre", 
         metavar="FILE", 
         required=True) 
    parser.add_argument("--threshold", 
         dest="threshold", 
         default=200, 
         type=int, 
         help="Threshold when to show white") 
    return parser 


if __name__ == "__main__": 
    args = get_parser().parse_args() 
    binarize_image(args.input, args.output, args.threshold) 

Nó trông giống như thế này cho ./binarize.py -i convert_image.png -o result_bin.png --threshold 200:

enter image description here

+3

Một lớp lót cho 'binarize_array' (nhanh hơn tôi cũng đoán): ' numpy.where (numpy_array> ngưỡng = 200, 255, 0) ' – Jacquot

+0

Điều này hoạt động hoàn hảo cho tìm kiếm google của tôi chỉ chuyển đổi hình ảnh thành đen trắng ... Cảm ơn! – LampShade

0

Bởi vì từ PIL convert("1") trả lại giá trị "Đúng" hoặc "Sai". Hãy thử in nó, sẽ được hiển thị: [False, False, True] với một dấu ngoặc đơn.

Trong khi mảng có nhiều mảng sử dụng khung đôi như thế này [[False, False, True]] hoặc [[0, 0, 1]], phải không?

2

Như Martin Thoma đã nói, bạn cần phải áp dụng bình thường thresholding. Nhưng bạn có thể làm điều này bằng cách sử dụng vector hóa đơn giản sẽ chạy nhanh hơn nhiều so với vòng lặp for được sử dụng trong câu trả lời đó.

Đoạn mã dưới đây chuyển đổi các pixel của hình ảnh thành 0 (màu đen) và 1 (màu trắng).

from PIL import Image 
import numpy as np 
import matplotlib.pyplot as plt 

#Pixels higher than this will be 1. Otherwise 0. 
THRESHOLD_VALUE = 200 

#Load image and convert to greyscale 
img = Image.open("photo.png") 
img = img.convert("L") 

imgData = np.asarray(img) 
thresholdedData = (imgData > THRESHOLD_VALUE) * 1.0 

plt.imshow(thresholdedData) 
plt.show() 
Các vấn đề liên quan