User12049279432
User12049279432

Reputation: 61

convert image (np.array) to binary image

Thank you for reading my question.

I am new to python and became interested in scipy. I am trying to figure out how I can make the image of the Racoon (in scipy misc) to a binary one (black, white). This is not taught in the scipy-lecture tutorial.

This is so far my code:

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np 
from scipy import misc  #here is how you get the racoon image

face = misc.face()
image = misc.face(gray=True)
plt.imshow(image, cmap=plt.cm.gray)
print image.shape 

def binary_racoon(image, lowerthreshold, upperthreshold):
    img = image.copy()
    shape = np.shape(img)

    for i in range(shape[1]):
        for j in range(shape[0]): 
             if img[i,j] < lowerthreshold and img[i,j] > upperthreshold:
                 #then assign black to the pixel
             else:
                 #then assign white to the pixel

    return img

    convertedpicture = binary_racoon(image, 80, 100) 
    plt.imshow(convertedpicture, cmap=plt.cm.gist_gray)

I have seen other people using OpenCV to make a picture binary, but I am wondering how I can do it in this way by looping over the pixels? I have no idea what value to give to the upper and lower threshold, so I made a guess of 80 and 100. Is there also a way to determine this?

Upvotes: 6

Views: 30288

Answers (3)

duhaime
duhaime

Reputation: 27611

In case anyone else is looking for a quick minimal example to experiment with, here's what I used to binarize an image:

from scipy.misc import imread, imsave

# read in image as 8 bit grayscale
img = imread('cat.jpg', mode='L')

# specify a threshold 0-255
threshold = 150

# make all pixels < threshold black
binarized = 1.0 * (img > threshold)

# save the binarized image
imsave('binarized.jpg', binarized)

Input:

enter image description here

Output:

enter image description here

Upvotes: 4

James
James

Reputation: 36746

You don't need to iterate over the x and y positions of the image array. Use the numpy array to check if the array is above of below the threshold of interest. Here is some code that produces a boolean (true/false) array as the black and white image.

# use 4 different thresholds
thresholds = [50,100,150,200]

# create a 2x2 image array
fig, ax_arr = plt.subplots(2,2)

# iterate over the thresholds and image axes
for ax, th in zip(ax_arr.ravel(), thresholds):
    # bw is the black and white array with the same size and shape
    # as the original array.  the color map will interpret the 0.0 to 1.0 
    # float array as being either black or white.
    bw = 1.0*(image > th)
    ax.imshow(bw, cmap=plt.cm.gray)
    ax.axis('off')

# remove some of the extra white space
fig.tight_layout(h_pad=-1.5, w_pad=-6.5)

enter image description here

Upvotes: 1

Eric
Eric

Reputation: 97661

You're overthinking this:

def to_binary(img, lower, upper):
    return (lower < img) & (img < upper)

In numpy, the comparison operators apply over the whole array elementwise. Note that you have to use & instead of and to combine the booleans, since python does not allow numpy to overload and

Upvotes: 3

Related Questions