(转载) Python-OpenCV 处理图像(五):图像中边界和轮廓检测

系列文章目录

关于边缘检测的基础来自于一个事实,即在边缘部分,像素值出现”跳跃“或者较大的变化。如果在此边缘部分求取一阶导数,就会看到极值的出现。

而在一阶导数为极值的地方,二阶导数为0,基于这个原理,就可以进行边缘检测。

关于 Laplace 算法原理,可参考

  • Laplace 算子

0x01. Laplace 算法

下面的代码展示了分别对灰度化的图像和原始彩色图像中的边缘进行检测:

效果展示

原图

灰度化图片检测

原始彩色图片检测

0x02. Sobel 算法

Sobel 也是很常用的一种轮廓识别的算法。

关于 Sobel 导数原理的介绍,可参考

  • Sobel 导数

以下是使用 Sobel 算法进行轮廓检测的代码和效果

处理之后效果图(感觉比Laplace效果要好些)

0x03. cv.MorphologyEx

cv.MorphologyEx 是另外一种边缘检测的算法

0x04. Canny 边缘检测

Canny 算法可以对直线边界做出很好的检测;

关于 Canny 算法原理的描述,可参考:

  • Canny 边缘检测

原图

使用 Canny 算法处理之后

标记出标准的直线

标记出所有可能的直线

0x05. 轮廓检测

OpenCV 提供一个 FindContours 函数可以用来检测出图像中对象的轮廓:

效果图:

原图

识别结果

0x06. 边界检测

import cv2.cv as cv im = cv.LoadImage("img/build.png", cv.CV_LOAD_IMAGE_GRAYSCALE) dst_32f = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_32F, 1) neighbourhood = 3 aperture = 3 k = 0.01 maxStrength = 0.0 threshold = 0.01 nonMaxSize = 3 cv.CornerHarris(im, dst_32f, neighbourhood, aperture, k) minv, maxv, minl, maxl = cv.MinMaxLoc(dst_32f) dilated = cv.CloneImage(dst_32f) cv.Dilate(dst_32f, dilated) # By this way we are sure that pixel with local max value will not be changed, and all the others will localMax = cv.CreateMat(dst_32f.height, dst_32f.width, cv.CV_8U) cv.Cmp(dst_32f, dilated, localMax, cv.CV_CMP_EQ) #compare allow to keep only non modified pixel which are local maximum values which are corners. threshold = 0.01 * maxv cv.Threshold(dst_32f, dst_32f, threshold, 255, cv.CV_THRESH_BINARY) cornerMap = cv.CreateMat(dst_32f.height, dst_32f.width, cv.CV_8U) cv.Convert(dst_32f, cornerMap) #Convert to make the and cv.And(cornerMap, localMax, cornerMap) #Delete all modified pixels radius = 3 thickness = 2 l = [] for x in range(cornerMap.height): #Create the list of point take all pixel that are not 0 (so not black) for y in range(cornerMap.width): if cornerMap[x,y]: l.append((y,x)) for center in l: cv.Circle(im, center, radius, (255,255,255), thickness) cv.ShowImage("Image", im) cv.ShowImage("CornerHarris Result", dst_32f) cv.ShowImage("Unique Points after Dilatation/CMP/And", cornerMap) cv.WaitKey(0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import cv2 . cv as cv
 
im = cv . LoadImage ( "img/build.png" , cv . CV_LOAD_IMAGE_GRAYSCALE )
 
dst_32f = cv . CreateImage ( cv . GetSize ( im ) , cv . IPL_DEPTH_32F , 1 )
 
neighbourhood = 3
aperture = 3
k = 0.01
maxStrength = 0.0
threshold = 0.01
nonMaxSize = 3
 
cv . CornerHarris ( im , dst_32f , neighbourhood , aperture , k )
 
minv , maxv , minl , maxl = cv . MinMaxLoc ( dst_32f )
 
dilated = cv . CloneImage ( dst_32f )
cv . Dilate ( dst_32f , dilated ) # By this way we are sure that pixel with local max value will not be changed, and all the others will
 
localMax = cv . CreateMat ( dst_32f . height , dst_32f . width , cv . CV_8U )
cv . Cmp ( dst_32f , dilated , localMax , cv . CV_CMP_EQ ) #compare allow to keep only non modified pixel which are local maximum values which are corners.
 
threshold = 0.01 * maxv
cv . Threshold ( dst_32f , dst_32f , threshold , 255 , cv . CV_THRESH_BINARY )
 
cornerMap = cv . CreateMat ( dst_32f . height , dst_32f . width , cv . CV_8U )
cv . Convert ( dst_32f , cornerMap ) #Convert to make the and
cv . And ( cornerMap , localMax , cornerMap ) #Delete all modified pixels
 
radius = 3
thickness = 2
 
l = [ ]
for x in range ( cornerMap . height ) : #Create the list of point take all pixel that are not 0 (so not black)
     for y in range ( cornerMap . width ) :
         if cornerMap [ x , y ] :
             l . append ( ( y , x ) )
 
for center in l :
     cv . Circle ( im , center , radius , ( 255 , 255 , 255 ) , thickness )
 
 
cv . ShowImage ( "Image" , im )
cv . ShowImage ( "CornerHarris Result" , dst_32f )
cv . ShowImage ( "Unique Points after Dilatation/CMP/And" , cornerMap )
 
cv . WaitKey ( 0 )

你可能感兴趣的:((转载) Python-OpenCV 处理图像(五):图像中边界和轮廓检测)