图像分割1
# 在绘图中显示中文字体,而非乱码
from pylab import mpl
mpl.rcParams["font.sans-serif"] = ["SimHei"]
# 在绘图中显示中文字体,而非乱码
from pylab import mpl
mpl.rcParams["font.sans-serif"] = ["SimHei"]
任选两种本章学过的算法(边缘检测或图像分割算法均可),对一张图像进行分割或边缘检测,并简要叙述算法原理、优缺点和实验发现。
#算法一 边缘检测
img =cv2.imread(图片路径, cv2.IMREAD_GRAYSCALE)
plt.subplot(1, 1, 1)
plt.imshow(img, 'gray')
plt.title("原图")
plt.xticks([])
plt.yticks([])
plt.show()
kernel_lp = np.array([[0,-1,0], [-1,4,-1], [0,-1,0]])
kernel_lp3 = np.array([[0,-1,0], [-1,4,-1], [0,-1,0], [8,-1,4], [6,-1,1]])
kernel_LoG = np.array([[-2,-4,-4,-4,-2], [-4,0,8,0,-4], [-4,8,24,8,-4], [-4,0,8,0,-4], [-2,-4,-4,-4,-2]])
filtered_lp = cv2.filter2D(img, cv2.CV_16S, kernel_lp)
lp_img = cv2.convertScaleAbs(filtered_lp)
filtered_lp1 = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
lp_img1 = cv2.convertScaleAbs(filtered_lp1)
filtered_LoG = cv2.filter2D(img, cv2.CV_16S, kernel_LoG)
LoG_img = cv2.convertScaleAbs(filtered_LoG)
title_list = ["拉普拉斯算子-3", "拉普拉斯算子(调包-3)", "LoG算子"]
img_list = [lp_img,lp_img1,LoG_img]
for i in range(3):
plt.subplot(3, 1, i+1)
plt.imshow(img_list[i], 'gray')
plt.title(title_list[i])
plt.xticks([])
plt.yticks([])
plt.show()
#算法二 图像分割算法
img =cv2.imread(r"C:\Users\zhang\Desktop\IMG_20230409_131124.jpg", cv2.IMREAD_GRAYSCALE)
plt.subplot(2,2,1), plt.imshow(img, 'gray'), plt.title('原始图像'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2), plt.hist(img.ravel(), 256, [0, 256])
plt.title('直方图'), plt.xlim([0, 256])
zmin = np.min(img)
zmax = np.max(img)
T0 = int((zmin + zmax) / 2)
eps = 1
while True:
mu0 = img[img < T0].mean()
mu1 = img[img > T0].mean()
T1 = (mu0 + mu1) / 2
if abs(T1 - T0) < eps:
break
T0 = T1
T0 = int(T0)
_, img_seg_diedai = cv2.threshold(img, T0, 255, 0)
plt.subplot(2,2,3), plt.imshow(img_seg_diedai, 'gray'), plt.title('迭代法'), plt.xticks([]), plt.yticks([])
thres, img_seg_otsu = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
plt.subplot(2,2,4), plt.imshow(img_seg_otsu, 'gray'), plt.title('大津法'), plt.xticks([]), plt.yticks([])
plt.show()
二阶导数边界检测:
二阶导数利用过零点来检测边界。
过零点检测步骤:假设滤波后图像为g(x,y)
(1)取出以p为中心的一个3*3邻域,p在左/右、上/下和两个对角方向中某一方向的邻域像素二阶导数值符号不同。
(2)g(x,y)在某一个方向的邻域像素响应值差的绝对值超过一个阈值,则说明该点是一个过零点。
二阶导数边界检测算子:
(1)拉普拉斯算子,具备各向同性的性质。
由于其无方向,故只需一个模板就可以进行边界检测。
对于阶跃型边界定位较为准确,但对噪声的敏感性较强,容易造成不连续的边界检测。
(2)LoG算子:拉普拉斯算子的改进,通常采用拉普拉斯-高斯算子(LoG)先进行图像滤波,抑制噪声, 然后对滤波图像计算二阶导数,以提高边界检测能力。
优缺点:
1.拉普拉斯算子:
优点:计算简单,对边缘的响应强烈。
缺点:对噪声敏感,可能会产生虚假边缘。
2.高斯拉普拉斯算子:
优点:通过高斯平滑减少噪声影响,边缘检测更准确。
缺点:计算复杂度较高,对参数(如σ)的选择敏感。
发现:
在噪声较多的图像中,拉普拉斯算子会产生许多虚假边缘。而高斯拉普拉斯算子在平滑图像的同时检测边缘,效果通常比拉普拉斯算子更好,尤其是在噪声较多的情况下。选择合适的σ值对高斯拉普拉斯算子的性能有很大影响。
迭代阈值法:
根据当前阈值,通过某种规则估算一个更优的阈值,重复执行该过程,直到相邻两次的阈值差小于某个指定的参数,此时认为算法收敛,否则继续迭代。
(1)估计初始阈值。
(2)阈值将图像灰度值分成2类,大于阈值的灰度值组成,小于阈值的灰度值组成,分别计算和的灰度均值和。
(3)计算和的平均值
。
(4)如果大于某个预定义的参数,则将赋予,执行第(2)步;否则,算法收敛,采用阈值分割图像。
当目标和背景呈现双峰分布时,迭代阈值法一般会得到好的分割结果。
通常将图像中最小灰度值和最大灰度值的平均值作为初始阈值。
Otsu阈值法:
Otsu阈值法认为最优的阈值应使得分割后的两类(前景和背景)的类间方差最大。
优缺点:
迭代阈值法:
优点:自适应性强,不需要人为选择阈值。
缺点:对于直方图双峰不明显的图像,效果可能不佳;计算量较大,速度较慢。
Otsu阈值法:
优点:自动性强,计算效率高,适用于全局阈值。
缺点:对于光照不均匀或噪声干扰大的图像,效果可能不佳。