标签:

我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢

如果需要检测到图像里面的边缘,首先我们需要知道边缘处具有什么特征。

对于一幅灰度图像来说,边缘两边的灰度值肯定不相同,这样我们才能分辨出哪里是边缘,哪里不是。

因此,如果我们需要检测一个灰度图像的边缘,我们需要找出哪里的灰度变化最大。显然,灰度变化越大,对比度越强,边缘就越明显。

那么问题来了,我们怎么知道哪里灰度变化大,哪里灰度变化小呢?

导数,梯度,边缘信息

在数学中,与变化率有关的就是导数。

如果灰度图像的像素是连续的(实际不是),那么我们可以分别原图像G对x方向和y方向求导数

获得x方向的导数图像Gx和y方向的导数图像Gy。Gx和Gy分别隐含了x和y方向的灰度变化信息,也就隐含了边缘信息。

如果要在同一图像上包含两个方向的边缘信息,我们可以用到梯度。(梯度是一个向量)

原图像的梯度向量Gxy为(Gx,Gy),梯度向量的大小和方向可以用下面两个式子计算

角度值好像需要根据向量所在象限不同适当+pi或者-pi。

梯度向量大小就包含了x方向和y方向的边缘信息。

图像导数

实际上,图像矩阵是离散的。

连续函数求变化率用的是导数,而离散函数求变化率用的是差分。

差分的概念很容易理解,就是用相邻两个数的差来表示变化率。

下面公式是向后差分

x方向的差分:Gx(n,y) = G(n,y)-G(n-1,y)

y方向的差分:Gy(x,n) = G(x,n)-G(x,n-1)

实际计算图像导数时,我们是通过原图像和一个算子进行卷积来完成的(这种方法是求图像的近似导数)。

最简单的求图像导数的算子是Prewitt算子:

x方向的Prewitt算子为

y方向的Prewitt算子为

---------------------------------------------

原图像和一个算子进行卷积的大概过程如下

如果图像矩阵中一块区域为

那么x5处的x方向的导数是,将x方向算子的中心和x5重合,然后对应元素相乘再求和,即

x5处的x方向导数为x3+x6+x9-x1-x4-x7

对矩阵中所有元素进行上述计算,就是卷积的过程。

--------------------------------------------

因此,利用原图像和x方向Prewitt算子进行卷积就可以得到图像的x方向导数矩阵Gx,

利用原图像和y方向Prewitt算子进行卷积就可以得到图像的y方向导数矩阵Gy。

利用公式

就可以得到图像的梯度矩阵Gxy,这个矩阵包含图像x方向和y方向的边缘信息。

Python实现卷积及Prewitt算子的边缘检测

首先我们把图像卷积函数封装在一个名为imconv的函数中

importnumpy as npfrom PIL importImagedefimconv(image_array,suanzi):‘‘‘计算卷积

参数

image_array 原灰度图像矩阵

suanzi 算子

返回

原图像与算子卷积后的结果矩阵‘‘‘image= image_array.copy() #原图像矩阵的深拷贝

dim1,dim2=image.shape#对每个元素与算子进行乘积再求和(忽略最外圈边框像素)

for i in range(1,dim1-1):for j in range(1,dim2-1):

image[i,j]= (image_array[(i-1):(i+2),(j-1):(j+2)]*suanzi).sum()#由于卷积后灰度值不一定在0-255之间,统一化成0-255

image = image*(255.0/image.max())#返回结果矩阵

return image

然后我们利用Prewitt算子计算x方向导数矩阵Gx,y方向导数矩阵Gy,和梯度矩阵Gxy。

importnumpy as npimportmatplotlib.pyplot as plt#x方向的Prewitt算子

suanzi_x = np.array([[-1, 0, 1],

[-1, 0, 1],

[-1, 0, 1]])#y方向的Prewitt算子

suanzi_y = np.array([[-1,-1,-1],

[ 0, 0, 0],

[1, 1, 1]])#打开图像并转化成灰度图像

image = Image.open("pika.jpg").convert("L")#转化成图像矩阵

image_array =np.array(image)#得到x方向矩阵

image_x =imconv(image_array,suanzi_x)#得到y方向矩阵

image_y =imconv(image_array,suanzi_y)#得到梯度矩阵

image_xy = np.sqrt(image_x**2+image_y**2)#梯度矩阵统一到0-255

image_xy = (255.0/image_xy.max())*image_xy#绘出图像

plt.subplot(2,2,1)

plt.imshow(image_array,cmap=cm.gray)

plt.axis("off")

plt.subplot(2,2,2)

plt.imshow(image_x,cmap=cm.gray)

plt.axis("off")

plt.subplot(2,2,3)

plt.imshow(image_y,cmap=cm.gray)

plt.axis("off")

plt.subplot(2,2,4)

plt.imshow(image_xy,cmap=cm.gray)

plt.axis("off")

plt.show()

Prewitt算子的结果如下图所示

上方:左图为原图像,右图为x方向导数图像

下方:左图为y方向导数图像,右图为梯度图像

从图中可以看出,Prewitt算子虽然能检测出图像边缘,但是检测结果较为粗糙,还带有大量的噪声。

近似导数的Sobel算子

Sobel算子与Prewitt比较类似,但是它比Prewitt算子要好一些。

x方向的Sobel算子为

y方向的Sobel算子为

