python canny检测_【数字图像分析】基于Python实现 Canny Edge Detection(Canny 边缘检测算法)...

Canny 边缘检测算法

Steps:

高斯滤波平滑

计算梯度大小和方向

非极大值抑制

双阈值检测和连接

代码结构:

Canny Edge Detection

|Gaussian_Smoothing

||convolution.py

|||convolution()

||gaussion_smoothing.py

|||dnorm()

|||gaussian_kernel()

|||gaussian_blur()

|Sobel_Filter

||sobel.py

|||sobel_edge_detection()

|Canny.py

||non_max_suppression()

||threshold()

||hysteresis()

||main()

代码解读:

1. 高斯滤波平滑

创建一个高斯核(kernel_size=5):

424b3182d69b297bf1d2e2858e7be3b8.png

执行卷积和平均操作(以下均以 lenna 图为例)

b9208a7953ba61c8197278004557a23f.png

2. 计算梯度大小和方向

水平方向和竖直方向

e647d858d3c058a2476709f73092620a.png

0776b59681d7c456be59ca16f9f4b7c7.png

梯度图:

e8f2f50c886217f53cec52a83c8331e5.png

3. 非极大值抑制

121d6b4fe7566e93ccddd3a5ffab7dc8.png

4. 双阈值检测和连接

b1b7f658f69a034d76fb468a15536ddf.png

以下是代码:

import numpy as np

import cv2

import argparse

from Computer_Vision.Canny_Edge_Detection.sobel import sobel_edge_detection

from Computer_Vision.Canny_Edge_Detection.gaussian_smoothing import gaussian_blur

import matplotlib.pyplot as plt

def non_max_suppression(gradient_magnitude, gradient_direction, verbose):

image_row, image_col = gradient_magnitude.shape

output = np.zeros(gradient_magnitude.shape)

PI = 180

for row in range(1, image_row - 1):

for col in range(1, image_col - 1):

direction = gradient_direction[row, col]

if (0 <= direction < PI / 8) or (15 * PI / 8 <= direction <= 2 * PI):

before_pixel = gradient_magnitude[row, col - 1]

after_pixel = gradient_magnitude[row, col + 1]

elif (PI / 8 <= direction < 3 * PI / 8) or (9 * PI / 8 <= direction < 11 * PI / 8):

before_pixel = gradient_magnitude[row + 1, col - 1]

after_pixel = gradient_magnitude[row - 1, col + 1]

elif (3 * PI / 8 <= direction < 5 * PI / 8) or (11 * PI / 8 <= direction < 13 * PI / 8):

before_pixel = gradient_magnitude[row - 1, col]

after_pixel = gradient_magnitude[row + 1, col]

else:

before_pixel = gradient_magnitude[row - 1, col - 1]

after_pixel = gradient_magnitude[row + 1, col + 1]

if gradient_magnitude[row, col] >= before_pixel and gradient_magnitude[row, col] >= after_pixel:

output[row, col] = gradient_magnitude[row, col]

if verbose:

plt.imshow(output, cmap='gray')

plt.title("Non Max Suppression")

plt.show()

return output

def threshold(image, low, high, weak, verbose=False):

output = np.zeros(image.shape)

strong = 255

strong_row, strong_col = np.where(image >= high)

weak_row, weak_col = np.where((image <= high) & (image >= low))

output[strong_row, strong_col] = strong

output[weak_row, weak_col] = weak

if verbose:

plt.imshow(output, cmap='gray')

plt.title("threshold")

plt.show()

return output

def hysteresis(image, weak):

image_row, image_col = image.shape

top_to_bottom = image.copy()

for row in range(1, image_row):

for col in range(1, image_col):

if top_to_bottom[row, col] == weak:

if top_to_bottom[row, col + 1] == 255 or top_to_bottom[row, col - 1] == 255 or top_to_bottom[row - 1, col] == 255 or top_to_bottom[

row + 1, col] == 255 or top_to_bottom[

row - 1, col - 1] == 255 or top_to_bottom[row + 1, col - 1] == 255 or top_to_bottom[row - 1, col + 1] == 255 or top_to_bottom[

row + 1, col + 1] == 255:

top_to_bottom[row, col] = 255

else:

top_to_bottom[row, col] = 0

bottom_to_top = image.copy()

for row in range(image_row - 1, 0, -1):

for col in range(image_col - 1, 0, -1):

if bottom_to_top[row, col] == weak:

if bottom_to_top[row, col + 1] == 255 or bottom_to_top[row, col - 1] == 255 or bottom_to_top[row - 1, col] == 255 or bottom_to_top[

row + 1, col] == 255 or bottom_to_top[

row - 1, col - 1] == 255 or bottom_to_top[row + 1, col - 1] == 255 or bottom_to_top[row - 1, col + 1] == 255 or bottom_to_top[

row + 1, col + 1] == 255:

bottom_to_top[row, col] = 255

else:

bottom_to_top[row, col] = 0

right_to_left = image.copy()

