Feature extraction and take color histogram

According to this article https://www.pyimagesearch.com/2016/04/11/finding-extreme-points-in-contours-with-opencv/ and this question CV - Extract differences between two images

I wrote some python code as below. As my predecessor said it is also far from perfect. The main disadvantages of this code are constants value to set manually: minThres (50), maxThres(100), dilate iteration count and erode iteration count.

import cv2
import numpy as np

windowName = "Edges"
pictureRaw = cv2.imread("bird.jpg")

## set to gray
pictureGray = cv2.cvtColor(pictureRaw,  cv2.COLOR_BGR2GRAY)

## blur
pictureGaussian = cv2.GaussianBlur(pictureGray, (7,7), 0)

## canny edge detector - you must specify threshold values
pictureCanny = cv2.Canny(pictureGaussian, 50, 100)

## perform a series of erosions + dilations to remove any small regions of noise
pictureDilate = cv2.dilate(pictureCanny, None, iterations=20)
pictureErode = cv2.erode(pictureDilate, None, iterations=5)

## find the nozero regions in the erode
imask2 = pictureErode>0

## create a Mat like pictureRaw
canvas = np.full_like(pictureRaw, np.array([255,0,0]), dtype=np.uint8)

## set mask 
canvas[imask2] = pictureRaw[imask2]
cv2.imwrite("result.png", canvas)

  1. Identify the edges of your imageSobel edge map

  2. Binarize the image via automatic thresholdingbinarized edge map

  3. Use contour detection to identify black regions which are inside a white region and merge them with the white region. (Mockup, image may slightly vary) Mockup of the merged mask

  4. Use the created image as mask to color the background and color it final image This can be done by simply setting each background pixel (black) to its respective color.

As you can see, the approach is far from perfect, but should give you a general idea about how to accomplish your task. The final image quality might be improved by slightly eroding the map to tighten it to the contours of the bird. You then also use the mask to calculate your color histogram by only taking foreground pixels into account. Edit: Look here:

  1. Eroded mask

eroded mask

  1. Final image

Final image with eroded mask