如何在opencv中实现不同程度的锐化

考虑到网友们中有急急国王,先上代码:

def sharpen(img, sharpness=100, ktype=1):
  n = sharpness/100
  if ktype == 1:
    sharpen_op = np.array([[0 ,  -n,   0 ], \
                           [-n, 4*n+1, -n], \
                           [0 ,  -n,   0 ]], dtype=np.float32)
  if ktype == 2:
    sharpen_op = np.array([[-n,  -n,   -n], \
                           [-n, 8*n+1, -n], \
                           [-n,  -n,   -n]], dtype=np.float32)
  img_sharpen = cv2.filter2D(img, cv2.CV_32F, sharpen_op)
  img_sharpen = cv2.convertScaleAbs(img_sharpen)
  return img_sharpen

其中:
img是opencv图像
sharpness是0~100的数字,代表锐化程度
注:理论上讲,sharpness可以超过100
再注:100是我定义的,你可以更改上限,将上述代码中的n = sharpness/100中的100换成别的数字即可
ktype是锐化卷积核类型,可以取1和2,默认使用第一种,哪种好我也不知道,但很棒的是,你可以都试试!
返回结果是锐化后的图像
使用例:img_sharpen_cv = sharpen(img_cv, sharpness=25) #锐化

为什么

网上的教程大多会告诉你,首先用numpy捏这么一个卷积核:

    sharpen_op = np.array([[0 , -1,  0], \
                           [-1,  5, -1], \
                           [0 , -1,  0]], dtype=np.float32)
#或者这种
    sharpen_op = np.array([[-1, -1, -1], \
                           [-1,  9, -1], \
                           [-1, -1, -1]], dtype=np.float32)

然后把它和原图一起扔进cv2.filter2D,图像就被锐化啦!
图像是被锐化了,但是不是锐的有点太过了?
大多数人肯定用过手机图库自带的锐化处理功能,他会给你一个滑动条,你把这个条拉大,它就多锐化,拉小,它就少锐化。
刚才锐化的图像,如果你像我一样会闲着没事拉那个条玩,看看不同的锐化效果,你就会发现,那个效果就跟条拉满差不多。

我超,天才!

这时一位天才的网友出现:看起来中心那个数是关键啊!那我直接把中心那个数改了不就完事了!(真的有这位网友,只不过他的帖子我不在此提及)
于是他改了那个数,得意洋洋地说,他解决了需求,然而他附了一张结果的动图,你看他的动图就会发现,当他拖动滑动条改动核中间的数值时,整个图片只能说是dramatical change,只有这个数字在5(第二种是8)左右的时候,图片才是相对正常的。
这位天才做了勇敢的尝试,但是他没试对。依照经验,一个问题蒙不对,就得学一学了。

什么是卷积

作为一名高中生,我没背过这个概念,所以没法做准确的描述,但是我会解释:

    sharpen_op = np.array([[0 , -1,  0], \
                           [-1,  5, -1], \
                           [0 , -1,  0]], dtype=np.float32)

以这个卷积核为例,他的意思是图像上每个像素点都取:自己的5倍+上下左右四个像素的-1倍

    sharpen_op = np.array([[-1, -1, -1], \
                           [-1,  9, -1], \
                           [-1, -1, -1]], dtype=np.float32)

同理,这个的意思是,图像上每个像素点都取:自己的9倍+周围一圈像素像素的-1倍

为什么锐化卷积核能锐化

一篇讲得比较正经的博客提到,锐化卷积核中所有数字的和应该是1。为什么和是1?其实我们把上面的意思变换一下就知道了:
自己的5倍+上下左右四个像素的-1倍 == 自己+(自己-上)+(自己-下)+(自己-左)+(自己-右)
这就是锐化卷积核的原理:把每个像素加上自己和周围几个像素的差,就能起到锐化效果(虽然我也不知道为什么)

真正的合理外推

当我们成功整会了以上内容,我们就知道怎么锐化得有个“度”了:
自己+(自己-上)+(自己-下)+(自己-左)+(自己-右) -> 100%的锐化
自己 -> 不锐化,即0%的锐化
因此:
自己+(自己-上)*n%+(自己-下)*n%+(自己-左)*n%+(自己-右)*n% -> n%的锐化
写成卷积核就是开头的代码:

    sharpen_op = np.array([[0 ,  -n,   0 ], \
                           [-n, 4*n+1, -n], \
                           [0 ,  -n,   0 ]], dtype=np.float32)

再加上前后必要的代码,完成!

你可能感兴趣的:(经验,opencv,计算机视觉,python)