for row in range(1, image_row):

for col in range(image_col - 1, 0, -1):

if right_to_left[row, col] == weak:

if right_to_left[row, col + 1] == 255 or right_to_left[row, col - 1] == 255 or right_to_left[row - 1, col] == 255 or right_to_left[

row + 1, col] == 255 or right_to_left[

row - 1, col - 1] == 255 or right_to_left[row + 1, col - 1] == 255 or right_to_left[row - 1, col + 1] == 255 or right_to_left[

row + 1, col + 1] == 255:

right_to_left[row, col] = 255

else:

right_to_left[row, col] = 0

left_to_right = image.copy()

for row in range(image_row - 1, 0, -1):

for col in range(1, image_col):

if left_to_right[row, col] == weak:

if left_to_right[row, col + 1] == 255 or left_to_right[row, col - 1] == 255 or left_to_right[row - 1, col] == 255 or left_to_right[

row + 1, col] == 255 or left_to_right[

row - 1, col - 1] == 255 or left_to_right[row + 1, col - 1] == 255 or left_to_right[row - 1, col + 1] == 255 or left_to_right[

row + 1, col + 1] == 255:

left_to_right[row, col] = 255

else:

left_to_right[row, col] = 0

final_image = top_to_bottom + bottom_to_top + right_to_left + left_to_right

final_image[final_image > 255] = 255

return final_image

if __name__ == '__main__':

ap = argparse.ArgumentParser()

ap.add_argument("-i", "--image", required=True, help="Path to the image")

ap.add_argument("-v", "--verbose", type=bool, default=False, help="Path to the image")

args = vars(ap.parse_args())

image = cv2.imread(args["image"])

blurred_image = gaussian_blur(image, kernel_size=9, verbose=False)

edge_filter = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])

gradient_magnitude, gradient_direction = sobel_edge_detection(blurred_image, edge_filter, convert_to_degree=True, verbose=args["verbose"])

new_image = non_max_suppression(gradient_magnitude, gradient_direction, verbose=args["verbose"])

weak = 50

new_image = threshold(new_image, 5, 20, weak=weak, verbose=args["verbose"])

new_image = hysteresis(new_image, weak)

plt.imshow(new_image, cmap='gray')

plt.title("Canny Edge Detector")

plt.show()

References

hahahha

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/412011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标和执行

信息系统可以给各行各业带来巨大的价值&#xff0c;因为它可以取代很多手工劳动&#xff0c;并且代价很低&#xff0c;另外很多原来无法做到的事情都可以借助信息系统完成。因此&#xff0c;在IT业里&#xff0c;可以说机会很多&#xff0c;各种行业都需要开发信息系统&#xf…

[vue] 你了解vue的diff算法吗?

[vue] 你了解vue的diff算法吗&#xff1f; 我的理解:计算出虚拟 DOM 中真正变化的部分,并且只针对该部分进行 DOM 更新,而非重新渲染整个页面个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 …

java 拖放文字_myeclipse2014如何实现jsp中的html代码的文字拖放

本帖最后由 liyihongcug 于 2015-3-5 16:53 编辑把 jsp打开 (visual jsp editor)之后上班区 单击右键 show --- pallette就可以了感叹myeclipse确实强大的 标签技术强于.net mvc强。vs2013能实现iis无需安装的情况下 动态指定 某个页面为首选 启动 --------------------希望2…

leetcode 二叉树的层次遍历 II(Binary Tree Level Order Traversal II)

目录 题目描述&#xff1a;示例&#xff1a;解法&#xff1a;题目描述&#xff1a; 给定一个二叉树&#xff0c;返回其节点值自底向上的层次遍历。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例&#xff1a; 给定二叉树 [3…

[vue] vue首页白屏是什么问题引起的?如何解决呢?

[vue] vue首页白屏是什么问题引起的&#xff1f;如何解决呢&#xff1f; 1.打包后文件引用路径不对&#xff0c;导致找不到文件报错白屏 2.路由模式mode设置影响个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家…

一篇极好的 CSS 教程

这是我codeproject上面看到的极好的css教程&#xff0c;今日放上让大家看看&#xff0c;待我明日青岛归来翻译给大家看看。CSS stands for Cascading Style Sheets. This is a simple styling language which allows attaching style to HTML elements. Every element type as …

python增强对比度_python增加图像对比度的方法

python增加图像对比度的方法来源&#xff1a;中文源码网 浏览&#xff1a; 次 日期&#xff1a;2019年11月5日【下载文档: python增加图像对比度的方法.txt 】(友情提示:右键点上行txt文档名->目标另存为)python增加图像对比度的方法本代码实现的是&#xff0c;在旋转…

因缺思厅的绕过

看一下页面源码&#xff0c;看到source.txt。所以进入同目录下的source.txt 代码审计下&#xff0c;并且百度了一些函数。过滤了很多关键字&#xff0c;因此常规的SQL注入没有头绪。想了挺久&#xff0c;因为要满足三个条件。1&#xff1a;不能输入过滤的关键字2&#xff1a;只…

