You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV实现以指定焦点为中心的渐进式模糊效果技术咨询

实现焦点渐进模糊的OpenCV思路

核心逻辑

要实现连续平滑的渐进模糊,核心是让每个像素的模糊程度与它到指定焦点的距离正相关,避免生硬的区域划分。通过生成多级模糊图像+平滑权重融合的方式,既能保证效率,又能实现无断层的模糊过渡。

具体步骤

  • 计算距离映射:以焦点坐标为中心,计算图像每个像素到焦点的欧氏距离,再将距离归一化后映射到模糊核的尺寸范围(注意OpenCV高斯模糊核必须是奇数)。这里用平滑的线性映射,也可以根据需求调整映射曲线(比如平方曲线让模糊递增更快)。
  • 生成多级模糊图:对原图做不同程度的高斯模糊,核大小从1(原图)到设定的最大核尺寸,步长为2(保证奇数),得到一组模糊程度依次递增的图像。
  • 构建平滑权重图:根据每个像素的距离对应的核尺寸,计算它在相邻两级模糊图之间的权重比例,确保模糊过渡无断层。
  • 融合模糊图像:按照权重图将多级模糊图像加权融合,得到最终的渐进模糊效果。

代码示例(Python + OpenCV)

import cv2
import numpy as np

def progressive_blur(img, focus_x, focus_y, max_kernel_size=31):
    # 确保最大模糊核为奇数
    if max_kernel_size % 2 == 0:
        max_kernel_size += 1
    
    h, w = img.shape[:2]
    # 生成每个像素到焦点的欧氏距离图
    y_grid, x_grid = np.mgrid[:h, :w]
    distances = np.sqrt((x_grid - focus_x)**2 + (y_grid - focus_y)**2)
    
    # 归一化距离并映射到模糊核的半长(核大小=2*k+1)
    max_dist = np.max(distances)
    normalized_dist = distances / max_dist
    k_values = normalized_dist * ((max_kernel_size - 1) // 2)
    
    # 生成不同模糊级别的图像
    blur_imgs = []
    kernel_sizes = range(1, max_kernel_size + 1, 2)
    for k in kernel_sizes:
        blur_imgs.append(cv2.GaussianBlur(img, (k, k), 0))
    
    # 初始化结果图像
    result = np.zeros_like(img, dtype=np.float32)
    
    # 融合相邻模糊级别
    for i in range(len(kernel_sizes) - 1):
        current_k = (kernel_sizes[i] - 1) // 2
        next_k = (kernel_sizes[i+1] - 1) // 2
        # 筛选当前区间内的像素
        mask = (k_values >= current_k) & (k_values < next_k)
        if not np.any(mask):
            continue
        # 计算融合权重
        weight = (k_values[mask] - current_k) / (next_k - current_k)
        # 适配彩色图像的通道维度
        if img.ndim == 3:
            weight = np.expand_dims(weight, axis=-1)
        # 加权融合
        result[mask] = (1 - weight) * blur_imgs[i][mask] + weight * blur_imgs[i+1][mask]
    
    # 处理最大模糊级别的区域
    mask = k_values >= ((max_kernel_size - 1) // 2)
    result[mask] = blur_imgs[-1][mask]
    
    return result.astype(np.uint8)

# 测试用法
if __name__ == "__main__":
    img = cv2.imread("test.jpg")
    # 假设焦点在图像中心
    focus_x = img.shape[1] // 2
    focus_y = img.shape[0] // 2
    blurred_img = progressive_blur(img, focus_x, focus_y, max_kernel_size=31)
    cv2.imwrite("progressive_blur.jpg", blurred_img)

优化建议

  • 效率优化:如果处理大尺寸图像,可以先对图像降采样,处理后再升采样,减少计算量。
  • 模糊类型调整:用cv2.bilateralFilter代替高斯模糊,能在模糊的同时保留图像边缘,效果更自然。
  • 映射曲线调整:修改距离到核尺寸的映射方式,比如用k_values = np.square(normalized_dist) * ...让模糊递增速率先慢后快,或者用平方根曲线让速率先快后慢,适配不同视觉需求。

内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 16:20:27