Python OpenCV 图像的二值化操作再次学习与图像平滑处理(卷积处理)

网友投稿 1181 2022-05-29

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 44 篇。

基础知识铺垫

今天再去回顾 上一篇 写二值化操作的博客,内容还是稚嫩了一些,果然第一遍的学习只是掌握了一丢丢的皮毛,还有很多细节的知识点需要补充。

二值化学习迭代

首先还是对 cv2.theshold 函数进行学习,函数原型与参数基础部分,翻阅上篇博客即可,重点补充如下内容。

函数原型还是先参考一下:

retval, dst = cv2.threshold(src, thresh, maxval, type[, dst])

重点要说明的参数是 type,先回顾一下基本函数的基本使用代码,毕竟有代码才方便回顾内容:

import cv2 as cv import numpy as np src = cv.imread("./test.png") gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) retval, dst = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) image = np.hstack((gray, dst)) cv.imshow("image", image) cv.waitKey()

运行结果如下:

最后一个 type 参数是复习到的重点知识,它的取值影响了最终二值图的结果。

在看一下 type 取值常见的有如下 5 个,这 5 个还可以分为三组,分别是

THRESH_BINARY 与 THRESH_BINARY_INV;

THRESH_TRUNC;

THRESH_TOZERO 与 THRESH_TOZERO_INV。

第一组中的两个取值和第三组的两个含义相同,都是相反的关系,因此看一个参数值即可。

THRESH_BINARY 最常用的,表示当像素点的值大于阈值 thresh 就取 maxval 设置的颜色,一般将 thresh 设置为 127,将 maxval 设置为 255,那 THRESH_BINARY 就会把所有灰度值大于 127 的都设置为 255。这里注意二值化操作的是灰度图像,虽然传递彩色图像也起作用,但是做二值化的时候,一定要提前把彩色图像转换为二值图像才可。

THRESH_TOZERO 超过阈值的像素无变化,不大于的像素设置为 0,具体其实你进行一下简单尝试即可。

import cv2 as cv import numpy as np cv.namedWindow("image",cv.WINDOW_FREERATIO) src = cv.imread("./test.png") gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) retval1, dst1 = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) retval2, dst2 = cv.threshold(gray, 127, 255, cv.THRESH_TOZERO) image = np.hstack((dst1,dst2)) cv.imshow("image", image) cv.waitKey()

使用该办法,明显会看到有些地方的灰度值得到了保留,注意 THRESH_TOZERO 是超过阈值的像素无变化,未超过的设置为 0 。

与 THRESH_BINARY 对比之后得到的结论就是,黑的地方一起黑,白的地方你更白。

所以在使用 THRESH_TOZERO 的时候,写成下面这个样子也没有什么问题。

retval2, dst2 = cv.threshold(gray, 127, 0, cv.THRESH_TOZERO)

THRESH_TRUNC 截断阈值化,大于阈值部分设置为阈值,否则不变,测试代码如下:

retval1, dst1 = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) retval2, dst2 = cv.threshold(gray, 127, 0, cv.THRESH_TOZERO) retval3, dst3 = cv.threshold(gray, 127, 0, cv.THRESH_TRUNC) image = np.hstack((dst1,dst2,dst3))

对比之后,立马就能明白,THRESH_TRUNC 会把图片的灰度值上限设置成一个具体值,例如本案例中的 127。

图像平滑处理学习迭代

平滑处理即卷积操作,在 这篇博客 前后都有所涉及,再次学习的时候,我们将其进行一下补充。

在对图像进行去噪处理的时候,可以使用均值滤波,它是简单的平均卷积操作,关于卷积数学相关的之后,在稍微后放 10 几天的时间,在进行补充,因为接下来的内容很多地方都会有卷积,多学一些应用层的之后,再去复盘数学基础,就事半功倍了。

虽然不涉及数学原理,但是咱还需要对底层实现进行一下基本的认知的,为了方便实现,我采用一张手动生成的灰度图进行演示。

生成一张灰度图的代码:

import cv2 as cv import numpy as np # 生成一个10*10的灰度图片 src = np.random.randint(256,size=(10, 10),dtype=np.uint8) print(src) cv.imshow("src",src)

因为是随机生成的,输出的代码如下:

[[ 90 134 192 243 116 2 172 143 22 218] [192 145 171 125 175 138 64 232 90 160] [ 61 20 231 37 77 27 141 182 71 194] [136 86 10 239 196 137 192 243 47 40] [220 167 3 50 227 70 135 227 225 218] [207 10 213 134 249 157 179 112 58 78] [107 33 68 143 124 215 175 167 108 195] [ 32 227 43 249 61 168 230 180 82 47] [ 89 211 253 141 199 140 34 185 179 32] [ 18 98 109 92 37 13 200 102 97 218]]

均值滤波默认会选择一个 3x3 的卷积核,然后进行从左到右,从上到下的卷积操作。

上图红色的 137,就是进行均值滤波之后的结果,计算中心数字 145 周围的 9 个数字之和,然后再除以 9,得到 137,替换掉 145 。

但是该操作你也会发现一个问题,就是边缘是无法凑到卷积核 3x3 的,这里橡皮擦也查阅了相关资料,存在的解释就是边缘填充,也就是前几篇博客学习的内容,不过我进行尝试之后,发现结果并不理想,抽时间还是要查阅一下 OpenCV 的源码,核对一下到底是什么计算方式,不过核心的思路已经比较清楚了,均值就是计算平均值。

由于它是该卷积核取九个值的平均值代替中间像素值,所以最终的效果是平滑的,将其应用到具体图像上,呈现如下效果。

import cv2 as cv import numpy as np cv.namedWindow("image",cv.WINDOW_FREERATIO) src = cv.imread("./t1.jpg") gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) dst = cv.blur(gray,(3,3)) image = np.hstack((gray,dst)) cv.imshow("image", image) cv.waitKey()

卷积核大小设置成任意都是可以的,只不过建议设置为 3x3、5x5 这些奇数。

方框滤波

在之前的博客中貌似没有涉及方框滤波的内容,这里在进行一下补充,与均值滤波用法基本一致,函数原型如下:

Python OpenCV 图像的二值化操作再次学习与图像平滑处理(卷积处理)

dst = cv2.boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]])

可以选择是否进行归一化操作,具体代码可以运行下述内容:

# 归一化 dst = cv.boxFilter(gray,-1,(3,3),normalize=True) # 不做归一化 dst = cv.boxFilter(gray,-1,(3,3),normalize=False)

简单说,不做归一化操作,在使用 3x3 卷积核进行计算之后,不除以 9,像素越界,默认保留成 255,也就大白了。

高斯滤波就是增加了高斯分布相关的知识,或者增加了空间距离相关的概念,说白了就是像素周边的像素权重不同了。相比于均值滤波,高斯滤波有着更好的平滑效果。

中值滤波就是把卷积核覆盖的矩阵进行从小到大排序,然后取中值为目标图像的像素值。

橡皮擦的小节

希望今天的 1 个小时你有所收获,我们下篇博客见~

相关阅读

技术专栏

Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧

Python 爬虫小课,精彩 9 讲

今天是持续写作的第

86

/ 100 天。

如果你想跟博主建立亲密关系,可以关注同名公众号

梦想橡皮擦

,近距离接触一个逗趣的互联网高级网虫。

博主 ID:梦想橡皮擦,希望大家

评论

OpenCV Python 神经网络

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:关系数据库——基础
下一篇:再造一座深圳,需要哪几步?
相关文章