天天看點

圖像處理之圖像的邊緣、輪廓檢測

圖像的邊緣、輪廓檢測在人類視覺和計算機視覺中均起着重要的作用。人類能夠僅憑一張背景剪影或一張草圖就能識别出物體的類型和姿态。OpenCV提供了許多邊緣檢測l濾波函數,包括Laplacian( )、Sobel()以及Scharr()。這些函數都能将邊緣轉化為白色或其他飽和的顔色,将非邊緣轉化為黑色,但是,這些函數不能有效的區分噪聲錯誤的判斷為邊緣。解決這個問題的辦法是對圖像進行模糊處理。這裡介紹一種很友善卻很實用的函數——Canny邊緣檢測。

Canny函數中包含兩個門檻值這也是與其他邊緣檢測函數不同的地方。門檻值是來确定哪裡是邊緣位置。門檻值越低,能夠檢測出的邊線越多,結果也就越容易受到圖檔噪聲的影響,并且越容易從圖像中挑出不相關的特性。與此相反,一個高的門檻值将會遺失細的或者短的線段。是以,Canny函數中要設定兩個門檻值是有不同用處的。高的那個門檻值是将要提取輪廓的物體與背景區分開來,就像門檻值分割的那個參數一樣,是決定目标與背景對比度的,低的那個門檻值是用來平滑邊緣的輪廓,有時高的門檻值設定太大了,可能邊緣輪廓不連續或者不夠平滑,通過低門檻值來平滑輪廓線,或者使不連續的部分連接配接起來。

import cv2
from matplotlib import pyplot as plt
img = cv2.imread("water_coins.jpg", 0)
edges = cv2.Canny(img, 200, 300)
plt.subplot(1,2,1), plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1,2,2), plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
           
圖像處理之圖像的邊緣、輪廓檢測

那麼對圖像的輪廓檢測,先要将圖像二值化操作,然後再調用findContours()函數。

import cv2
import numpy as np

img = np.zeros((200, 200), dtype=np.uint8)
img[50:150, 50:150] = 255
# 二值化處理
ret, th = cv2.threshold(img, 127, 255, 0)
# findcontours()函數。有三個參數:輸入圖像、層次類型和輪廓逼近方法。
# 由函數傳回的層次樹相當重要:cv2.RETR_TREE參數會得到圖像中輪廓的整體層次結構(contours)。如果隻想得到最外面的輪廓,可以使用cv2.RETR_EXTERNAL。這對消除包含在其他輪廓中的輪廓很有用。
# 第三個參數有兩種方法:
#cv2.CHAIN_APPROX_NONE存儲所有的輪廓點,相鄰的兩個點的像素位置差不超過1,即max(abs(x1-x2),abs(y2-y1))==1 cv2.CHAIN_APPROX_SIMPLE壓縮水準方向,垂直方向,對角線方向的元素,隻保留該方向的終點坐标,例如一個矩形輪廓隻需4個點來儲存輪廓資訊cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
image, contours, hierarchy = cv2.findContours(th, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 色彩空間轉換函數cv2.cvtColor()
color = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2BGR)
# 畫出輪廓,-1,表示所有輪廓,畫筆顔色為(0, 255, 0),即Green,粗細為2
img = cv2.drawContours(color, contours, -1, (0, 255, 0), 2)
cv2.imwrite("contours.png", color)
cv2.waitKey()
cv2.destroyAllWindows()
           
圖像處理之圖像的邊緣、輪廓檢測

參考:

《OpenCV 3計算機視覺Python語言實作》

  OpenCV幫助文檔:http://docs.opencv.org/3.0.0/da/d22/tutorial_py_canny.html

繼續閱讀