I have an image and circle zone. I need to blur all, except for circle zone. Also i need to make border of circle smooth.
The input:
The output(made it in image
So the main problem with (mask/255) * blur + (1-mask/255)*another img was operators. They were working only with one channel. Next problem is working with float numbers for "smoothing".
I've changed code of blending with alpha channel to this:
1) i'm taking every channel for source images and mask
2) Performing formula
3) Merging channels
def blend_with_mask_matrix(src1, src2, mask):
res_channels = []
for c in range(0, src1.shape[2]):
a = src1[:, :, c]
b = src2[:, :, c]
m = mask[:, :, c]
res = cv.add(
cv.multiply(b, cv.divide(np.full_like(m, 255) - m, 255.0, dtype=cv.CV_32F), dtype=cv.CV_32F),
cv.multiply(a, cv.divide(m, 255.0, dtype=cv.CV_32F), dtype=cv.CV_32F),
dtype=cv.CV_8U)
res_channels += [res]
res = cv.merge(res_channels)
return res
And as a gradient mask i'm just using blurred circle.
def blur_image(cv_image, radius, center, gaussian_core, sigma_x):
blurred = cv.GaussianBlur(cv_image, gaussian_core, sigma_x)
circle_not_mask = np.zeros_like(cv_image)
cv.circle(circle_not_mask, center, radius, (255, 255, 255), -1)
#Smoothing borders
cv.GaussianBlur(circle_not_mask, (101, 101), 111, dst=circle_not_mask)
# Computing
res = blend_with_mask_matrix(cv_image, blurred, circle_not_mask)
return res
Result:
It is working a bit slower than very first version without smoother borders, but it's ok.
Closing question.