【问题标题】:Rectified image: interpolate missing points校正后的图像:插入缺失点
【发布时间】: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


【解决方案1】:

我仍然相信warpPerspective 完全符合您的要求(绝地思维技巧)。说真的,它应该在一行中完成您使用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 与您在提供的第一个代码示例中使用的矩阵完全相同。

【讨论】:

  • 如果我这样做,我会得到一个空图像(白色或黑色取决于我用于 dst 的数组(显然我需要先设置它))我的代码 # 加载图像并将其转换为灰度( 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)) dst = np.ones((2000,2000))*255 # 白色背景 cv2.warpPerspective(img, H, (rows, cols), dst, cv2.WARP_INVERSE_MAP ) new_img = Image.fromarray(np.uint8(dst)) new_img.save('testje.jpg')
  • 如果我给你一个示例图像(或我想在全景图中使用的所有 6 个图像)和一个示例输出全景图(拼接和校正),这会有所帮助吗?
  • 不是那么多,因为我的问题是 python 中的编码以及您与H 和两个图像的约定。 P1img 的相机矩阵,对吧?如果您在我的编辑中添加cv2.INTER_LINEAR,会更好吗?
  • 抱歉,还是不行。但是,如果这更容易(或更好),我也可以使用现实世界中的测量点,而不是使用计算出的单应性
  • @Yorian 好的,最后一次尝试,如果你删除cv2.WARP_INVERSE_MAP,你能检查结果吗,就像我的编辑一样?
【解决方案2】:

griddata 的第三个参数是一个 (M,D) 形状的需要插值的位置数组(这里 D=2)。你正在输入一个 (width, height) 的元组,所以这可能就是你得到一个 [nan] 数组的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 2013-12-29
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    相关资源
    最近更新 更多