Gradient mask blending in opencv python

前端 未结 3 568
[愿得一人]
[愿得一人] 2020-12-17 06:17

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

3条回答
  •  旧巷少年郎
    2020-12-17 06:30

    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.

提交回复
热议问题