当前位置: 首页 > news >正文

skimage.filters.apply_hysteresis_threshold详解

本文内容均参考scipy1.9.1scipy1.9.1scipy1.9.1版本的源码,若有任何不当欢迎指出
我们截取官方注释如下:

def apply_hysteresis_threshold(image, low, high):"""Apply hysteresis thresholding to ``image``.This algorithm finds regions where ``image`` is greater than ``high``OR ``image`` is greater than ``low`` *and* that region is connected toa region greater than ``high``.Parameters----------image : array, shape (M,[ N, ..., P])Grayscale input image.low : float, or array of same shape as ``image``Lower threshold.high : float, or array of same shape as ``image``Higher threshold.Returns-------thresholded : array of bool, same shape as ``image``Array in which ``True`` indicates the locations where ``image``was above the hysteresis threshold.Examples-------->>> image = np.array([1, 2, 3, 2, 1, 2, 1, 3, 2])>>> apply_hysteresis_threshold(image, 1.5, 2.5).astype(int)array([0, 1, 1, 1, 0, 0, 0, 1, 1])References----------.. [1] J. Canny. A computational approach to edge detection.IEEE Transactions on Pattern Analysis and Machine Intelligence.1986; vol. 8, pp.679-698.:DOI:`10.1109/TPAMI.1986.4767851`"""

我一开始的时候只读到了这句话:

This algorithm finds regions where ``image`` is greater than ``high``OR ``image`` is greater than ``low`` *and* that region is connected toa region greater than ``high``.

我以为的是如果某一个区域的像素值如果在高低阈值之间,那么这个像素点就会被留下,但是不是这样的。这句话里面有一个重点地方为:

that region is connected to a region greater than ``high``.

这就表明了这个函数留下的有两种像素点:

  1. 超出最高阈值的
  2. 在低阈值与高阈值之间的像素点:如果这个点所在的low像素连通块(高低之间的)与高像素块有连接的话,那么这个像素块整体都会被保留

口说无凭,我们来看一下源码:

    low = np.clip(low, a_min=None, a_max=high)  # ensure low always below highmask_low = image > lowmask_high = image > high# Connected components of mask_lowlabels_low, num_labels = ndi.label(mask_low)# Check which connected components contain pixels from mask_highsums = ndi.sum(mask_high, labels_low, np.arange(num_labels + 1))connected_to_high = sums > 0thresholded = connected_to_high[labels_low]return thresholded

这一段代码看似简单,但里面有很多函数必须要理解其含义才能明白这一整个代码。
在这里为了简单起见,我们把这个low和high都设置成常数。比如,low=20,high=50;

    mask_low = image > lowmask_high = image > high

这两句是生成了一个mask_low和mask_high的bool矩阵,也就是True和False
接着往下看:

    labels_low, num_labels = ndi.label(mask_low)

这个函数是需要注意的。
在这里插入图片描述
这是官方文档中给出的示例,其实就是把每一个连通块进行标号,并且返回这个图里有几个连通块。
好,接下来来看这句话:

 sums = ndi.sum(mask_high, labels_low, np.arange(num_labels + 1))

小小的一句话却藏着很多机密,就是这一句话决定了我们前面说的那两种保留下来的像素点。
这个sum函数点进去之后是:

def sum(input, labels=None, index=None):"""Calculate the sum of the values of the array.Notes-----This is an alias for `ndimage.sum_labels` kept for backwards compatibilityreasons, for new code please prefer `sum_labels`.  See the `sum_labels`docstring for more details."""return sum_labels(input, labels, index)

这个sum_labels的官方文档是:
在这里插入图片描述
这里面的函数描述为:

Values of `input` inside the regions defined by `labels` are summed together.

这就意味着

 sums = ndi.sum(mask_high, labels_low, np.arange(num_labels + 1))

这句话的含义是统计Low(包含high)连通块上有多少个high,如果至少有一个,那么这个块将被保留。
至少我们得到的sums是全部连通块的high数量
应该形如
在这里插入图片描述
sums[i]表示第i个连通块的high数量。
接着往下看:

    connected_to_high = sums > 0

connected_to_high[i]就是表示第i个连通块是否与high相连,如果第i个连通块全是high的,那么一定保留,如果全是low,但是connected_to_high[i]>0,则保留,如果一半high一半low也保留,直接相连。
接下来的这一句话有点诡异,也为他是用矩阵做了索引。
但其实没啥,就是取得矩阵值做索引,然后把connected_to_high得值给放到相应位置上就可以了。

  thresholded = connected_to_high[labels_low]

label_low是连通块号,形状是图片形状。connected_to_high含义不再赘述。
返回的就是True False矩阵表示每个像素点是否被留下。
好了本文结束,感谢观看~

http://www.lryc.cn/news/45840.html

相关文章:

  • 一、基础算法5:前缀和与差分 模板题+算法模板(前缀和,子矩阵的和,差分,差分矩阵)
  • Python矩阵分解之QR分解
  • 随机森林程序
  • 每日一练2627——变态跳台阶快到碗里来不用加减乘除做加法三角形
  • LeetCode-146. LRU 缓存
  • #课程笔记# 电路与电子技术基础 课堂笔记 第3章 电路分析的几个定理
  • 推迟参数设计的自适应反步控制和自适应神经网络的反步控制设计
  • spring5.1+SmartInstantiationAwareBeanPostProcessor 解决循环依赖
  • apply、call与bind
  • 《Effective Objective-C 2.0 》 阅读笔记 item3
  • SSL/TLS 证书管理
  • supersqli(SQL注入流程及常用SQL语句)
  • 【数据结构】用Java实现一棵二叉树
  • 【面试】面试官问的几率较大的网络安全面试题
  • [Python] 循环语句
  • 计算机网络考试复习——第一章 1.5 1.6
  • 3.29 最小生成树算法
  • 计算机科班与培训开发编程的区别在哪里?
  • idea设置常用自设置快捷键及坐标
  • Vue 3.0 实例方法
  • 日撸 Java 三百行day1-10
  • Ubuntu Instant-ngp 训练自有数据集
  • k8s集群只一台节点,重启节点后命名空间找不到了
  • MarkDown示例
  • spring cloud 雪崩效应
  • Python 自动化指南(繁琐工作自动化)第二版:三、函数
  • c++多线程 1
  • STM32F103制作FlashDriver
  • springboot树形结构接口, 懒加载实现
  • java企业级信息系统开发学习笔记02初探spring——利用组件注解符精简spring配置文件