影象處理三:影象變形forward warping和inverse warping
阿新 • • 發佈:2018-12-10
一、影象變形
假設原影象為f(u,v),扭曲的目標影象是g(x,y)
1. forward warping
在已知影象座標轉換關係x(u,v)和y(u,v),直接把原圖座標對映到轉換後圖像相對應的位置上,近似取整得到結果。
帶來的問題:新圖上有很多點並不規整。
2. inverse warping
對於每個獲得新座標(x,y),用逆向對映函式u(x,y),v(x,y)找到它在原圖上對應的位置(u,v),然後g(x,y)=f(u,v)。若點算出來不在格子上,用插值方法獲得畫素值。
二、python影象變形
import cv2 import math import numpy as np #載入一個灰度影象 image = cv2.imread('F:/a.jpg',cv2.IMREAD_GRAYSCALE) #獲取高、寬 rows,cols = image.shape ''' rows = height (y軸) cols = width (X軸) ''' #建立一個空影象 output = np.zeros(image.shape,dtype = image.dtype) #垂直方向變形 for i in range(rows): for j in range(cols): offset_x = int(50.0*math.cos(2*math.pi*i/180.0)) offset_y = 0 if j+offset_x < cols:#X軸方向 output[i,j] = image[i,(j+offset_x)%cols] else: output[i,j] = 255 #cv2.imshow('Original Image',image) cv2.imwrite("F:/b.jpg",output) #cv2.imshow('Vertical wave',output) #水平方向變形 for i in range(rows): for j in range(cols): offset_x = 0 offset_y = int(50.0*math.sin(2*math.pi*j/180.0)) if i+offset_y < rows:#Y軸方向 output[i,j] = image[(i+offset_y)%rows,j] else: output[i,j] = 255 #cv2.imshow('Horizontal wave',output) cv2.imwrite("F:/c.jpg",output) #垂直+水平方向變形 for i in range(rows): for j in range(cols): offset_x = int(50.0*math.cos(2*math.pi*i/180)) offset_y = int(50.0*math.sin(2*math.pi*j/180)) if j+offset_x < cols and i+offset_y < rows: output[i,j] = image[(i+offset_y)%rows,(j+offset_x)%cols] else: output[i,j] = 255 #cv2.imshow('Vertical & Horizontal wave',output) cv2.imwrite("F:/d.jpg",output) #凹形 for i in range(rows): for j in range(cols): offset_x = int(128.0*math.sin(2*math.pi*i/(2*cols))) offset_y = 0 if j+offset_x < cols: output[i,j] = image[i,(j+offset_x)%cols] else: output[i,j] = 255 #cv2.imshow('Concave wave',output) cv2.imwrite("F:/e.jpg",output) cv2.waitKey()
原圖:
(1)垂直方向變形
(2)水平方向變形
(3)垂直+水平方向變形
(4)凹形
三、附:計算二維曲線長度
import numpy as np from mpl_toolkits.mplot3d import * import matplotlib.pyplot as plt ## 二維空間曲線,採用引數形式 def curve_param_2d(dt=0.0001,plot=True): dt = dt # 變化率 t = np.arange(0,2*np.pi, dt) x = t*np.cos(t) y = t*np.sin(t) # print(len(t)) area_list = [] # 儲存每一微小步長的曲線長度 # 下面的方式是迴圈實現 # for i in range(1,len(t)): # # 計算每一微小步長的曲線長度,dx = x_{i}-x{i-1},索引從1開始 # dl_i = np.sqrt( (x[i]-x[i-1])**2 + (y[i]-y[i-1])**2 ) # # 將計算結果儲存起來 # area_list.append(dl_i) # 更加pythonic的寫法 area_list = [np.sqrt( (x[i]-x[i-1])**2 + (y[i]-y[i-1])**2 ) for i in range(1,len(t))] area = sum(area_list)# 求和計算曲線在t:[0,2*pi]的長度 print("二維引數曲線長度:{:.4f}".format(area)) if plot: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x,y) plt.title("2-D Parameter Curve") plt.show() ## 二維空間曲線 def curve_2d(dt=0.0001,plot=True): dt = dt # 變化率 t = np.arange(-6,10, dt) x = t y = x**3/8 - 4*x + np.sin(3*x) # print(len(t)) area_list = [] # 儲存每一微小步長的曲線長度 # for i in range(1,len(t)): # # 計算每一微小步長的曲線長度,dx = x_{i}-x{i-1},索引從1開始 # dl_i = np.sqrt( (x[i]-x[i-1])**2 + (y[i]-y[i-1])**2 ) # # 將計算結果儲存起來 # area_list.append(dl_i) area_list = [np.sqrt( (x[i]-x[i-1])**2 + (y[i]-y[i-1])**2 ) for i in range(1,len(t))] area = sum(area_list)# 求和計算曲線在t:[0,2*pi]的長度 print("二維曲線長度:{:.4f}".format(area)) if plot: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x,y) plt.title("2-D Curve") plt.show() if __name__ == '__main__': curve_param_2d(plot=True) curve_2d(plot=True)