I am working on an image processing feature extraction. I have a photo of a bird in which I have to extract bird area and tell what color the bird has. I used canny feature extraction method to get the edges of a bird.
How to extract only bird area and make the background to blue color?
openCv solution should also be fine.
import skimage import numpy as np %matplotlib inline import matplotlib.pyplot as plt import os filename = os.path.join(os.getcwd(),'image\image_bird.jpeg') from skimage import io bird =io.imread(filename,as_grey=True) plt.imshow(bird)
from skimage import feature edges = feature.canny(bird,sigma=1) plt.imshow(edges )
Actual bird image can be taken from bird link
2 Answers
Answers 1
Identify the edges of your image
Binarize the image via automatic thresholding
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)
Use the created image as mask to color the background and color it
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:
- Final image
Answers 2
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)
0 comments:
Post a Comment