OpenCV Python學習筆記(七)

# -*-coding:utf-8

# 幾何變換
# 目標:
#   幾個變換,移動,旋轉,仿射變換等
#   函數:cv2.getPerspectiveTransform()
# 變換 OpenCV提供了兩個變換函數,cv2.warpAffine和cv2.warpPerspective
# 使用這兩個函數你可以實現所有類型的變換
# cv2.warpAffine 接收的參數是 2×3 的變換矩陣
# cv2.warpPerspective 接收的參數是 3×3 的變換矩陣


# 擴展縮放:cv2.resize()
import cv2
import numpy as np

# img = cv2.imread("02.jpg")
# # print img.shape
# # # (1378L, 960L, 3L)
#
# # # 下面的None本應該是輸出圖像的尺寸,但是因爲後邊我們設置了縮放因子(fx,fy)
# # # 因此這裏爲None
# res = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
# # # 另一種表達方式
# # width, height = img.shape[:2]
# # res = cv2.resize(img, (0.5*width, 0.5*height),interpolation=cv2.INTER_CUBIC)
# print res.shape
# # (689L, 480L, 3L)
# cv2.imshow("img", img)
# cv2.imshow("res", res)
# if cv2.waitKey(0) & 0xFF == 27:
#     cv2.destroyAllWindows()

# 平移

# 平移就是將對象換一個位置。如果你要沿(x,y)方向移動,移動的距離 是(tx,ty),
# 你可以以下面的方式構建移動矩陣:
#       |1 0 tx|
#  M =  |      |
#       |0 1 ty| 
# 你可以使用 Numpy 數組構建這個矩陣(數據類型是 np.float32)
# 然後把它傳給函數 cv2.warpAffine()
# img = cv2.imread("02.jpg")
# rows, cols, ch = img.shape
# M = np.float32([[1, 0 , 100],[0, 1, 50]])           # 構建矩陣
# res = cv2.warpAffine(img, M, (cols, rows))
# cv2.imshow("img", img)
# cv2.imshow("res", res)
# if cv2.waitKey(0)&0xFF == 27:
#     cv2.destroyAllWindows()

# 函數 cv2.warpAffine() 的第三個參數的是輸出圖像的大小,格式應該是圖像的(寬,高)
# 應該記住的是圖像的寬對應的是列數,高對應的是行數

# 旋轉
# 對一個圖像旋轉角度 θ, 需要使用到下面形式的旋轉矩陣。
# M =   cosθ −sinθ
#       sinθ cosθ  
# 但是 OpenCV 允許你在任意地方進行旋轉,但是旋轉矩陣的形式應該修
# 改爲  
# M =   α β (1−α)·center.x−β ·center.y
#      −β α β ·center.x + (1−α)·center.x  
# 其中:
#       α = scale·cosθ
#       β = scale·sinθ
# 爲了構建這個旋轉矩陣,OpenCV提供了一個函數:cv2.getRotationMatrix2D。
#
# f_img = cv2.imread("02.jpg")
# img = cv2.resize(f_img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
# rows, cols, ch = img.shape
# # 這裏的第一個參數爲旋轉中心,第二個爲旋轉角度,第三個爲旋轉後的縮放因子
# # 可以通過設置旋轉中心,縮放因子,以及窗口大小來防止旋轉後超出邊界的問題
# M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.6)
# # 第三個參數是輸出圖像的尺寸中心
# dst=cv2.warpAffine(img,M,(2*cols,2*rows))
# while(1):
#     cv2.imshow('img',dst)
#     if cv2.waitKey(1)&0xFF==27:
#         break
# cv2.destroyAllWindows()

# 仿射變換(Affine Transformation或 Affine Map)是一種二維座標到二維座標之間的線性變換,
# 它保持了二維圖形的“平直性”(即:直線經過變換之後依然是直線)和
# “平行性”(即:二維圖形之間的相對位置關係保持不變,平行線依然是平行線,且直線上點的位置順序不變)。
# 放射變換可以寫爲如下的形式:
#    x1 = a1*x0 + b1*y0 + c1
#    y1 = a2*x0 + b2*y0 + c2
# 或者用矩陣表示(意思一下)
#   |x1|   |a1 b1 c1|  |x|
#   |  | = |        |* |y|
#   |y1|   |a2 b2 c2|  |1|
# 仿射變換簡單點說可以是有平移、錯切、縮放、反轉、旋轉複合而成
# 在OpenCV中爲了創建這個矩陣需要從原圖像中找到三個點以及他們在輸出圖像中的位置
# 然後 cv2.getAffineTransform 會創建一個 2x3 的矩陣
# 最後這個矩陣會被傳給函數 cv2.warpAffine()

# img = cv2.imread("02.jpg")
# rows, cols, ch = img.shape
#
# pos1 = np.float32([[50, 50], [200, 50], [50, 200]])       # 原始圖像中的點
# pos2 = np.float32([[10, 100], [200, 50], [100, 250]])     # 變換後原圖中的點應該在的位置
#
# M = cv2.getAffineTransform(pos1, pos2)
#
# dst = cv2.warpAffine(img, M, (cols, rows))  # (寬, 高)的形式
# cv2.imshow("img", img)
# cv2.imshow("dst", dst)
# if cv2.waitKey(0)&0xFF == 27:
#     cv2.destroyAllWindows()


# 透視變換:在不同的視覺拍攝同一個物體,會有不同的圖像,透視變換就是類似於改變拍攝物體的角度(視覺),故稱透視變換
# 對於視角變換,我們需要一個 3x3 變換矩陣。在變換前後直線還是直線
# 要構建這個變換矩陣,你需要在輸入圖像上找 4 個點,以及他們在輸出圖 像上對應的位置
# 這四個點中的任意三個都不能共線
# 這個變換矩陣可以有 函數 cv2.getPerspectiveTransform() 構建
# 然後把這個矩陣傳給函數 cv2.warpPerspective

img = cv2.imread("02.jpg")
rows, cols, ch = img.shape

pos1 = np.float32([[56, 65], [368, 52], [28, 387], [398, 390]])             # 原圖像的點
pos2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])                 # 變換後pos1點在新圖上點的位置

M = cv2.getPerspectiveTransform(pos1, pos2)                                 # 形成透視變換的矩陣

dst = cv2.warpPerspective(img, M, (cols, rows))

cv2.imshow("img", img)
cv2.imshow("dst", dst)
if cv2.waitKey(0)&0xFF == 27:
    cv2.destroyAllWindows()

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