算法步骤
全局二值化容易受阴影影响,所以可以局部二值化。自适应阈值分割的本质就是局部二值化。
具体操作步骤如下:
(1) 对某个像素值,原来为 \(S\),取其周围的 \(n\times n\) 的区域,求区域均值或高斯加权值,记为 \(T\);
(2) 对 \(8\) 位图像,如果 \(S > T\),则该像素点二值化为 \(255\), 否则为 \(0\)。
优化:
(1) 在实际操作中,通过卷积操作,即均值模糊或高斯模糊,实现求区域均值或高斯加权值;
(2) 上面步骤中,增加超参数 \(C\),\(C\) 可以为任何实数,当 \(S > T- C\) 时,把原像素二值化为 \(255\)。
(3) 也可以设置超参数 \(\alpha\in [0,1]\),当 \(S > (1-\alpha) T\) 时把原像素点二值化为 \(255\),通常取 \(\alpha=0.15\)。
效果
左图为原始灰度图,右图为自适应阈值化结果。
实现
1. 调用OpenCV函数
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread(img_path, 0) # img_path 为图像路径
img_bin = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,
cv.THRESH_BINARY, 21, 6)
plt.imshow(np.hstack([img, img_bin]), cmap='gray')
plt.show()
2. 自己实现
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread(img_path, 0) # img_path 换为图片路径
C = 6
winSize = 21
img_blur = cv.blur(img, (winSize, winSize))
img_bin = np.uint8(img > img_blur.astype(np.int) - C) * 255 # 此时的 img_bin 即为最终阈值化结果
3. 自己实现(方法二)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread(img_path, 0) # img_path 换为图片路径
alpha = 0.05
winSize = 21
img_blur = cv.GaussianBlur(img, (winSize, winSize), 5)
img_bin = np.uint8(img > (1 - alpha) * img_blur) * 255 # 此时的 img_bin 即为最终阈值化结果
说明:
- 未经许可,谢绝转载。
- 本教程为《数字图像处理Python OpenCV实战》的配套代码相关内容。
免费视频教程为0-6章(标题号≤6),可在此处点击观看。
所有课件及源代码可在此处下载:
链接:https://pan.baidu.com/s/198PySe_vebO3e06idHSQ6g
提取码:11o4
有问题可在QQ群(1079300899)指出,进群答案:数字图像处理。在本文评论指出可能导致回复很晚。