Reputation: 2677
The following code, as explained here, effectively finds the contours of an object in an image, and fills those contours with white, while setting the background to black.
import cv2
import numpy as np
# Read image
im_in = cv2.imread('bee-02.png', cv2.IMREAD_GRAYSCALE)
th, im_th = cv2.threshold(im_in, 250, 255, cv2.THRESH_BINARY_INV)
# Copy the thresholded image.
im_floodfill = im_th.copy()
# Mask used to flood filling.
h, w = im_th.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
# Floodfill from point (0, 0)
cv2.floodFill(im_floodfill, mask, (0,0), 255)
# Invert floodfilled image
im_floodfill_inv = cv2.bitwise_not(im_floodfill)
# Combine the two images to get the foreground.
im_out = im_th | im_floodfill_inv
# Display images.
cv2.imshow("Foreground", im_out)
cv2.waitKey(0)
Here's an example of what it does:
What's a good way to augment the above code such that the exterior contours of the image are smoothed? If possible, I'd like to use a method that makes it possible to specify the gradation of the smoothing. I guess that one way to do it would be to apply heavy blurring before applying the masking function, but presumably, there's a better way.
Upvotes: 2
Views: 4256
Reputation: 10852
You can also make gaussian blur with large kernel (something like 7x7 or 15x15) before thresholding.
Upvotes: 1
Reputation: 15986
I would look into morphological opening and closing operations. Specifically I would try a morphological close with a nice big disc operator and you'll probably get something close to what you want.
They will operate directly on the binary data you've got (much less expensive than blurring) and will likely achieve the effect you're looking for in terms of simplifying or "blurring" the visual outline.
Upvotes: 3