人眼怎么识别图像边缘?

比如有一幅图,图里面有一条线,左边很亮,右边很暗,那人眼就很容易识别这条线作为边缘.也就是像素的灰度值快速变化的地方.

sobel算子



对于f(t),其导数f'(t)反映了每一处的变化趋势.在变化最快的位置其导数最大. sobel算子的思路就是模拟求一阶导数.

sobel算子是一个离散差分算子.它计算图像像素点亮度值的近似梯度.

图像是二维的,即沿着宽度/高度两个方向.

我们使用两个卷积核对原图像进行处理:

  • 水平方向



    很好理解,原始像素灰度值-->(右边像素值-左边像素值),反映了水平方向的变化情况.

  • 垂直方向

这样的话,我们就得到了两个新的矩阵,分别反映了每一点像素在水平方向上的亮度变化情况和在垂直方向上的亮度变换情况.

综合考虑这两个方向的变化,我们使用



反映某个像素的梯度变化情况.

有时候为了简单起见,也直接用绝对值相加替代.

opencv里可以使用了如下的卷积核,可以"放大像素的变化情况".



可以参考这个函数Scharr

opencv实现

import cv2 as cv
def test():
src = cv.imread("/home/sc/disk/keepgoing/opencv_test/sidetest.jpeg")
src = cv.GaussianBlur(src, (3, 3), 0)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
grad_x = cv.Sobel(gray, -1, 1, 0, ksize=3)
grad_y = cv.Sobel(gray, -1, 0, 1, ksize=3) grad = cv.addWeighted(grad_x, 0.5, grad_y, 0.5, 0) cv.imshow("origin",src)
cv.imshow("grad",grad)
cv.waitKey() test()

首先是高斯模糊去噪.某种意义上说高斯模糊是和sobel相反的过程.高斯模糊平滑了某点像素与周边像素的差异.那为什么还要先高斯去噪呢?

噪声就是像素的强度相对于真值有个突变。从时域上讲,通过高斯滤波能让一个像素的强度与周围的点相关,就减小了突变的影响;从频域上讲,突变引入了高频分量,而高斯滤波器可以滤除高频分量。

高斯去噪是为了防止把噪点也检测为边缘.

然后计算grad_x,grad_y.即对原图做水平方向/垂直方向的sobel卷积核卷积

    grad_x = cv.Sobel(gray, -1, 1, 0, ksize=3)
grad_y = cv.Sobel(gray, -1, 0, 1, ksize=3)

sobel api



注意区分c++版本和python版本api. 在上述代码中,第二个参数-1代表我们希望输出的图像矩阵和原图有同样的depth,第3/4个参数分别代表在x/y方向做一阶差分.取值0或1.

ksize必须为奇数.

tips:通常我们使用( xorder = 1, yorder = 0, ksize = 3) or ( xorder = 0, yorder = 1, ksize = 3)来计算水平/垂直方向的一阶差分矩阵.ksize=3用的是标准sobel卷积核.如果ksize传入FILTER_SCHARR,则使用的是如下卷积核:

最后将两个矩阵叠加,综合考虑水平和垂直方向的像素灰度值变化强度.得到边缘.

 grad  = cv.addWeighted(grad_x, 0.5, grad_y, 0.5, 0)

完整代码处理效果如下

ksize采用cv.FILTER_SCHARR效果如下:

    grad_x = cv.Sobel(gray, -1, 1, 0, ksize=cv.FILTER_SCHARR)
grad_y = cv.Sobel(gray, -1, 0, 1, ksize=cv.FILTER_SCHARR)

