前言
僅記錄學習過程,有問題歡迎討論
邊緣提取(涉及語義分割):
圖象的邊緣是指圖象局部區域亮度變化顯著的部分,也有正負之分,暗到亮為正
-
求邊緣的幅度:sobel,Canny算子
-
圖像分高頻分量和低頻分量,高頻分量就是灰度變化劇烈的地方(顯眼)
圖像銳化:目的是使圖像的邊緣更加清晰,細節部分更加突出,常用拉普拉斯變化核函數。
邊緣檢測的步驟:邊緣檢測就是提取高頻分量。在邊緣像素值會出現”跳躍“或者較大的變化
- 濾波:邊緣檢測的算法主要是基于圖像強度的一階和二階導數(為0,一階極值),但導數通常對噪聲很敏感,
所以采用濾波減弱噪聲。常見的濾波方法主要有高斯濾波。 - 增強:增強邊緣的基礎是確定圖像各點鄰域強度的變化值并凸顯出顯著變化點。
- 檢測:經過增強的圖像,往往鄰域中有很多點的梯度值比較大,可以采用用閾值化方法來檢測方法來對這些點進行取舍。
Canny邊緣檢測算法:
- 灰度化后高斯濾波:消除噪聲
高斯卷積核大小影響Canny檢測的性能,越大,檢測對噪聲敏感越低,定位誤差也會增大,5*5還行 - 檢測圖像的水平/垂直邊緣:計算梯度—Sobel算子
用類似于[-1,0,1][-2,0,2][-1,0,1]的矩陣來求梯度的幅值,幅值較大的像素點的為邊緣 - 非極大值抑制:去除邊緣檢測帶來的雜散響應
- 搜素局部最大值,抑制非極大值,去除冗余的邊緣。通俗就是找到像素局部最大值,其他值置為0,就可以剔除大部分非邊緣點。
- 沿著梯度方向比較像素點的值,保留最大像素點
- 雙閾值檢測和連接邊緣:滯后閾值法
- 大于高閾值為強邊緣,小于低閾值不是邊緣。介于中間是弱邊緣。
- 閾值的選擇取決于給定輸入圖像的內容,和噪聲點的區別就是是否連續:
相機模型(實際就是坐標系轉化):
針孔相機模型存在四個坐標系:世界坐標系、攝像機坐標系、圖像物理坐標系和圖像像素坐標系。
- 世界坐標系的坐標為Pw(Xw,Yw,Zw),
- 對應的攝像機坐標系坐標為Po(x,y,z),–齊次方程做坐標系變化
- 對應的圖像物理坐標系的坐標為P’(x’,y’),–相似三角的原理等比例
- 對應的圖像像素坐標系的坐標為p(u,v)。–轉化為長度為像素單位!
鏡頭畸變
- 畸變是由于透鏡形狀和制造工藝的誤差造成的,分為徑向畸變和切向畸變。
- 徑向畸變是由于透鏡形狀的曲線造成,分為枕形畸變和桶形畸變。
- 切向畸變是由于透鏡制造工藝的誤差造成的,分為對稱畸變和非對稱畸變。
- 可以通過透視變化(投影為新平面)來矯正畸變圖片
通過4個點(兩組x,y)來確定關系,然后投影新平面圖片
Canny算法和透視變化
"""
1-實現canny算法2-實現透視變換
"""
import cv2
import numpy as np# 實現Canny
def CannyDemo(img, low, high):# 灰度化gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 高斯濾波blur = cv2.GaussianBlur(gray, (5, 5), 0)# 采用sobel 算子求梯度[x,y方向求梯度,找出變化最大的像素點]grad_x = cv2.Sobel(blur, cv2.CV_16S, 1, 0, ksize=3)grad_y = cv2.Sobel(blur, cv2.CV_16S, 0, 1, ksize=3)# 轉回uint8abs_grad_x = cv2.convertScaleAbs(grad_x)abs_grad_y = cv2.convertScaleAbs(grad_y)# 合并梯度dst = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)# 非極大值抑制dst = cv2.Canny(dst, low, high)return dst# 實現透視變化
def getWarpPerspectiveMatrix(img, dst):nums = img.shape[0]x = np.zeros((2 * nums, 8)) # x*warpMatrix=yy = np.zeros((2 * nums, 1))for i in range(0, nums):x_i = src[i, :]y_i = dst[i, :]x[2 * i, :] = [x_i[0], x_i[1], 1, 0, 0, 0,-x_i[0] * y_i[0], -x_i[1] * y_i[0]]y[2 * i] = y_i[0]x[2 * i + 1, :] = [0, 0, 0, x_i[0], x_i[1], 1,-x_i[0] * y_i[1], -x_i[1] * y_i[1]]y[2 * i + 1] = y_i[1]x = np.mat(x)# 用x.I求出x的逆矩陣,然后與y相乘,求出warpMatrixmatrix = x.I * y # 求出a_11, a_12, a_13, a_21, a_22, a_23, a_31, a_32# 之后為結果的后處理matrix = np.array(matrix).T[0]matrix = np.insert(matrix, matrix.shape[0], values=1.0, axis=0) # 插入a_33 = 1matrix = matrix.reshape((3, 3))return matrixif __name__ == '__main__':img = cv2.imread('lenna.png')# canny邊緣檢測# canny = CannyDemo(img, 50,150)# cv2.imshow('canny', canny)# cv2.waitKey(0)# 實現透視變化img1 = cv2.imread('photo1.jpg')src = np.float32([[207, 151], [517, 285], [17, 601], [343, 731]])dst = np.float32([[0, 0], [337, 0], [0, 488], [337, 488]])print(img.shape)# 生成透視變換矩陣;進行透視變換result = getWarpPerspectiveMatrix(src, dst)print("warpMatrix:")print(result)img_perspective = cv2.warpPerspective(img1, result, (337, 488))cv2.imshow("img_perspective", img_perspective)cv2.waitKey(0)