【发布时间】:2014-03-27 17:45:26
【问题描述】:
我有一张图像,我尝试绕 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')
【问题讨论】:
-
你好,我想是我建议使用
warpPerspective:) 你能清楚地解释一下你所说的图像“旋转”是什么意思吗?因为图像始终是 2D 的,所以对其应用 3D 旋转会使其拉伸。 -
是的。在你的帮助下,我让它工作了,但图像非常奇怪地扭曲了。也许我的代码有问题,但这就是我所做的(无法评论这么长的代码,所以编辑了我的原始帖子)
-
除了您在最终图像中遗漏了很多信息之外,单应性
H似乎正确地转换了图像吗? -
是的。图像看起来不错。更改 R1(或 R2)我可以手动围绕三个轴旋转图像,这工作正常
标签: python opencv image-processing