opencv边缘检测的更多相关文章

  1. [OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    http://blog.csdn.net/poem_qianmo/article/details/25560901 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

  2. OpenCV——边缘检测入门、Canny边缘检测

    边缘检测的一般步骤: 最优边缘检测的三个评价标准: 低错误率:表示出尽可能多的实际边缘,同时尽可能地减少噪声产生的误报: 高定位性:标识出的边缘要与图像实际边缘尽可能接近: 最小响应:图像中的边缘只能 ...

  3. opencv边缘检测的入门剖析(第七天)

    ---边缘检测概念理解--- 边缘检测的理解可以结合前面的内核,说到内核在图像中的应用还真是多,到现在为止学的对图像的操作都是核的操作,下面还有更神奇的! 想把边缘检测出来,从图像像素的角度去想,那就 ...

  4. OpenCV边缘检测的详细参数调节

    1. findCountours 转载于http://blog.sina.com.cn/s/blog_7155fb1a0101a90h.html findContours函数,这个函数的原型为: &l ...

  5. opencv边缘检测-拉普拉斯算子

    sobel算子一文说了,索贝尔算子是模拟一阶求导,导数越大的地方说明变换越剧烈,越有可能是边缘. 那如果继续对f'(t)求导呢? 可以发现"边缘处"的二阶导数=0. 我们可以利用这 ...

  6. opencv 边缘检测原理

    只是实现一下,暂不考虑效率 import cv2 as cv import numpy as np import math # 从源码层面实现边缘检测 img = cv.imread('../imag ...

  7. OpenCV——边缘检测(sobel算子、Laplacian算子、scharr滤波器)

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  8. opencv边缘检测报错

    cnts = cv2.findContours(edged_image.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnts = cnts[0] if ...

  9. 【资料分享】 OpenCV精华收藏

    OpenCV精华收藏 SkySeraph Dec.29th 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified Dat ...

随机推荐

  1. MySQL之备份和还原

    在实际项目中对于数据库的安全是重中之重,为防万一我们需要做好备份工作.备份分为全量备份和增量备份,今天我们就来实践下备份和还原操作. 一.为什么需要备份 在生产环境中数据库可能会遭遇到各种各样的不测从 ...

  2. 我常用的一些linux命令

    之前做过两年的运维,用过很多命令,深切体会到某些linux命令熟练掌握后对效率提升有多大.举个简单的例子,在做了研发后经常会有跑一些数据,对于结果数据的处理,我们的产品同学一般都习惯于用excel做统 ...

  3. eruda.js 实现线上调出控制台

    <script src="//cdn.bootcss.com/eruda/1.3.0/eruda.min.js"></script> 调用 eruda.in ...

  4. js 截屏保存图片

    html2canvas.js 这个js有个强大的功能,就是能将html 对应的dom生成canvas. 这样,我们就可以通过生成的canvas转化成 base64 图片,从而实现截屏功能: 核心代码如 ...

  5. spss数据分析可以被人工智能替换吗

    作为一名需要对课题进行研究的大学生,我在日常学习中经常需要用到spss,虽然老师上课已经初步教了我如何用这个软件,然而,在使用过程中我还是遇到了许多问题.具体来说,就是这个软件在很多地方都不够与时俱进 ...

  6. Eclipse Paho MQTT Utility

    下载地址: https://repo.eclipse.org/content/repositories/paho-releases/org/eclipse/paho/org.eclipse.paho. ...

  7. HDU- 3605 - Escape 最大流 + 二进制压位

    HDU - 3605 : acm.hdu.edu.cn/showproblem.php?pid=3605 题目: 有1e5的的人,小于10个的星球,每个星球都有容量,每个人也有适合的星球和不适合的星球 ...

  8. yzoj P2043 & 洛谷 P1282 多米诺骨牌 题解

    题意 类似于就是背包. 解析 代码 跟解析有点不一样v[i]价值,w[i]重量,s背包容积,背包转移即可. #include<bits/stdc++.h> using namespace ...

  9. 关闭Linux(Ubuntu)错误报告

    关于错误报告 网上查了下,Ubuntu(包括elementary,elementary是基于Ubuntu的)桌面版预装了Apport,它是一个错误收集系统,会收集软件崩溃.未处理异常和其他,包括程序b ...

  10. mysql5.7指定字符集

    在这个配置下面加上下面这行就可以 [mysqld] character_set_server=utf8 重启后: mysql> show variables like 'char%';+---- ...