opencv python中的渐变蒙版混合

01g*_*t13 3 python opencv mask image-processing

我有一个图像和圆形区域。我需要模糊所有,除了圆形区域。另外我需要使圆的边界平滑。
输入: 输入

输出(在带有掩码的图像编辑器中制作,但我认为 opencv 仅使用位图掩码):
输出

现在我在 python 中有代码,它不会模糊圆圈的边界。

def blur_image(cv_image, radius, center, gaussian_core, sigma_x):
    blurred = cv.GaussianBlur(cv_image, gaussian_core, sigma_x)
    h, w, d = cv_image.shape
# masks
    circle_mask = np.ones((h, w), cv_image.dtype)
    cv.circle(circle_mask, center, radius, (0, 0, 0), -1)
    circle_not_mask = np.zeros((h, w), cv_image.dtype)
    cv.circle(circle_not_mask, center, radius, (2, 2, 2), -1)
# Computing
    blur_around = cv.bitwise_and(blurred, blurred, mask=circle_mask)
    image_in_circle = cv.bitwise_and(cv_image, cv_image, mask=circle_not_mask)
    res = cv.bitwise_or(blur_around, image_in_circle)
    return res
Run Code Online (Sandbox Code Playgroud)

当前版本:
在此处输入图片说明 如何模糊圆圈的边界?在输出示例中,我在程序中使用了渐变掩码。opencv 中有类似的东西吗?
更新 04.03
所以,我已经尝试过这个回答主题的公式以及我所拥有的:
另一个尝试
代码:

def blend_with_mask_matrix(src1, src2, mask):
    res = src2 * (1 - cv.divide(mask, 255.0)) + src1 * cv.divide(mask, 255.0)
return res
Run Code Online (Sandbox Code Playgroud)

这段代码应该与最近的代码类似,但事实并非如此。圆圈中的图像略有不同。它有一些颜色问题。这个问题仍然悬而未决。

Kin*_*t 金 7

我想也许你想要这样的东西。

这是源图像

在此处输入图片说明

所述源所迷离配对在此处输入图片说明

所述掩模alphablened配对

在此处输入图片说明


代码注释中带有描述的代码。

#!/usr/bin/python3
# 2018.01.16 13:07:05 CST
# 2018.01.16 13:54:39 CST
import cv2
import numpy as np

def alphaBlend(img1, img2, mask):
    """ alphaBlend img1 and img 2 (of CV_8UC3) with mask (CV_8UC1 or CV_8UC3)
    """
    if mask.ndim==3 and mask.shape[-1] == 3:
        alpha = mask/255.0
    else:
        alpha = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)/255.0
    blended = cv2.convertScaleAbs(img1*(1-alpha) + img2*alpha)
    return blended

img = cv2.imread("test.png")

H,W = img.shape[:2]
mask = np.zeros((H,W), np.uint8)
cv2.circle(mask, (325, 350), 40, (255,255,255), -1, cv2.LINE_AA)
mask = cv2.GaussianBlur(mask, (21,21),11 )

blured = cv2.GaussianBlur(img, (21,21), 11)

blended1 = alphaBlend(img, blured, mask)
blended2 = alphaBlend(img, blured, 255- mask)

cv2.imshow("blened1", blended1);
cv2.imshow("blened2", blended2);
cv2.waitKey();cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

一些有用的链接:

  1. OpenCV C++ 中的 Alpha 混合:在 opencv 中将 2 个图像与透明蒙版相结合

  2. OpenCV Python 中的 Alpha 混合: opencv python 中的渐变蒙版混合


01g*_*t13 3

所以主要问题(mask/255) * blur + (1-mask/255)*another img是运营商。他们只使用一个渠道。下一个问题是使用浮点数进行“平滑”。
我已将与 Alpha 通道混合的代码更改为:
1) 我将每个通道用作源图像和蒙版
2) 执行公式
3) 合并通道

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
Run Code Online (Sandbox Code Playgroud)

作为渐变蒙版,我只是使用模糊圆圈。

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
Run Code Online (Sandbox Code Playgroud)

结果:

结果 它的工作速度比第一个版本慢一些,没有更平滑的边框,但没关系。
结束语。