我该怎么做?如果有帮助的话,我知道相机的位置。
为了实现这一点,我考虑假设每个像素都是一个平面上的点,然后根据从高度图中获得的Z值垂直地平移每个点,并从该平移中(想象你从上面看这些点;移位会导致点从你的视角移动)提取每个像素的X和Y平移量,这些量可以输入到
cv.Remap()
中。但我不知道如何用OpenCV获取点的投影3D偏移量,更不用说构建偏移图了。
以下是我正在处理的参考图像:
我知道激光的角度为45度,从校准图像中,我可以轻松计算出书的高度。
h(x) = sin(theta) * abs(calibration(x) - actual(x))
我使用这种方法对两条线进行线性插值,以生成一个表面。以下是使用Python代码实现的示例(它在一个循环内):
height_grid[x][y] = heights_top[x] * (cv.GetSize(image)[1] - y) + heights_bottom[x] * y
我希望这能帮到您;)
目前,我有以下方法来对图像进行去畸变处理。中间的奇怪内容将一个三维坐标投影到相机平面上,考虑其位置(以及相机的位置、旋转等):
class Point:
def __init__(self, x = 0, y = 0, z = 0):
self.x = x
self.y = y
self.z = z
mapX = cv.CreateMat(cv.GetSize(image)[1], cv.GetSize(image)[0], cv.CV_32FC1)
mapY = cv.CreateMat(cv.GetSize(image)[1], cv.GetSize(image)[0], cv.CV_32FC1)
c = Point(CAMERA_POSITION[0], CAMERA_POSITION[1], CAMERA_POSITION[2])
theta = Point(CAMERA_ROTATION[0], CAMERA_ROTATION[1], CAMERA_ROTATION[2])
d = Point()
e = Point(0, 0, CAMERA_POSITION[2] + SENSOR_OFFSET)
costx = cos(theta.x)
costy = cos(theta.y)
costz = cos(theta.z)
sintx = sin(theta.x)
sinty = sin(theta.y)
sintz = sin(theta.z)
for x in xrange(cv.GetSize(image)[0]):
for y in xrange(cv.GetSize(image)[1]):
a = Point(x, y, heights_top[x / 2] * (cv.GetSize(image)[1] - y) + heights_bottom[x / 2] * y)
b = Point()
d.x = costy * (sintz * (a.y - c.y) + costz * (a.x - c.x)) - sinty * (a.z - c.z)
d.y = sintx * (costy * (a.z - c.z) + sinty * (sintz * (a.y - c.y) + costz * (a.x - c.x))) + costx * (costz * (a.y - c.y) - sintz * (a.x - c.x))
d.z = costx * (costy * (a.z - c.z) + sinty * (sintz * (a.y - c.y) + costz * (a.x - c.x))) - sintx * (costz * (a.y - c.y) - sintz * (a.x - c.x))
mapX[y, x] = x + (d.x - e.x) * (e.z / d.z)
mapY[y, x] = y + (d.y - e.y) * (e.z / d.z)
print
print 'Remapping original image using map...'
remapped = cv.CreateImage(cv.GetSize(image), 8, 3)
cv.Remap(image, remapped, mapX, mapY, cv.CV_INTER_LINEAR)
现在这篇文章已经成为了一个大量图片和代码的长串...无论如何,这个代码块要花费7分钟来运行一张1800万像素的相机图像;那太长了,而且最终这种方法对图像没有任何作用(每个像素的偏移量是<< 1
)。
有什么想法吗?