整流图像:插入缺失点

时间:2014-02-25 13:11:30

标签: python opencv image-processing

我有一个图像,我尝试围绕x,y和z轴旋转(整流)。这很好,但我丢失了很多数据。这是我使用的脚本:

# import libraries
import numpy as np
# import dateutil
# import pyparsing
import matplotlib.pyplot as plt
import cv2
import sys
from scipy import *
import Image
import matrotation as rmat
import math
from scipy.interpolate import griddata

# set variable with location of files
working_dir = 'C:\Users\Yorian\Desktop\TU\Stage Shore\python_files\Rectification'
sys.path.append(working_dir)

# C is 3x1 matrix met (Xc, Yc, Zc).transpose()
# neem voor nu: C is nulvector
C = np.zeros((3,1), dtype='float32')

# 3x3 Identity matrix
I = np.identity(3)

# k matrix 3x3, LOAD the center pixel automatically as the point to rate around
K = np.array([[1.49661077e+04, -4.57744650e-13, 0.0],
             [0.0, -1.49661077e+04, 0.0],
             [0.0, 0.0, 1.0]])

# rotatie matrix 1 (3x3) 0 graden om zowel x, y als z as
R1 = rmat.getR(25.0, 45.0, 0.0)

# [I|-C] (Zie Sierds paper) = 
I_extended = np.hstack((I,C))

# P = K*R*I
P1 = K.dot(R1).dot(I_extended)

# rotatie matrix 2
R2 = rmat.getR(0.0, 0.0, 0.0)
P2 = K.dot(R2).dot(I_extended)

# Homography Matrix = H = P_rect * pinv(P) => P2 * pinv(P1)
H = P2.dot(np.linalg.pinv(P1))

# do image transform: x_uv_new = H * x_uv_original

# load image and convert it to grayscale (L)
img = Image.open('c5.jpg').convert('L')

# img.show()
img_array = np.array(img)

height = img_array.shape[0]
width = img_array.shape[1]

U, V = np.meshgrid(range(img_array.shape[1]),
                   range(img_array.shape[0]))
UV = np.vstack((U.flatten(),
                V.flatten())).T
UV_warped = cv2.perspectiveTransform(np.array([UV]).astype(np.float32), H)

UV_warped = UV_warped[0]
UV_warped = UV_warped.astype(np.int)

x_translation = min(UV_warped[:,0])
y_translation = min(UV_warped[:,1])

new_width = np.amax(UV_warped[:,0])-np.amin(UV_warped[:,0])
new_height = np.amax(UV_warped[:,1])-np.amin(UV_warped[:,1])
# new_img_2 = cv2.warpPerspective(img_array, H, (new_height+1, new_width+1))

UV_warped[:,0] = UV_warped[:,0] - int(x_translation)
UV_warped[:,1] = UV_warped[:,1] - int(y_translation)

# create box for image
new_img = np.zeros((new_height+1, new_width+1)) # 0 = black 255 - white background

for uv_pix, UV_warped_pix in zip(UV, UV_warped):
    x_orig = uv_pix[0] # x in origineel
    y_orig = uv_pix[1] # y in origineel
    color = img_array[y_orig, x_orig]

    x_new = UV_warped_pix[0] # new x
    y_new = UV_warped_pix[1] # new y
    new_img[y_new, x_new] = np.array(color)


img = Image.fromarray(np.uint8(new_img))
img.save("testje.jpg")

这很好用。但是我错过了很多信息。旋转越大,我放松的信息就越多。为了获得更多信息,我想:插入缺失的点。我尝试使用grid()执行此操作,但它返回一个如下所示的数组: [楠]

此代码:

# import libraries
import numpy as np
# import dateutil
# import pyparsing
import matplotlib.pyplot as plt
import cv2
import sys
from scipy import *
import Image
import matrotation as rmat
import math
from scipy.interpolate import griddata

# set variable with location of files
working_dir = 'C:\Users\Yorian\Desktop\TU\Stage Shore\python_files\Rectification'
sys.path.append(working_dir)

# C is 3x1 matrix met (Xc, Yc, Zc).transpose()
# neem voor nu: C is nulvector
C = np.zeros((3,1), dtype='float32')

# 3x3 Identity matrix
I = np.identity(3)

# k matrix 3x3, LOAD the center pixel automatically as the point to rate around
K = np.array([[1.49661077e+04, -4.57744650e-13, 0.0],
             [0.0, -1.49661077e+04, 0.0],
             [0.0, 0.0, 1.0]])

# rotatie matrix 1 (3x3) 0 graden om zowel x, y als z as
R1 = rmat.getR(25.0, 45.0, 0.0)

