一、什麼是邊緣檢測?

圖像邊緣是指圖像中像素強度發生顯著變化的區域(比如物體的輪廓、文字的邊界等)。邊緣檢測的目的就是識別這些變化區域,從而簡化圖像信息、突出目標特徵。在計算機視覺中,邊緣檢測是目標識別、圖像分割、特徵提取的基礎步驟,廣泛應用於人臉識別、自動駕駛、醫學影像分析等領域。

二、Python OpenCV環境準備

在開始前,請確保已安裝Python和OpenCV庫。如果未安裝,可通過以下命令快速安裝:

pip install opencv-python

三、邊緣檢測核心流程

邊緣檢測通常分爲三步:圖像預處理(灰度化、降噪)、邊緣檢測算法(提取梯度信息)、結果可視化

四、Canny邊緣檢測(核心算法)

Canny邊緣檢測是OpenCV中最常用的邊緣檢測算法,由John Canny於1986年提出。它通過多步梯度計算和非極大值抑制,能生成清晰、連續的邊緣,是工業界和科研中效果最好的邊緣檢測方法之一。

Canny邊緣檢測步驟

  1. 灰度化:將彩色圖像轉爲灰度圖(減少計算量)。
  2. 高斯模糊:消除圖像噪聲(噪聲會干擾邊緣檢測)。
  3. 計算梯度:用Sobel算子計算圖像的梯度幅值和方向。
  4. 非極大值抑制:保留梯度方向上的局部最大值,細化邊緣。
  5. 雙閾值篩選:設置低閾值(low_threshold)和高閾值(high_threshold),篩選出真正的邊緣。

代碼實現:Canny邊緣檢測

import cv2
import numpy as np

# 1. 讀取圖像(替換爲你的圖像路徑,如'./test.jpg')
image = cv2.imread('test.jpg')
if image is None:
    print("圖像讀取失敗,請檢查路徑!")
    exit()

# 2. 灰度化處理(轉爲單通道灰度圖)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 3. 高斯模糊(降噪,核大小建議5x5)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)  # 標準差爲0時由核大小自動計算

# 4. Canny邊緣檢測(參數:原圖、低閾值、高閾值)
edges = cv2.Canny(blurred, 50, 150)  # 低閾值50,高閾值150

# 5. 顯示結果
cv2.imshow('Original Image', image)
cv2.imshow('Gray Image', gray)
cv2.imshow('Blurred Image', blurred)
cv2.imshow('Canny Edges', edges)

# 等待按鍵後關閉窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

# (可選)保存結果
cv2.imwrite('canny_edges.jpg', edges)

閾值對結果的影響

Canny的兩個閾值(低、高)決定了邊緣的“敏感度”:
- 低閾值低,高閾值低:會檢測到更多邊緣(包括噪聲導致的僞邊緣)。
- 低閾值高,高閾值高:會漏掉一些細節邊緣,但邊緣更清晰。

嘗試調整閾值(如low=30, high=100low=80, high=200),觀察結果差異:

# 不同閾值對比示例
edges1 = cv2.Canny(blurred, 30, 100)
edges2 = cv2.Canny(blurred, 80, 200)
cv2.imshow('Low Threshold', edges1)
cv2.imshow('High Threshold', edges2)
cv2.waitKey(0)

五、其他經典邊緣檢測算法

除Canny外,OpenCV還提供了其他基於梯度的邊緣檢測算子,原理類似但效果各有特點:

1. Sobel算子

基於梯度的一階導數算法,可分別計算x方向(水平邊緣)和y方向(垂直邊緣)的梯度:

# Sobel算子示例
sobelx = cv2.Sobel(blurred, cv2.CV_64F, 1, 0, ksize=5)  # x方向梯度
sobely = cv2.Sobel(blurred, cv2.CV_64F, 0, 1, ksize=5)  # y方向梯度
sobel_edges = cv2.addWeighted(np.absolute(sobelx), 0.5, np.absolute(sobely), 0.5, 0)
cv2.imshow('Sobel Edges', sobel_edges)

2. Laplacian算子

基於二階導數,對噪聲敏感,需先模糊處理:

laplacian = cv2.Laplacian(blurred, cv2.CV_64F, ksize=3)
laplacian_edges = np.absolute(laplacian)
cv2.imshow('Laplacian Edges', laplacian_edges)

六、實踐與總結

  1. 關鍵技巧
    - 優先對圖像進行高斯模糊(核大小3x3/5x5),減少噪聲干擾。
    - Canny閾值需根據圖像對比度調整(如清晰圖像閾值可設爲50-150,複雜場景可設爲100-200)。
    - 處理彩色圖像時,建議先轉爲灰度圖再進行邊緣檢測。

  2. 常見問題
    - 圖像讀取失敗:檢查路徑是否正確(絕對路徑或相對路徑)。
    - 顯示圖像顏色異常:OpenCV默認讀取爲BGR格式,若需顯示彩色圖,可先用cv2.cvtColor(..., cv2.COLOR_BGR2RGB)轉換。

通過本文,你已掌握Python OpenCV邊緣檢測的基礎流程和核心算法。後續可嘗試在實際項目中調整參數,探索不同場景下的最佳效果。邊緣檢測是計算機視覺的入門基石,打好基礎後可進一步學習圖像分割、目標追蹤等進階內容!

小夜