OpenCV Using Python——边缘检测和Otsu方法背景分割

边缘检测和Otsu方法背景分割

1. 简介

        鉴于OpenCV的官方文档中选择的图片比较完美,所以当遇到现实问题时会苦恼方法的选择。下面简要谈谈自己遇到的个别问题的认识。

2. 实现代码

        代码主要内容为使用拉普拉斯算子和自适应高斯阈值作边缘检测;用Otsu方法作前后背景分割。
(1)拉普拉斯算子提取的边缘由于数据长度的关系,很多边缘在图中被忽略了;
(2)Canny算子因为提取的边缘断断续续,所以这里不再给出结果,一般用于图片中有大范围或明显的几何结构(比如道路检测)等场合中;
(3)自适应高斯提取边缘在不同的图像块内的阈值都不一样,所以对图片中不同的光照条件会有很好的适应;
(4)Otsu方法可用于提取前后背景,适用于有两个尖峰的灰度直方图的图片中(这样的图片前后背景乍看会分得很开)。维基里有Otsu方法的java代码,但转换的结果和OpenCV自带的函数结果不太一致。
import cv2
import math
import cv2.cv
import numpy as np
from matplotlib import pyplot as plt
################################################################################

print 'Load Image'

imgFile = 'images/big_alice.jpg'

# load an original image
img = cv2.imread(imgFile)
################################################################################

# color value range
cRange = 256

rows,cols,channels = img.shape

# convert color space from bgr to gray
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
################################################################################

# laplacian edge
imgLap = cv2.Laplacian(imgGray,cv2.CV_8U)

# otsu method
threshold,imgOtsu = cv2.threshold(imgGray,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# adaptive gaussian threshold  
imgAdapt = cv2.adaptiveThreshold(imgGray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
# imgAdapt = cv2.medianBlur(imgAdapt, 3)    
################################################################################

# display original image and gray image
plt.subplot(2,2,1), plt.imshow(img), plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2), plt.imshow(imgLap,cmap = 'gray'), plt.title('Laplacian Edge'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3), plt.imshow(imgOtsu,cmap = 'gray'), plt.title('Otsu Method'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4), plt.imshow(imgAdapt,cmap = 'gray'), plt.title('Adaptive Gaussian Threshold'), plt.xticks([]), plt.yticks([])
plt.show()                                                
################################################################################

print 'Goodbye!'

3. 实现结果

        实现效果如下图所示,上一行的图片因为前景轮廓清晰和背景统一,所以可以发现所有方法都可以用。下一行图片背景复杂很多,对边缘提取影响不大,但Otsu方法的前后背景分割显然不可行,原因是背景的混乱导致在灰度直方图中的背景对应的灰度值投票过少,不足以形成尖峰使得前后背景分割的阈值刚好停留在尖峰的山脚附近。

OpenCV Using Python——边缘检测和Otsu方法背景分割_第1张图片        

你可能感兴趣的:(Python,OpenCV)