opencv:畸变矫正:透视变换算法的思想与实现
畸變矯正
注意:雖然能夠成功矯正但是也會損失了部分圖像!
透視變換(Perspective Transformation)
概念:
透視變換是將圖片投影到一個新的視平面(Viewing Plane),也稱作投影映射(Projective Mapping)。 我們常說的仿射變換是透視變換的一個特例。 透視變換的目的就是把現(xiàn)實中為直線的物體,在圖片上可能呈現(xiàn)為斜線,通過透視變換轉(zhuǎn)換成直線 的變換。 仿射變換(Affine Transformation或 Affine Map),又稱為仿射映射,是指在幾何中,圖像進行從 一個向量空間進行一次線性變換和一次平移,變換為到另一個向量空間的過程。
思想:
通用的變換公式為:
x,y是原始圖片坐標,對應得到變換后的圖片坐標(X’;Y’;Z’)其中:
可以看作原圖像的數(shù)據(jù)各值與變換后圖像的數(shù)據(jù)各值,對應相等。
令a33=1,展開上面公式,得到一個點的情況:
如果我們要解出上面含有8個未知量(a)的方程,我們需要8個像素點,原圖像4個,新圖像4個。
源點四個坐標分別為A:(x0,y0),(x1,y1),(x2,y2),(x3,y3) 目標點四個坐標分別為B:(X’0,Y’0),(X’1,Y’1),(X’2,Y’2),(X’3,Y’3)
手動代碼實現(xiàn):
import numpy as npdef WarpPerspectiveMatrix(src, dst):assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4#assert:當src的格式等于dst的格式,并且src的格式大于等于4,程序才繼續(xù)運行nums = src.shape[0]A = np.zeros((2*nums, 8)) # A*warpMatrix=BB = np.zeros((2*nums, 1))for i in range(0, nums):A_i = src[i,:]B_i = dst[i,:]A[2*i, :] = [A_i[0], A_i[1], 1, 0, 0, 0,-A_i[0]*B_i[0], -A_i[1]*B_i[0]]B[2*i] = B_i[0]A[2*i+1, :] = [0, 0, 0, A_i[0], A_i[1], 1,-A_i[0]*B_i[1], -A_i[1]*B_i[1]]B[2*i+1] = B_i[1]A = np.mat(A)#用A.I求出A的逆矩陣,然后與B相乘,求出warpMatrixwarpMatrix = A.I * B #求出a_11, a_12, a_13, a_21, a_22, a_23, a_31, a_32#之后為結(jié)果的后處理warpMatrix = np.array(warpMatrix).T[0]warpMatrix = np.insert(warpMatrix, warpMatrix.shape[0], values=1.0, axis=0) #插入a_33 = 1warpMatrix = warpMatrix.reshape((3, 3))return warpMatrixif __name__ == '__main__':print('warpMatrix')src = [[10.0, 457.0], [395.0, 291.0], [624.0, 291.0], [1000.0, 457.0]] #編造的輸入src = np.array(src)dst = [[46.0, 920.0], [46.0, 100.0], [600.0, 100.0], [600.0, 920.0]] #編造的輸出dst = np.array(dst)warpMatrix = WarpPerspectiveMatrix(src, dst)print(warpMatrix)這里就不展示結(jié)果了 重點是思想
opencv接口代碼實現(xiàn):
import cv2 import numpy as npimg = cv2.imread('photo1.jpg')result3 = img.copy()#img = cv2.GaussianBlur(img,(3,3),0) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #轉(zhuǎn)灰度,做單通道計算比較節(jié)省時間 edges = cv2.Canny(gray,50,150,apertureSize = 3) #canny邊緣檢測(僅針對這次的輸入圖片) cv2.imshow("canny", edges)''' 注意這里src和dst的輸入并不是圖像,而是圖像對應的頂點坐標。 ''' src = np.float32([[207, 151], [517, 285], [17, 601], [343, 731]]) dst = np.float32([[0, 0], [337, 0], [0, 488], [337, 488]]) # 生成透視變換矩陣;進行透視變換 m = cv2.getPerspectiveTransform(src, dst) result = cv2.warpPerspective(result3, m, (337, 488)) # (337,488)是輸出圖像大小 cv2.imshow("src", img) cv2.imshow("result", result) cv2.waitKey(0)結(jié)果展示:
分別是:輸入圖片,邊緣提取,透視變換結(jié)果
成功將其原圖片中紙片矯正~
但是注意:雖然成功矯正但是也損失了部分圖像!
總結(jié)
以上是生活随笔為你收集整理的opencv:畸变矫正:透视变换算法的思想与实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到虫是什么预兆
- 下一篇: 梦到粉色的天空是什么意思