经典数字图像处理2-边缘检测和图像分割

经典数字图像处理2-边缘检测和图像分割_第1张图片
传统图像处理可以简单分为这四大部分,其中图像增强和图像滤波已经介绍,以下部分将介绍边缘检测和图像分割技术。

边缘检测

边缘一般是指图像中一段连续的像素值发生变化明显的地方。检测边缘可以用于检测物体或者提取特征的参考。

一阶导数sobel

计算相邻像素值的变化程度,一般有水平、垂直两个方向,也有斜方向使用的卷积核,可有效检测到对应物体的边缘。
经典数字图像处理2-边缘检测和图像分割_第2张图片

二阶导数拉普拉斯

经典数字图像处理2-边缘检测和图像分割_第3张图片
得到结果:
经典数字图像处理2-边缘检测和图像分割_第4张图片

candy边缘检测算法

1.图像去噪(高斯滤波)
2.图像使用水平、垂直、斜方向四个方向的sobel算子得到边缘;
3.非极大值抑制;
4.设置高低阈值,高于maxval选择,低于maxval高于minval,判断是否在已选择的边上,若确定则选择,不在则抛弃。
经典数字图像处理2-边缘检测和图像分割_第5张图片
图中ABC三点,A高于maxval选择,BC都在两者之间,但C与A连接,选择C抛弃B。

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg',0)
edges = cv2.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()

经典数字图像处理2-边缘检测和图像分割_第6张图片

图像分割

常用Graphcut图割的方法来聚类,将一张图分割成子图。后面对于彩色图像,使用GMM高斯混合模型来描述图像,与图割方法结合,效果更加。

python——opencv实现过程:

  • 用户输入一个矩形。矩形外的所有区域肯定都是背景(我们在前面已经提到,所有的对象都要包含在矩形框内)。矩形框内的东西是未知的。同样用户确定前景和背景的任何操作都不会被程序改变。
  • 计算机会对我们的输入图像做一个初始化标记。它会标记前景和背景像素。
  • 使用一个高斯混合模型(GMM)对前景和背景建模。
  • 根据我们的输入,GMM 会学习并创建新的像素分布。对那些分类未知的像素(可能是前景也可能是背景),可以根据它们与已知分类(如背景)的像素的关系来进行分类(就像是在做聚类操作)。
  • 这样就会根据像素的分布创建一副图。图中的节点就是像素点。除了像素点做节点之外还有两个节点:Source_node 和 Sink_node。所有的前景像素都和 Source_node 相连。所有的背景像素都和 Sink_node 相
    连。
  • 将像素连接到 Source_node/end_node 的(边)的权重由它们属于同一类(同是前景或同是背景)的概率来决定。两个像素之间的权重由边的信息或者两个像素的相似性来决定。如果两个像素的颜色有很大的不同,那么它们之间的边的权重就会很小。
  • 使用 mincut 算法对上面得到的图进行分割。它会根据最低成本方程将图
    分为 Source_node 和 Sink_node。成本方程就是被剪掉的所有边的权重之和。在裁剪之后,所有连接到 Source_node 的像素被认为是前景,所有连接到 Sink_node 的像素被认为是背景。
  • 继续这个过程直到分类收敛。

最终效果:
经典数字图像处理2-边缘检测和图像分割_第7张图片

import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg')
mask = np.zeros(img.shape[:2],np.uint8)
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
rect = (50,50,450,290)
# 函数的返回值是更新的 mask, bgdModel, fgdModel
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]
plt.imshow(img),plt.colorbar(),plt.show()

你可能感兴趣的:(数字图像处理)