# [I|-C] (Zie Sierds paper) = 
I_extended = np.hstack((I,C))

# P = K*R*I
P1 = K.dot(R1).dot(I_extended)

# rotatie matrix 2
R2 = rmat.getR(0.0, 0.0, 0.0)
P2 = K.dot(R2).dot(I_extended)

# Homography Matrix = H = P_rect * pinv(P) => P2 * pinv(P1)
H = P2.dot(np.linalg.pinv(P1))

# do image transform: x_uv_new = H * x_uv_original

# load image and convert it to grayscale (L)
img = Image.open('c5.jpg').convert('L')

# img.show()
img_array = np.array(img)

height = img_array.shape[0]
width = img_array.shape[1]

U, V = np.meshgrid(range(img_array.shape[1]),
                   range(img_array.shape[0]))
UV = np.vstack((U.flatten(),
                V.flatten())).T
UV_warped = cv2.perspectiveTransform(np.array([UV]).astype(np.float32), H)

UV_warped = UV_warped[0]
UV_warped = UV_warped.astype(np.int)

x_translation = min(UV_warped[:,0])
y_translation = min(UV_warped[:,1])

new_width = np.amax(UV_warped[:,0])-np.amin(UV_warped[:,0])
new_height = np.amax(UV_warped[:,1])-np.amin(UV_warped[:,1])

UV_warped[:,0] = UV_warped[:,0] - int(x_translation)
UV_warped[:,1] = UV_warped[:,1] - int(y_translation)

# create box for image
data = np.zeros((len(UV_warped),1))

for i, uv_pix in enumerate(UV):
    data[i,0] = img_array[uv_pix[1], uv_pix[0]]

grid = griddata(UV_warped, data, (new_width+1, new_height+1), method='linear')

有人可以帮助我从中获取插值的图像吗?

顺便说一句:我使用了warpPerspective函数,就像有人告诉我的那样,但这会拉伸图像,但不会旋转"它

我也看了cv2.inpaint(),但也无法解决这个问题。我找到了这个:http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_photo/py_inpainting/py_inpainting.html但是它就是这样的。我想拍一张照片。

编辑:

我以前用warpTransform执行此操作的代码:

#Importing modules
import json
import urllib2
import numpy as np
import cv2
from scipy import *
import Image

# data is now a dictionairy containing list with dictionairies with the x, y, z, U, V
# example:
# data[cameraID][listnumber] = {'x': x, 'y': y, 'z': z, 'U': U, 'V': V}

T = {} # H is a list of Translation matrices, one for each camera

for cam in data:
    if len(cam) > 4:
        xyz_ar = np.array([[data[cam][0]['x'], data[cam][0]['y']],
                           [data[cam][1]['x'], data[cam][1]['y']],
                           [data[cam][2]['x'], data[cam][2]['y']],
                           [data[cam][3]['x'], data[cam][3]['y']]],np.float32)

        UV_ar = np.array([[data[cam][0]['U'], data[cam][0]['V']],
                          [data[cam][1]['U'], data[cam][1]['V']],
                          [data[cam][2]['U'], data[cam][2]['V']],
                          [data[cam][3]['U'], data[cam][3]['V']]], np.float32)

        T[cam] = cv2.getPerspectiveTransform(UV_ar, xyz_ar)
    else:
        print('niet genoeg meetpunten voor de camera')

# load image
img = cv2.imread('c5.jpg')
rows, cols, channels = img.shape

# warp voor camera 5
dst = cv2.warpPerspective(img, T[u'KDXX05C'], (rows, cols))
new_img = Image.fromarray(np.uint8(dst))
new_img.save('testje.jpg')

2 个答案:

答案 0 :(得分:1)

我仍然相信warpPerspective完全符合您的要求( jedi mind trick )。说真的,它应该在一行中用meshgridvstackgriddata来实现。

您可以尝试以下代码吗? (我不熟悉Python,所以这可能需要一些调整):

# load image and convert it to grayscale (L)
img = cv2.imread('c5.jpg')
rows, cols, channels = img.shape
# img.show()

# Homography Matrix = H = P_rect * pinv(P) => P2 * pinv(P1)
H = P2.dot(np.linalg.pinv(P1))

cv2.warpPerspective(img, H, (rows, cols), dst, cv2.INTER_LINEAR)
new_img = Image.fromarray(np.uint8(dst))
new_img.save('testje.jpg')

其中H与您在第一个代码示例中使用的矩阵完全相同。

答案 1 :(得分:1)

griddata的第三个参数是形状为(M,D)的需要插值的位置数组(此处D = 2)。您输入的是(宽度,高度)元组,所以这可能就是为什么要获得[nan]数组的原因。