1. 程式人生 > >影象處理三:影象變形forward warping和inverse warping

影象處理三:影象變形forward warping和inverse warping

一、影象變形

假設原影象為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)