目录
10.1 基础知识
在图像分割中,基本的挑战是将一幅图像划分为多个区域,这些区域需满足特定的条件。通常情况下,针对单色图像的分割算法会依据灰度值的两种主要特性之一:不连续性和相似性。
在第一种特性中,假设各个区域的边界与背景明显不同,允许基于灰度的局部不连续性来检测边界,这种方法主要采用基于边缘的分割技术。而第二种特性则使用基于区域的分割方法,依据预先定义的一组标准将图像分割成相似的区域。
10.2 点,线和边缘检测
10.2.1孤立点检测
点检测以二阶导数为基础,使用拉普拉斯公式:
在输出图像中,超过阈值的点呗标注为1,其他点标注为0,从而产生一幅二值图像。
10.2.2 线检测
线检测是复杂度更高的检测,预期二阶导数将导致更强的响应,通常用3*3的拉普拉斯模型来检测特定方向的线。如以下四个模版:
分别用来测试水平,+45°,垂直,-45°的的线最佳。
10.2.3边缘模型
边缘检测是基于灰度突变来分割图像的最常用的方法。
台阶边缘是指在1个像素的距离上发生两个灰度级间理想的过渡。图a显示了一个垂直台阶边缘的一部分和通过该边缘的一个水平剖面。
数字图像都存在被模糊且带有噪声的边缘,图b斜坡的斜度与边缘的模糊程度成反比。在这一模型中,不再存在一条细的(1像素宽)轨迹。相反,一个边缘点现在是斜坡中包含的任何点。
边缘的第三种模型是所谓的“屋顶”边缘,这种边缘具有图c所示的特性。屋顶边缘是通过一个区域的线的模型,屋顶边缘的基底(宽度)由该线的宽度和尖锐度决定。
10.2.4基本边缘检测
灰度变化也可以用一阶导数来完成。梯度是图像边缘的强度和方向,梯度用Vf来表示,并用向量来定义:
罗伯特交叉梯度算子是最早尝试使用具有对角优势的二维模板之一。公式如下:
Prewitt算子携带了更多有关边缘方向的信息,公式如下:
Sobel算子在上式中心系数加了个权值2,可以平滑图像,公式如下:
罗伯特算子实验代码和结果:
import cv2
import numpy as np
# 读取图像
image = cv2.imread('haitan.png', cv2.IMREAD_GRAYSCALE)
# 定义罗伯特交叉算子
roberts_cross_v = np.array([[1, 0], [0, -1]])
roberts_cross_h = np.array([[0, 1], [-1, 0]])
# 应用罗伯特交叉算子进行边缘检测
vertical_edges = cv2.filter2D(image, -1, roberts_cross_v)
horizontal_edges = cv2.filter2D(image, -1, roberts_cross_h)
# 合并垂直和水平边缘图像
edges = cv2.addWeighted(vertical_edges, 0.5, horizontal_edges, 0.5, 0)
# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Roberts Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
Prewitt算子实验代码和结果:
import cv2
import numpy as np
# 读取图像
image = cv2.imread('haitan.png', cv2.IMREAD_GRAYSCALE)
# 缩小图像(可选)
# scaled_image = cv2.resize(image, None, fx=0.5, fy=0.5)
# 定义Prewitt算子
prewitt_x = np.array([[-1, 0, 1],
[-1, 0, 1],
[-1, 0, 1]])
prewitt_y = np.array([[-1, -1, -1],
[0, 0, 0],
[1, 1, 1]])
# 应用Prewitt算子进行边缘检测
edges_x = cv2.filter2D(image, -1, prewitt_x)
edges_y = cv2.filter2D(image, -1, prewitt_y)
# 合并x和y方向的边缘检测结果
edges = cv2.addWeighted(edges_x,