pythonnumpyimage-processingscikit-imageomr

Scikit image color filtering and changing parts of image to array


I want to do some Optical Mark Recognition using scikit-image. I am looking for 2 functions

Lets say I have an image that looks like this:OMR

The way I would detect it is using filters to clean the image: (ie bilateral and Gaussian filtering for noise specks in filter module)

Then I would use a gray-scaling in color module Third I would use a canny edge detector in filter module

I am trying to find out what do I use to filter the cells by color so I can mark reds and blues apart?

I am guessing there is some function for Hues, saturation, and brightness or RGB that can be used to filter out specific colors or some thing that can be used with k-means from scikit learn for filtering data

Second is how would I transform this image to an numpy array/pandas dataframe which will be the following:

[[1,2,0,2,0]
[0,1,1,0,1]
[0,0,1,2,0]]

Where red is 1, blue is 2, and white is 0. I have seen some people put a line that goes down it but do not know what it is called or if it is available in sk-image.


Solution

  • The following code makes use of scikit-image's peak detector, applied on a distance map computed between the image and the values of pure red and blue:

    from skimage import io, color, img_as_float
    from skimage.feature import corner_peaks, plot_matches
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    image = img_as_float(io.imread('colordots.jpg'))
    
    black_mask = color.rgb2gray(image) < 0.1
    distance_red = color.rgb2gray(1 - np.abs(image - (1, 0, 0)))
    distance_blue = color.rgb2gray(1 - np.abs(image - (0, 0, 1)))
    
    distance_red[black_mask] = 0
    distance_blue[black_mask] = 0
    
    coords_red = corner_peaks(distance_red, threshold_rel=0.9, min_distance=50)
    coords_blue = corner_peaks(distance_blue, threshold_rel=0.9, min_distance=50)
    
    f, ((ax0, ax1), (ax2, ax3)) = plt.subplots(2, 2, figsize=(15, 10))
    ax0.imshow(image)
    ax0.set_title('Input image')
    ax1.imshow(image)
    ax1.set_title('Marker locations')
    ax1.plot(coords_red[:, 1], coords_red[:, 0], 'ro')
    ax1.plot(coords_blue[:, 1], coords_blue[:, 0], 'bo')
    ax1.axis('image')
    ax2.imshow(distance_red, interpolation='nearest', cmap='gray')
    ax2.set_title('Distance to pure red')
    ax3.imshow(distance_blue, interpolation='nearest', cmap='gray')
    ax3.set_title('Distance to pure blue')
    plt.show()
    

    Color dot detection