码迷,mamicode.com
首页 > 其他好文 > 详细

OpenCV入门笔记(五) 边缘检测

时间:2015-08-03 22:47:06      阅读:339      评论:0      收藏:0      [点我收藏+]

标签:opencv   sobel   canny   laplacian   边缘检测   

这里介绍三种边缘检测的方法, Sobel算子(索贝尔算子)Laplacian算子(拉普拉斯算子)Canny算子 的边缘检测。

一、Sobel算子

Sobel算子在一阶偏导上检测边缘,且能在水平(x 方向)和竖直(y 方向)分别作用。直观上,Sobel寻找这样的边缘:中间灰度值特别大,两边很小,即像素值出现跳跃的现象。我们可以通过求梯度值来确定。

x 和 y 两个方向的核函数如下:

????1?2?1000+1+2+1???(Gx)

???+10?1+20?2+10?1???(Gy)

若要同时考虑两个方向,则用

|G|=(Gx)2+(Gy)2????????????2

或者为了方便,直接用绝对值的和

|G|=|Gx|+|Gy|

核函数和图像的卷积过程,其实是梯度的一个近似,从核函数的结构上可以看出来。注意Kernel的大小需是奇数。


二、Laplacian算子

Laplacian算子偏重在二阶导数上寻找边缘。因为前面讲到的Sobel算子,其中边缘的一阶导数的极大值时,往往伴随着二阶导数取 0 的情况。

Laplacian算子定义如下:

Laplacian(f)=?2f?x2+?2f?y2


三、代码示例

代码示例如下,展示【原图】,【Sobel算子】,【x方向】,【y方向】,和【Laplacian算子】后的效果。

import cv2

# 读入并转化成灰度图
img = cv2.imread("1.jpg", 0)

# 加特效!
sobel = cv2.Sobel(img, cv2.CV_8U, 1, 1, ksize = 5)
sobel_x = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize = 5)
sobel_y = cv2.Sobel(img, cv2.CV_8U, 0, 1, ksize = 5)

laplacian = cv2.Laplacian(img, cv2.CV_8U)

# 创建窗口
cv2.namedWindow("origin", cv2.WINDOW_NORMAL)
cv2.namedWindow("sobel x", cv2.WINDOW_NORMAL)
cv2.namedWindow("sobel y", cv2.WINDOW_NORMAL)
cv2.namedWindow("sobel", cv2.WINDOW_NORMAL)
cv2.namedWindow("laplacian", cv2.WINDOW_NORMAL)

# 显示
cv2.imshow("origin", img)
cv2.imshow("sobel x", sobel_x)
cv2.imshow("sobel y", sobel_y)
cv2.imshow("sobel", sobel)
cv2.imshow("laplacian", laplacian)

cv2.waitKey(0)
cv2.destroyAllWindows()

效果图如下:

技术分享


四、Canny算子

Canny算子像Sobel算子那样,也有两个方向的核函数,不同的是,Canny会组合成四个方向的导数,每个方向达到局部最大值才能是边缘的候选点。

Canny算法有两个阈值,设小的阈值为 t1, 大的阈值为 t2

若小于小的阈值,即 t<t1,直接抛弃;
若大于大的阈值,即 t>t2,则直接判定为边缘像素;
若是处于中间,t1<t<t2,则必须和确定的边缘像素(大于最大阈值)相连才能进一步判断为边缘像素。


代码示例,创建一个滑动条,可以动态改变两个阈值

import cv2

threshold_one = 100
threshold_two = 200

# 下阈值改变
def refresh_x(x):
    global threshold_one
    threshold_one = x 
    refresh()

# 上阈值改变
def refresh_y(y):
    global threshold_two 
    threshold_two = y 
    refresh()

# 刷新Canny检测
def refresh():
    global threshold_one
    global ghreshold_two
    print ‘x = %d, y = %d‘ %(threshold_one, threshold_two)

    canny = cv2.Canny(blur, threshold_one, threshold_two)
    cv2.imshow("canny", canny)

# 读入并转成灰度图
img = cv2.imread("1.jpg", 0)

# 高斯模糊,减少噪点
blur = cv2.GaussianBlur(img, (5, 5), 0)

# 检测边缘
canny = cv2.Canny(blur, 100, 200)

# 创建窗口
cv2.namedWindow("origin", cv2.WINDOW_NORMAL)
cv2.namedWindow("canny", cv2.WINDOW_NORMAL)

# 创建进度条
cv2.createTrackbar("threhold one: ", "canny", 0, 255, refresh_x)
cv2.createTrackbar("threhold two: ", "canny", 0, 255, refresh_y)

# 显示
cv2.imshow("origin", img)
cv2.imshow("canny", canny)

cv2.waitKey(0)
cv2.destroyAllWindows()

限于篇幅,图片效果就不放出来了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

OpenCV入门笔记(五) 边缘检测

标签:opencv   sobel   canny   laplacian   边缘检测   

原文地址:http://blog.csdn.net/zhangxb35/article/details/47261657

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!