python代码只需要将上面代码中的Prewitt算子改成Sobel算子即可。

#x方向的Sobel算子

suanzi_x = np.array([[-1, 0, 1],

[-2, 0, 2],

[-1, 0, 1]])#y方向的Sobel算子

suanzi_y = np.array([[-1,-2,-1],

[ 0, 0, 0],

[1, 2, 1]])

Sobel算子的结果如下图所示

上方:左图为原图像,右图为x方向导数图像

下方:左图为y方向导数图像,右图为梯度图像

从图中看出,比较Prewitt算子和Sobel算子,Sobel算子稍微减少了一点噪声,但噪声还是比较多的。

未完,待续

参考列表

1.《python计算机视觉编程》

标签:

python边缘检测画简笔画_python计算机视觉2:图像边缘检测相关推荐

  1. python边缘检测画简笔画_OpenCV-Python 边缘检测

    Sobel边缘检测 Sobel算子是一种具有方向性的边缘检测算子,可以分别计算水平和垂直方向上的灰阶突变. import cv2 img = cv2.imread("01.jpg&quo ...

  2. python正弦波叠加方波_傅立叶变换还能画简笔画?谷歌工程师开发的这个试玩网站火了...

    晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI 无论是处理声音和图像信号,都必须用到傅立叶变换.其实除了这些"正经"用途,它还能做一些有意思的事情. 最近,一位名叫Je ...

  3. 傅立叶变换还能画简笔画?谷歌工程师开发的这个试玩网站火了| 附资源

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 无论是处理声音和图像信号,都必须用到傅立叶变换.其实除了这些"正经"用途,它还能做一些有意思的事情. 最近,一位名叫J ...

  4. 保护环境的画用计算机怎么画,保护环境的画简笔画

    简笔画是由成人创造的概念化的造型符号,是对物的形的高度概括与夸张.许多家长及老师在儿童初学绘画时经常引导其学习简笔画,其目的正如一位家长所言:"简笔画简单,孩子容易掌握".事实并非 ...

  5. python turtle画滑稽表情_python使用turtle库绘制奥运五环

    python使用turtle库绘制奥运五环 Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令 ...

  6. python程序画漂亮图片_Python能画美观的专业插图吗 ?当然!

    原标题:Python能画美观的专业插图吗 ?当然! 文末领取[Python绘图代码] 冯昱尧| 方法一作者 阿昆 | 方法二作者 极市平台 | 编译 知乎 | 来源 1 方法一 强烈推荐 Python ...

  7. 【边缘检测】基于matlab八方向sobel图像边缘检测【含Matlab源码 1865期】

    ⛄一.八方向Sobel算子的边缘检测算法简介 1 引言 随着数字图像的广泛应用, 对图像精度的要求也逐步提高.边缘是目标图像与背景图像的分界, 是图像最基本的特征之一.图像边缘蕴含了图像丰富的内在信息 ...

  8. python matplotlib画数据分布图_Python数据可视化之matplotlib

    数据可视化能让人们更直观的传递数据所要表达的信息.Python 中有两个专用于可视化的库,matplotlib 和 seaborn ,本文将介绍matplotlib. Matplotlib:基于Pyt ...

  9. python图像边缘检测_python opencv实现图像边缘检测

    本文利用python opencv进行图像的边缘检测,一般要经过如下几个步骤: 1.去噪 如cv2.GaussianBlur()等函数: 2.计算图像梯度 图像梯度表达的是各个像素点之间,像素值大小的 ...

最新文章

  1. 云大计算机基础,2019云南大学计算机技术专硕上岸经验
  2. CentOS中提示rz命令找不到安装lrzsz来解决
  3. kill -0 pid是做什么用的?
  4. 【ArcGIS风暴】ArcGIS生成GlobeLand30土地利用数据集中国区域行列号shp格式对照图(附shp下载)
  5. WordPress数据表wp-options数据字段存JSON数据
  6. Objective-C路成魔【11-多态性、动态类型和动态绑定】
  7. 1725.可以形成最大正方形的矩阵数目
  8. Sentinel限流实战
  9. 用计算机做动画,如何制作动画
  10. 攻防世界逆向-logmein
  11. lattice若干bug
  12. const char* std::string CString 之间的转换
  13. python程序运行进程、使用时间、剩余时间显示
  14. Excel笔记(4)常用函数21-34
  15. 基于MATLAB/yalmip/cplex 的机组最优组合
  16. Codewars(3)
  17. echarts地图地名显示_ECharts特定地图区域的文本标签
  18. Macbook terminal: No application knows how to open问题
  19. Django Ninja简单教程
  20. linux ftp 未找到命令,Linux不能使用FTP 命令 -bash: ftp: command not found

热门文章

  1. codesys高级应用
  2. 【求职】2020福建省教师招聘考试小学信息技术
  3. 小程序1.7亿日活,微信张小龙亲临2018微信公开课PRO发表演讲
  4. java如何判断对象为空_java对象如何判断是否为空
  5. Android 跳转到华为钱包、小米钱包、Samsung Pay、OPPO钱包、魅族钱包主页面
  6. 富爸爸股票投资入门到精通,知识卡片笔记分享
  7. Orleans 2.0 官方文档 ——Grains定时器和提醒器(Reminder)
  8. Mybatis 如何批量删除数据
  9. Nodejs学习网址
  10. 怎样在word2007中插入图片和表格