Search code examples
pythonopencvbackground-colorfeature-extractionfeature-detection

How to extract color features via histogram from a masked image?


I extracted an object from an image, so now I have a masked image with a tennis ball and a black background.

I want to extract the color features from the tennis ball alone via a histogram. This is the code I have so far, but by the looks of the histogram, the black background dominates the any of the other colors, which makes the histogram ineffective:

from PIL import Image
from pylab import *

# Import image and convert to gray
image = Image.open("res_300.png")
im = image.convert('L')
im_array = array(im)

# Create a new figure
figure()
gray()

# Show contours with origin upper left corner
contour(im, origin='image')
axis('equal')
axis('off')

# Create histogram
figure()
hist(im_array.flatten(), 128)
show()

Is there a way to draw the histogram from the tennis ball BGR color features while disregarding the black background?

I'm a python rookie. Thank you.


Solution

  • To split the color channels into BGR, we can use cv2.split() then use cv2.calcHist() to extract the color features with a histogram. To remove the dominant black background, we can set the range to [1, 256].

    enter image description here

    from matplotlib import pyplot as plt
    import cv2
    
    image = cv2.imread('1.png')
    
    channels = cv2.split(image)
    colors = ("b", "g", "r")
    
    plt.figure()
    plt.title("Color Histogram")
    plt.xlabel("Bins")
    plt.ylabel("# of Pixels")
    features = []
    
    # Loop over the image channels (B, G, R)
    for (channel, color) in zip(channels, colors):
    
        # Calculate histogram
        hist = cv2.calcHist([channel], [0], None, [255], [1, 256])
        features.extend(hist)
    
        # Plot histogram
        plt.plot(hist, color = color)
        plt.xlim([0, 256])
    
    plt.show()