用opencv-python实现能线性调整的模糊、锐化

现在的手机图库中,模糊和锐化是必不可少的两个功能。
然而,各位应该都有注意到:在opencv中,锐化和模糊的主要参数都是卷积核半径,且必须为奇数;但是在使用图库软件时,大部分时候只需要拖动一个滑动条。或许“滑动条”的说法不够明显,更直观的说法是:图库软件的模糊和锐化只需要一个浮点数做参数。

显然,图库软件的开发者不可能重复造轮子,他们用的模糊和锐化,底层必然和opencv相似。本文讲的就是如何在opencv中实现这样一个以浮点数控制操作力度的锐化或模糊。本文的思路也适用于其他卷积操作,如USM。

连续与不连续

卷积核半径是不连续的,而操作力度是连续的
也就是说,虽然我们可以建立这样一个映射,但是非整数的操作力度并不直接对应任意一个卷积核卷积的结果。

操作力度卷积核半径
13
25
37

我想到的解决方法是:线性混合。按比例混合两个卷积核卷积的结果,就能表示小数的操作力度。

实现

首先将线性混合封装成函数

def gen_kparams(degree):
    # 根据参数“degree”生成两个内核半径和它们的混合比例
    assert degree>0
    deg_head = math.ceil(degree)
    deg_tail = degree+1-deg_head
    ksize_large = deg_head*2+1
    ksize_small = ksize_large-2
    large_ratio = deg_tail
    small_ratio = 1-large_ratio
    return ksize_large, large_ratio, ksize_small, small_ratio

def get_filtered(img, filter_func, degree):
    # 根据生成的参数处理图片并混合
    ksize_large, large_ratio, ksize_small, small_ratio = gen_kparams(degree)
    large = filter_func(img, ksize_large)
    small = filter_func(img, ksize_small)
    ret = cv2.addWeighted(large, large_ratio, small, small_ratio, 0)
    return ret

然后加入具体的操作

gaussian_filter = lambda img, ksize: cv2.GaussianBlur(img, (ksize, ksize), 0)
laplacian_filter = lambda img, ksize: cv2.Laplacian(img, -1, ksize=ksize)

def blur(img, degree=1):
    ret = get_filtered(img, gaussian_filter, degree)
    return ret
def sharpen(img, degree=1):
    ret = cv2.subtract(img, get_filtered(img, laplacian_filter, degree))
    return ret
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值