Search code examples
pythonimage-processingscikit-imageimage-thresholding

Using Skimage adaptive thresholding on an image and getting the output


I am trying to use scikit-image's adaptive threshold on my image. I tested out their sample code from HERE

import matplotlib.pyplot as plt

from skimage import data
from skimage.filters import threshold_otsu, threshold_adaptive


image = data.page()

global_thresh = threshold_otsu(image)
binary_global = image > global_thresh

block_size = 35
binary_adaptive = threshold_adaptive(image, block_size, offset=10)

fig, axes = plt.subplots(nrows=3, figsize=(7, 8))
ax0, ax1, ax2 = axes
plt.gray()

ax0.imshow(image)
ax0.set_title('Image')

ax1.imshow(binary_global)
ax1.set_title('Global thresholding')

ax2.imshow(binary_adaptive)
ax2.set_title('Adaptive thresholding')

for ax in axes:
    ax.axis('off')

plt.show()

The code takes in a sample image, thresholds it and shows it using plt. However, I am trying to retrieve the numpy array of the thresholded image. When I tried using cv2.imwrite on the variable binary_global, it does not work. When printing out binary_global--it is actually an array consisting of False and True values rather than numbers. I am not sure how plt can use that and produce an image. Regardless, how can I threshold the image and retrieve the new thresholded image's array with the RGB values?


Solution

  • You first need convert the scikit image to opencv to be able to use cv2.imwrite().

    Add the following changes-

    from skimage import img_as_ubyte
    import matplotlib.pyplot as plt
    from skimage import data
    from skimage.filters import threshold_otsu, threshold_adaptive
    import cv2
    
    
    image = data.page()
    
    global_thresh = threshold_otsu(image)
    binary_global = image > global_thresh
    
    block_size = 35
    binary_adaptive = threshold_adaptive(image, block_size, offset=10)
    
    fig, axes = plt.subplots(nrows=3, figsize=(7, 8))
    ax0, ax1, ax2 = axes
    plt.gray()
    
    ax0.imshow(image)
    ax0.set_title('Image')
    
    ax1.imshow(binary_global)
    ax1.set_title('Global thresholding')
    
    ax2.imshow(binary_adaptive)
    ax2.set_title('Adaptive thresholding')
    
    for ax in axes:
        ax.axis('off')
    
    plt.show()
    img = img_as_ubyte(binary_global)
    cv2.imshow("image", img)
    cv2.waitKey(0)
    

    You can then use the img for writing etc.