python-3.x - 使用 OpenCv 的阈值?
问题描述
正如问题所述,我想对我的图像应用双向自适应阈值技术。也就是说,我想找到邻域中的每个像素值,如果它小于或大于邻域的平均值减去常数 c,则将其设置为 255。
以这幅图像为例,作为像素的邻域。需要保留的像素区域是第三个和第六个正方形上半部分(从左到右和从上到下)的较暗区域,以及八个和十二个正方形的上半部分。
显然,这一切都取决于设定的常数值,但理想情况下,与邻域的平均像素值有显着差异的区域将被保留。不过,我可以自己担心调音。
解决方案
您的问题和评论是矛盾的:保持一切(显着)比邻域的平均值(+/- 常数)更亮/更暗(问题)与保持一切都在平均值 +/- 常数(评论)内。我认为第一个是正确的,我会尽力给出答案。
使用cv2.adaptiveThreshold
肯定是有用的;参数化可能很棘手,尤其是在示例图像的情况下。首先,让我们看一下输出:
我们看到,给定图像中的强度值范围很小。第三和第六方格的上半部分与他们的邻居并没有真正的不同。在那里很难找到适当的区别。方块#8 和#12 的上半部分(或方块#10 的下半部分)更有可能被发现。
顶行现在显示更多“全局”参数(blocksize = 151
, c = 25
),底行显示更多“局部”参数(blocksize = 51
, c = 5
)。中间列是比邻域更暗的所有内容(就参数而言),右列是比邻域更亮的所有内容。我们看到,在更“全局”的情况下,我们得到了正确的上半部分,但几乎没有“显着”的较暗区域。看,在更“本地”的情况下,我们看到一些较暗的区域,但我们不会找到有问题的完整上半部分/下半部分。那只是因为不同的三角形是如何排列的。
在技术方面:您需要两次调用cv2.adaptiveThreshold
,一次使用cv2.THRESH_BINARY_INV
mode 来找到更暗的东西,一次使用cv2.THRESH_BINARY
mode 来找到更亮的东西。此外,您必须为两种不同的情况提供c
或-c
。
这是完整的代码:
import cv2
from matplotlib import pyplot as plt
from skimage import io # Only needed for web grabbing images
plt.figure(1, figsize=(15, 10))
img = cv2.cvtColor(io.imread('https://i.stack.imgur.com/dA1Vt.png'), cv2.COLOR_RGB2GRAY)
plt.subplot(2, 3, 1), plt.imshow(img, cmap='gray'), plt.colorbar()
# More "global" parameters
bs = 151
c = 25
img_le = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, bs, c)
img_gt = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, bs, -c)
plt.subplot(2, 3, 2), plt.imshow(img_le, cmap='gray')
plt.subplot(2, 3, 3), plt.imshow(img_gt, cmap='gray')
# More "local" parameters
bs = 51
c = 5
img_le = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, bs, c)
img_gt = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, bs, -c)
plt.subplot(2, 3, 5), plt.imshow(img_le, cmap='gray')
plt.subplot(2, 3, 6), plt.imshow(img_gt, cmap='gray')
plt.tight_layout()
plt.show()
希望能有所帮助——不知何故!
-----------------------
System information
-----------------------
Python: 3.8.1
Matplotlib: 3.2.0rc1
OpenCV: 4.1.2
-----------------------
推荐阅读
- python - 如何使重复功能适用于我的不和谐机器人?
- go - golang 使用无痛查询更新 elasticsearch
- java - 尽管构建成功,但无法看到使用 Add-Lib API 的 Maven 项目的结果
- javascript - 一次删除多个 Firebase 侦听器
- python - 我在 pandas 中导入一个 CSV 文件,但该列作为多索引导入
- webi - 如何重新定义维度?
- android - 无法在导航抽屉按钮单击时显示吐司
- r - 如何将 df 从列表中分离出来
- java - Java 中使用 ArrayList 的年龄过滤器
- javascript - 如何使用 v-text-field 自动填充