【图像处理opencv】_图像边缘
生活随笔
收集整理的這篇文章主要介紹了
【图像处理opencv】_图像边缘
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄
0 程序環(huán)境與所學(xué)函數(shù)
1 Prewitt、Robert 算子
?2 sobel 、scharr算子
3 Laplacian 、 LoG算子
?4 Canny邊緣檢測
5 Canny邊緣檢測底層代碼實(shí)現(xiàn)
0 程序環(huán)境與所學(xué)函數(shù)
本章程序運(yùn)行需要導(dǎo)入下面三個(gè)庫,并定義了一個(gè)顯示圖像的函數(shù)
import cv2 as cv import numpy as np import matplotlib.pyplot as pltdef show(img):if img.ndim == 2:plt.imshow(img, cmap='gray')else:plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))plt.show()所學(xué)函數(shù)
Premitt、Roberts算子
cv.filter2D(img, -1, kernel)Sobel、Scharr算子
cv.Sobel(img, cv.CV_16S, 1, 0, ksize=3) cv.Scharr(img, cv.CV_64F, 0, 1, ksize=3)Laplacian、LoG算子
cv.Laplacian(img, cv.CV_16S)Canny邊緣檢測
cv.Canny(img, 20, 200)1 Prewitt、Robert 算子
Prewitt原理:紅色矩陣代表兩個(gè)不同方向的算子(水平方向與豎直方向)
效果
?編程實(shí)現(xiàn)
# Prewitt算子 img = cv.imread('pic/gift500x500.jpg', 0)kx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=np.float32) ky = np.array([[-1,0, 1], [-1,0, 1], [-1, 0, 1]], dtype=np.float32)imgx = cv.filter2D(img, cv.CV_16S, kx) #CV_16S是數(shù)據(jù)類型 imgy = cv.filter2D(img, cv.CV_16S, ky)absX = cv.convertScaleAbs(imgx) absY = cv.convertScaleAbs(imgy)img_prewitt = cv.add(absX, absY) # np.uint8 show(img_prewitt)顯示
# 銳化 img_pre_sharp1 = cv.addWeighted(img, 0.9, img_prewitt, 0.2, 0) img_pre_sharp2 = cv.add(img, img_prewitt) cv.imwrite('pic/gift_sharp.jpg', np.hstack([img, img_pre_sharp1, img_pre_sharp2]))?Roberts算子原理
?效果
?程序?qū)崿F(xiàn)
# Roberts算子 img = cv.imread('pic/gift500x500.jpg', 0)kx = np.array([[-1, 0], [0, 1]], dtype=np.float32) ky = np.array([[0, -1], [1, 0]], dtype=np.float32)imgx = np.abs(cv.filter2D(img, cv.CV_16S, kx)) imgy = np.abs(cv.filter2D(img, cv.CV_16S, ky))img_robert = cv.convertScaleAbs(np.abs(imgx) + np.abs(imgy)) # np.uint8show(np.hstack([img, img_robert]))顯示
?2 sobel 、scharr算子
原理
?sobel算子編程實(shí)現(xiàn)
#sobel算子 img = cv.imread('pic/bookshelf500x333.jpg', 0) show(img)grad_x = cv.Sobel(img, cv.CV_16S, 1, 0, ksize=3)#1表示dx工作0表示dy不工作 grad_y = cv.Sobel(img, cv.CV_16S, 0, 1, ksize=3)grad_xabs = np.abs(grad_x) grad_yabs = np.abs(grad_y) grad_xy = grad_xabs + grad_yabsshow(np.hstack([img, grad_xabs, grad_yabs, grad_xy]))顯示
??Scharr算子編程實(shí)現(xiàn)
img = cv.imread('pic/bookshelf500x333.jpg', 0)grad_x = np.abs(cv.Scharr(img, -1, 1, 0)) grad_y = np.abs(cv.Scharr(img, -1, 0, 1)) img_grad = cv.add(grad_x, abs(grad_y))show(np.hstack([img, img_grad])) show(np.hstack([grad_x, grad_y]))顯示
3 Laplacian 、 LoG算子
原理:
?
?效果
?Laplacian算子編程實(shí)現(xiàn)
img = cv.imread('pic/notebook500x333.jpg', 0)img_lap = cv.Laplacian(img, cv.CV_16S, ksize=5, scale=0.2)img_lap2 = np.abs(img_lap).clip(0, 255) show(np.hstack([img, img_lap2]))顯示
?LoG算子編程實(shí)現(xiàn)
img = cv.imread('pic/notebook500x333.jpg', 0)img_g = cv.GaussianBlur(img, (3,3), 0) img_log = cv.Laplacian(img_g, cv.CV_16S, ksize=5, scale=0.2)img_log2 = np.abs(img_log).clip(0, 255) show(np.hstack([img, img_log2]))顯示
?4 Canny邊緣檢測
原理:
?效果
?編程實(shí)現(xiàn)
img = cv.imread('pic/notebook500x333.jpg', 0)img_canny = cv.Canny(img, 20, 200) #小于20設(shè)為0大于200設(shè)為255 show(np.hstack([img, img_canny]))顯示
5 Canny邊緣檢測底層代碼實(shí)現(xiàn)
原理
?
?代碼實(shí)現(xiàn)
img = cv.imread('pic/notebook500x333.jpg', 0)# 1. 平滑 img_blur = cv.GaussianBlur(img, (5,5), 2)# 2. 計(jì)算梯度 gradx = cv.Sobel(img_blur, cv.CV_64F, 1, 0) grady = cv.Sobel(img_blur, cv.CV_64F, 0, 1) R = np.abs(gradx) + np.abs(grady) T = np.arctan(grady / (gradx + 1e-3))# 3. 細(xì)化邊緣 h, w = R.shape img_thin = np.zeros_like(R)for i in range(1, h-1):for j in range(1, w-1):theta = T[i,j]if -np.pi / 8 <= theta < np.pi / 8:if R[i,j] == max([R[i,j], R[i,j-1], R[i, j+1]]):img_thin[i,j] = R[i,j]elif -3 * np.pi / 8 <= theta < -np.pi / 8:if R[i,j] == max([R[i,j], R[i-1,j+1], R[i+1,j-1]]):img_thin[i,j] = R[i,j]elif np.pi / 8 <= theta < 3 * np.pi / 8:if R[i,j] == max([R[i,j], R[i-1,j-1], R[i+1,j+1]]):img_thin[i,j] = R[i,j] else:if R[i,j] == max([R[i,j], R[i-1,j], R[i+1,j]]):img_thin[i,j] = R[i,j]show(img_thin)th1 = 20 th2 = 200h, w = img_thin.shape img_edge = np.zeros_like(img_thin, dtype=np.uint8)for i in range(1, h-1):for j in range(1, w-1):if img_thin[i,j] >= th2:img_edge[i,j] = img_thin[i,j]elif img_thin[i,j] > th1:around = img_thin[i-1:i+2, j-1:j+2]if around.max() >= th2:img_edge[i,j] = img_thin[i,j]show(img_edge)?
?
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【图像处理opencv】_图像边缘的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【图像处理opencv】_图像锐化
- 下一篇: 【python进阶】_多线程多进程