[vue] vue能监听到数组变化的方法有哪些?为什么这些方法能监听到呢?

[vue] vue能监听到数组变化的方法有哪些&#xff1f;为什么这些方法能监听到呢&#xff1f; 你说的是vue内部的源码对Array数据的中转代理嘛 好像对push, shift等通用方法都做了代理吧! 因为它对中转的数据都做了监听个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知…

Python自制微信机器人:群发消息、自动接收好友

运营公众号也有半年了&#xff0c;今年5月份开始的&#xff0c;之前一直用一款windows工具来运营自动接受好友请求、群发文章、自动回复等操作&#xff0c;但颇有不便。 举几个场景&#xff1a; 突然在外面看到一篇文章很好&#xff0c;临时写了一篇&#xff0c;想群发一下。好…

61条面向对象设计的经验原则

你不必严格遵守这些原则&#xff0c;违背它们也不会被处以宗教刑罚。但你应当把这些原则看成警铃&#xff0c;若违背了其中的一条&#xff0c;那么警铃就会响起。 -----Arthur J.Riel (1)所有数据都应该隐藏在所在的类的内部。p13 (2)类的使用者必须依赖类的共有接口&#xff0…

gesturedetector.java_我的flutter代码中的GestureDetector不起作用

我正在玩flip_card package(这个软件包会创建一张卡片&#xff0c;当你点击它时&#xff0c;它会翻转卡片并显示卡片的正面或背面) . 我想要做的是&#xff0c;每次点击卡片时显示不同的图像&#xff0c;并且卡片翻转到正面 .为此&#xff0c;我将flip_card example修改为有状态…

[vue] vue打包成最终的文件有哪些?

[vue] vue打包成最终的文件有哪些&#xff1f; vendor.js, app.js, app.css, 1.xxx.js 2.xxx.js如果有设置到单独提取css的话 还有 1.xxx.css ......个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 …

IronPython资料

Python文档&#xff1a;http://blog.csdn.net/ccat/category/9998.aspx A bit more on IronPython&#xff1a;http://blogs.msdn.com/aaronmar/archive/2006/02/16/a-bit-more-on-ironpython.aspx Python 2.5 中文Tutorial http://wiki.woodpecker.org.cn/moin/March_Liu/PyT…

记一次webpack4+react+antd项目优化打包文件体积的过程

背景 最近自己整了一个基于webpack4和react开发的博客demo项目&#xff0c;一路整下来磕磕碰碰但也实现了功能&#xff0c;就准备发到阿里云上面去看看&#xff0c;借用了同事的阿里云小水管服务器&#xff0c;配置完成之后首页加载花了十几秒&#xff0c;打开控制台network查看…

java hashedmap_Java基础 - Map接口的实现类 : HashedMap / LinkedHashMap /TreeMap 的构造/修改/遍历/ 集合视图方法/双向迭代输出...

import java.util.*;/**一:Collection接口的* Map接口: HashMap(主要实现类) : HashedMap / LinkedHashMap /TreeMap* Map接口:对, 重复的键会进行值得覆盖 ,输出顺序和放入顺序是不一定可以保持顺序的!* 修改查询操作: 1.put(key, value), 2.remove(key) 3.putAll(其他map), 复…

[vue] vue如何优化首页的加载速度?

[vue] vue如何优化首页的加载速度&#xff1f; 补充下2楼&#xff1a; ssr直出&#xff0c; webpack压缩HTML/CSS/JS&#xff0c; 首屏css单独提取内联&#xff0c; 关键资源Proload&#xff0c; 图片&#xff1a;不缩放&#xff0c;使用webp、小图片base64&#xff0c;iconfo…

25岁了

忙了一天&#xff0c;在下午收到kk的email才想起来今天是自己的生日&#xff0c;应该请大家吃蛋糕的。想想这一年过得真快&#xff0c;2006这几个数字我还没有写惯&#xff0c;就要开始写2007了。时光如梭&#xff0c;一点都不假。 25岁啰&#xff0c;转眼间自己怎么就这把年纪…

java同时满足语句_关于控制语句,下列哪些说法符合《阿里巴巴Java开发手册》:...

案例分析一&#xff1a;假定CPU的主频是500MHz。硬盘采用DMA方式进行数据传送&#xff0c;其数据传输率为4MB/s, 每次DMA传输的数据量为8KB, 要求没有任何数据传输被错过。如果CPU在DMA初始化设置和启动硬盘操作等方面用了1000个时钟周期&#xff0c;并且在DMA传送完成后的中断…

【java小知识】FileReader读取文件出现乱码的解决办法

转1&#xff1a;https://blog.csdn.net/a532672728/article/details/79432619 转2&#xff1a;https://www.cnblogs.com/qq78292959/p/3794993.html 小结&#xff1a; 1&#xff09;注意txt文件&#xff0c;保存的格式&#xff0c;Windows的记事本默认保存的ANSI&#xff0c;我…