数字图像处理课程实习——边缘检测与图像分割

        本次实验的目标主要是为了掌握图像边缘检测和分割的意义和手段,掌握图像边缘检测和分割的方法及应用并通过实验讨论不同算子对边缘检测效果的影响。

        本次实验主要完成了对图像进行Sobel算子边缘检测,对图像进行Prewitt算子边缘检测,对图像进行log算子边缘检测,对图像进行 Canny 算子边缘检测;以及对图像进行固定阈值(分别取了100和150两个阈值)分割,对图像进行迭代阈值分割。并对比分析了不同边缘检测算子的边缘检测效果,不同阈值分割方法的结果。(在考核思考题处还完成了实现Otsu的分割并进行了结果的对比)

代码如下:

from skimage import io,filters,img_as_ubyte, feature
import matplotlib.pyplot as plt
import cv2
import math
import numpy as np

# 读取灰度图
img = io.imread('camera.png', as_gray=True)
#创建画布
plt.figure(num=1,figsize=(8, 4))
#显示原始图像
plt.subplot(2, 3, 1), plt.imshow(img,cmap='gray'),plt.title('original'), plt.axis('off')
# sobel 边缘检测
edges_sobel = filters.sobel(img)
#显示sobel检测后的图像
plt.subplot(2, 3, 2), plt.imshow(edges_sobel, cmap='gray'), plt.title('sobel'), plt.axis('off')

# prewitt 边缘检测
edges_prewitt = filters.prewitt(img)
#显示prewitt检测后的图像
plt.subplot(2, 3, 3), plt.imshow(edges_prewitt, cmap='gray'), plt.title('prewitt'), plt.axis('off')

# log 边缘检测
# 先通过高斯滤波降噪
gaussian = cv2.GaussianBlur(img, (3, 3), 0)
# 再通过拉普拉斯算子做边缘检测
dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize=3)
LOG = cv2.convertScaleAbs(dst)
#显示log检测后的图像
plt.subplot(2, 3, 4), plt.imshow(LOG, cmap='gray'), plt.title('log'), plt.axis('off')

# canny 边缘检测
edges_canny = feature.canny(img, sigma=1.0)
#显示canny检测后的图像
plt.subplot(2, 3, 5), plt.imshow(edges_canny, cmap='gray'), plt.title('canny'), plt.axis('off')
plt.show()

img1 = cv2.imread('camera.png', cv2.IMREAD_GRAYSCALE)
# 固定阈值分割 T=100
_, out1 = cv2.threshold(img1, 100, 255, cv2.THRESH_BINARY)
# 固定阈值分割 T=150
_, out2 = cv2.threshold(img1, 150, 255, cv2.THRESH_BINARY)
# 迭代阈值分割
T = img1.mean()
done=False
while not done:
    t0 = img1[img1 < T].mean()
    t1 = img1[img1 >= T].mean()
    t = (t0 + t1) / 2
    done = abs(T - t) < 1
    T = t
    _, img_iter = cv2.threshold(img1, T, 255, cv2.THRESH_BINARY)

#otsu大津法进行图像分割
# 方法选择为THRESH_OTSU
ret1, th1 = cv2.threshold(img1, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print(f"大津法下作用的阈值为{ret1}")
#创建画布
plt.figure(num=2,figsize=(8, 4))
#分别显示原图像,固定阈值分割后的图像,迭代阈值分割后的图像
plt.subplot(1,5,1), plt.imshow(img1,cmap='gray'), plt.title('original'), plt.axis('off')
plt.subplot(1,5,2), plt.imshow(out1,cmap='gray'), plt.title('fixed100'), plt.axis('off')
plt.subplot(1,5,3), plt.imshow(out2,cmap='gray'), plt.title('fixed150'), plt.axis('off')
plt.subplot(1,5,4), plt.imshow(img_iter,cmap='gray'), plt.title('iter'), plt.axis('off')
plt.subplot(1,5,5), plt.imshow(th1,cmap='gray'), plt.title('otsu'), plt.axis('off')

plt.show()

实验分析与日志

  1. 本实验进行边缘检测,用到了skimage包,故需提前下载并配置好该包。
  2. 通过边缘检测实验,我更加深入地理解了一阶微分算子、二阶微分算子以及在进行检测前平滑与否对检测结果的影响。Sobel算子和Prewitt算子都是一阶微分算子,其在对比度大的点产生较高的响应,故其产生的边缘较粗;而Log算子是用到了拉普拉斯算子这一二阶微分算子,其在对比度大的点产生零交叉,故其能产生更细的边缘,同时其在锐化前先使用了高斯滤波器进行平滑去噪,减轻了噪声对拉普拉斯算子的影响。而canny算子进一步优化,采用了非最大抑制的方法,效果更佳。
  3. 通过对比不同阈值分割法我也更加深入理解了其效果及使用场景的不同。

你可能感兴趣的:(数字图像处理学习专栏,计算机视觉,图像处理,python,pycharm,opencv)