I have a binary image (white and black), the where Region of Interest (ROI) is black. The shape of ROI is irregular and the location of ROI can be anywhere in the frame.
I want to have a smooth gradation at the edge of the ROI (black -> dark grey -> grey -> light grey -> white).
I research the links below, however those cannot solve my problem:
- How to blur some portion of Image in Android?
- OpenCV - How to achieve a gradual image blur effect?
- Combining 2 images with transparent mask in opencv
- Gradient mask blending in opencv python
Example of ROI - original image, the REAL Shape is irregular and Location is anywhere:
Expected result - in the edge of ROI the is gradation part changing from stright line to dash line: black -> dark grey -> grey -> light grey -> white:
Here is one way to do that for an outer gradient in Python/OpenCV.
- Read the input- Convert to grayscale- Threshold to binary- Apply a distance transform- Stretch it to full dynamic range- Stretch to limit the gradient to a short distance around the rectangle- Save the output
Input:
import cv2
import numpy as np
import skimage.exposure# read image
img = cv2.imread('rect_black.jpg')# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# threshold to binary
thresh = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY)[1]# apply distance transform
distimg = cv2.distanceTransform(thresh, cv2.DIST_L2, 3)# scale distance image to full dynamic range
distimg = skimage.exposure.rescale_intensity(distimg, in_range='image', out_range=(0,255)).astype(np.uint8)# scale distance image to form limited gradient border
result = skimage.exposure.rescale_intensity(distimg, in_range=(0,25), out_range=(0,255)).astype(np.uint8)# save result
cv2.imwrite('rect_black_distance.png',distimg)
cv2.imwrite('rect_black_result.png',result)# show the images
cv2.imshow("distance", distimg)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Stretched Distance Image:
Result:
Note: In place of the distance transform, one could just use a Gaussian blur.