opencv: Canny邊緣檢測(圖示+源碼)

綜述:

Canny 邊緣檢測是一種非常流行的邊緣檢測算法。

滯後閾值參照表:

圖像的灰度梯度

判定結果

> maxVal

真的邊界

< minVal

非邊界

minVal < … < maxVal

如果這個點是否與某個被確定爲真正的邊界點相連,就認爲它也是邊界點,如果不是就拋棄

實驗思路:

  1. 設置對照試驗,一組在Canny邊緣檢測前 不經過 高斯濾波處理,一組 有先經過 高斯濾波處理(由於邊緣檢測容易受到噪聲影響,預先使用 5x5 的高斯濾波器 去除噪聲);
  2. 在多組不同的 滯後閥值 的設定下,分別進行Canny邊緣檢測;
  3. 將兩組邊緣檢測結果以圖片格式分別存入 without_with_Gaussian_filterpretreated_with_Gaussian_filter 兩個文件夾;
  4. 依次從這兩個文件夾中取出同名圖片,左右拼接在一起(左半邊是未經過高斯濾波的邊緣檢測結果,右邊是已預先經過高斯濾波處理的),存入 concatenate 文件夾 。

Demo:

原始圖像

(../pic/girl.jpg):

拼接後的對照圖像

(左半邊是未經過高斯濾波的邊緣檢測結果,右邊是已預先經過高斯濾波處理的)

minVal = 0, maxVal = 50 (../pic/concatenate/canny_edge[000,050].jpg):

minVal = 0, maxVal = 100 (../pic/concatenate/canny_edge[000,100].jpg):

minVal = 0, maxVal = 150 (../pic/concatenate/canny_edge[000,150].jpg):

minVal = 0, maxVal = 200 (../pic/concatenate/canny_edge[000,200].jpg):

minVal = 0, maxVal = 250 (../pic/concatenate/canny_edge[000,250].jpg):

minVal = 50, maxVal = 100 (../pic/concatenate/canny_edge[050,100].jpg):

minVal = 50, maxVal = 150 (../pic/concatenate/canny_edge[050,150].jpg):

minVal = 50, maxVal = 200 (../pic/concatenate/canny_edge[050,200].jpg):

minVal = 50, maxVal = 250 (../pic/concatenate/canny_edge[050,250].jpg):

minVal = 100, maxVal = 150 (../pic/concatenate/canny_edge[100,150].jpg):

minVal = 100, maxVal = 200 (../pic/concatenate/canny_edge[100,200].jpg):

minVal = 100, maxVal = 250 (../pic/concatenate/canny_edge[100,250].jpg):

minVal = 150, maxVal = 200 (../pic/concatenate/canny_edge[150,200].jpg):

minVal = 150, maxVal = 250 (../pic/concatenate/canny_edge[150,250].jpg):

minVal = 200, maxVal = 250 (../pic/concatenate/canny_edge[200,250].jpg):

附上自己寫的實驗代碼:

# -*- coding: utf-8 -*-

import cv2
import os
import numpy as np

Min_Max = [(0, 50), (0, 100), (0, 150), (0, 200), (0, 250),
           (50, 100), (50, 150), (50, 200), (50, 250),
           (100, 150), (100, 200), (100, 250),
           (150, 200), (150, 250),
           (200, 250)]
pic = cv2.imread('../pic/girl.jpg')


try:
    os.mkdir('../pic/pretreated_with_Gaussian_filter')
    os.mkdir('../pic/without_Gaussian_filter')
    os.mkdir('../pic/concatenate')
except OSError:
    pass


# 不經過 高斯濾波處理 去除噪聲
for min_max in Min_Max:
    min = min_max[0]
    max = min_max[1]
    edges = cv2.Canny(pic, min, max)
    edges = np.expand_dims(edges, axis=2)
    # cv2.imshow('canny_edge[{:>03},{:>03}]'.format(min, max), edges)
    # cv2.waitKey(2000)
    # cv2.destroyAllWindows()
    cv2.imwrite('../pic/without_Gaussian_filter/canny_edge[{:>03},{:>03}].jpg'.format(min, max), edges)


# 有先經過 高斯濾波處理 去除噪聲
pic = cv2.GaussianBlur(src=pic, ksize=(5, 5), sigmaX=0, sigmaY=0)

for min_max in Min_Max:
    min = min_max[0]
    max = min_max[1]
    edges = cv2.Canny(pic, min, max)
    edges = np.expand_dims(edges, axis=2)
    # cv2.imshow('canny_edge[{:>03},{:>03}]'.format(min, max), edges)
    # cv2.waitKey(2000)
    # cv2.destroyAllWindows()
    cv2.imwrite('../pic/pretreated_with_Gaussian_filter/canny_edge[{:>03},{:>03}].jpg'.format(min, max), edges)


# 組合顯示圖片 進行對比
image_no_gaussian_paths = [os.path.join('../pic/without_Gaussian_filter', path) for path in os.listdir('../pic/without_Gaussian_filter')]
image_with_gaussian_paths = [path.replace('without_Gaussian_filter', 'pretreated_with_Gaussian_filter') for path in image_no_gaussian_paths]

for (image_no_gaussian_path, image_with_gaussian_path) in zip(image_no_gaussian_paths, image_with_gaussian_paths):
    image_no_gaussian = cv2.imread(image_no_gaussian_path)
    image_with_gaussian = cv2.imread(image_with_gaussian_path)
    concat_pic = np.concatenate([image_no_gaussian, image_with_gaussian], axis=1)
    # cv2.imshow(image_no_gaussian_path[-23:-4], concat_pic)
    # cv2.waitKey(2000)
    # cv2.destroyAllWindows()
   cv2.imwrite('../pic/concatenate/{:>03}.jpg'.format(image_no_gaussian_path[-23:-4]), concat_pic)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章