您将拍摄图像并标记特定点(例如,标记人眼睛,鼻子,嘴巴等周围的区域),然后将它们转换为标记为另一图像的点。类似的东西:
transform(original_image, marked_points_in_the_original, marked_points_in_the_reference)
我似乎找不到描述它的算法,也找不到任何库。我也愿意自己做,只要我能找到好的/易于遵循的材料。我知道这是可能的,因为我已经看到一些不完整的(不能真正解释如何做到这一点).pdfs在谷歌与它。
以下是标记点和转换的示例,因为您要求澄清。虽然我之前说的这个没有使用2个人。
编辑:我设法使im.transform
方法有效,但参数是((box_x, box_y, box_width, box_height), (x0, y0, x1, y1, x2, y2, x3, y3))
的列表,第一个点是NW,第二个SW,第三个NE和第四个SE。据我所知,(0,0)是屏幕最左上角。如果我做的一切都正确,那么这种方法并不能真正做到我所需要的。
答案 0 :(得分:8)
Blender提供的示例代码对我不起作用。此外,im.transform
的PIL文档含糊不清。所以我深入研究PIL源代码,最后弄清楚如何使用该接口。这是我的完整用法:
import numpy as np
from PIL import Image
def quad_as_rect(quad):
if quad[0] != quad[2]: return False
if quad[1] != quad[7]: return False
if quad[4] != quad[6]: return False
if quad[3] != quad[5]: return False
return True
def quad_to_rect(quad):
assert(len(quad) == 8)
assert(quad_as_rect(quad))
return (quad[0], quad[1], quad[4], quad[3])
def rect_to_quad(rect):
assert(len(rect) == 4)
return (rect[0], rect[1], rect[0], rect[3], rect[2], rect[3], rect[2], rect[1])
def shape_to_rect(shape):
assert(len(shape) == 2)
return (0, 0, shape[0], shape[1])
def griddify(rect, w_div, h_div):
w = rect[2] - rect[0]
h = rect[3] - rect[1]
x_step = w / float(w_div)
y_step = h / float(h_div)
y = rect[1]
grid_vertex_matrix = []
for _ in range(h_div + 1):
grid_vertex_matrix.append([])
x = rect[0]
for _ in range(w_div + 1):
grid_vertex_matrix[-1].append([int(x), int(y)])
x += x_step
y += y_step
grid = np.array(grid_vertex_matrix)
return grid
def distort_grid(org_grid, max_shift):
new_grid = np.copy(org_grid)
x_min = np.min(new_grid[:, :, 0])
y_min = np.min(new_grid[:, :, 1])
x_max = np.max(new_grid[:, :, 0])
y_max = np.max(new_grid[:, :, 1])
new_grid += np.random.randint(- max_shift, max_shift + 1, new_grid.shape)
new_grid[:, :, 0] = np.maximum(x_min, new_grid[:, :, 0])
new_grid[:, :, 1] = np.maximum(y_min, new_grid[:, :, 1])
new_grid[:, :, 0] = np.minimum(x_max, new_grid[:, :, 0])
new_grid[:, :, 1] = np.minimum(y_max, new_grid[:, :, 1])
return new_grid
def grid_to_mesh(src_grid, dst_grid):
assert(src_grid.shape == dst_grid.shape)
mesh = []
for i in range(src_grid.shape[0] - 1):
for j in range(src_grid.shape[1] - 1):
src_quad = [src_grid[i , j , 0], src_grid[i , j , 1],
src_grid[i + 1, j , 0], src_grid[i + 1, j , 1],
src_grid[i + 1, j + 1, 0], src_grid[i + 1, j + 1, 1],
src_grid[i , j + 1, 0], src_grid[i , j + 1, 1]]
dst_quad = [dst_grid[i , j , 0], dst_grid[i , j , 1],
dst_grid[i + 1, j , 0], dst_grid[i + 1, j , 1],
dst_grid[i + 1, j + 1, 0], dst_grid[i + 1, j + 1, 1],
dst_grid[i , j + 1, 0], dst_grid[i , j + 1, 1]]
dst_rect = quad_to_rect(dst_quad)
mesh.append([dst_rect, src_quad])
return mesh
im = Image.open('./old_driver/data/train/c0/img_292.jpg')
dst_grid = griddify(shape_to_rect(im.size), 4, 4)
src_grid = distort_grid(dst_grid, 50)
mesh = grid_to_mesh(src_grid, dst_grid)
im = im.transform(im.size, Image.MESH, mesh)
im.show()
我建议在iPython中执行上面的代码然后打印出mesh
以了解im.transform
需要什么样的输入。对我来说输出是:
In [1]: mesh
Out[1]:
[[(0, 0, 160, 120), [0, 29, 29, 102, 186, 120, 146, 0]],
[(160, 0, 320, 120), [146, 0, 186, 120, 327, 127, 298, 48]],
[(320, 0, 480, 120), [298, 48, 327, 127, 463, 77, 492, 26]],
[(480, 0, 640, 120), [492, 26, 463, 77, 640, 80, 605, 0]],
[(0, 120, 160, 240), [29, 102, 9, 241, 162, 245, 186, 120]],
[(160, 120, 320, 240), [186, 120, 162, 245, 339, 214, 327, 127]],
[(320, 120, 480, 240), [327, 127, 339, 214, 513, 284, 463, 77]],
[(480, 120, 640, 240), [463, 77, 513, 284, 607, 194, 640, 80]],
[(0, 240, 160, 360), [9, 241, 27, 364, 202, 365, 162, 245]],
[(160, 240, 320, 360), [162, 245, 202, 365, 363, 315, 339, 214]],
[(320, 240, 480, 360), [339, 214, 363, 315, 453, 373, 513, 284]],
[(480, 240, 640, 360), [513, 284, 453, 373, 640, 319, 607, 194]],
[(0, 360, 160, 480), [27, 364, 33, 478, 133, 480, 202, 365]],
[(160, 360, 320, 480), [202, 365, 133, 480, 275, 480, 363, 315]],
[(320, 360, 480, 480), [363, 315, 275, 480, 434, 469, 453, 373]],
[(480, 360, 640, 480), [453, 373, 434, 469, 640, 462, 640, 319]]]
答案 1 :(得分:7)
在类似的说明中,您可以使用ImageMagick的Python API执行Shepards's Distortion。
答案 2 :(得分:5)
这是PIL转换的一个很好的资源(你想看 MESH ):http://effbot.org/tag/PIL.Image.Image.transform。
来自文档:
与QUAD类似,但数据是目标矩形和相应的源四边形的列表。
im.transform(size, MESH, data)
数据是矩形的元组:
data = [((a, b, c, d), (e, f, g, h)),
((i, j, k, l), (m, n, o, p))]
它将第一个矩形转换为第二个矩形。