Search code examples
pythonimage-processingroi

Using python to select an area of an Image


I am trying to select an area of an image to do some analysis on that specific area of the image.

However, when I searched online, I am only able to find guides on how to select a rectangular area. I need to select an area that is drawn using my mouse. An example of such area is included bellow.

Would anyone be able to recommend to me some key words or libraries to search to help me with this or links to guides that do something similar?

Also, I am not sure if it is necessary information but the analysis I am trying to do on the region of interest is to Find a ratio of amount of white to black pixels in that specific area.

Example of an area I am trying to select


Solution

  • I produced a simple working example based on this answer. I also tried using scipy.ndimage.morphology.fill_binary_holes, but could not get it to work. Note that the provided function takes a little longer since it is assuming that the input image is grayscale and not binarized.

    I specifically avoided the usage of OpenCV, since I find the setup to be a bit tedious, but I think it should also provide an equivalent (see here).

    Additionally, my "binarization" is kind of hacky, but you can probably figure out how to parse your image into a valid format yourself (and it might be easier if you produce the result within a program). In any case, I would suggest making sure that you have a proper image format, since jpeg's compression might violate your connectivity, and cause issues in certain cases.

    import scipy as sp
    import numpy as np
    import scipy.ndimage
    import matplotlib.pyplot as plt
    
    def flood_fill(test_array,h_max=255):
        input_array = np.copy(test_array) 
        el = sp.ndimage.generate_binary_structure(2,2).astype(np.int)
        inside_mask = sp.ndimage.binary_erosion(~np.isnan(input_array), structure=el)
        output_array = np.copy(input_array)
        output_array[inside_mask]=h_max
        output_old_array = np.copy(input_array)
        output_old_array.fill(0)   
        el = sp.ndimage.generate_binary_structure(2,1).astype(np.int)
        while not np.array_equal(output_old_array, output_array):
            output_old_array = np.copy(output_array)
            output_array = np.maximum(input_array,sp.ndimage.grey_erosion(output_array, size=(3,3), footprint=el))
        return output_array
    
    x = plt.imread("test.jpg")
    # "convert" to grayscale and invert
    binary = 255-x[:,:,0]
    
    filled = flood_fill(binary)
    
    plt.imshow(filled)
    

    This produces the following result: final result