是否有用于控制点的python图像变形/图像变形的库? [英] Is there a library for image warping / image morphing for python with controlled points?

查看:83
本文介绍了是否有用于控制点的python图像变形/图像变形的库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您将拍摄图像并标记特定的点(例如,标记人的眼睛,鼻子,嘴等周围的区域),然后将它们转换为标记为另一幅图像的点.像这样:

You'd take images and mark specific points (for example, mark the region around the eyes, nose, mouth etc of people) and then transform them into the points marked into another image. Something like:

transform(original_image, marked_points_in_the_original, marked_points_in_the_reference)

我似乎找不到找到描述它的算法,也找不到带有它的任何库.我也愿意自己做,只要我能很好/容易地遵循它上的材料即可.我知道这是有可能的,因为我已经看到了一些不完整的(不要真的解释怎么做)在Google上使用它的.pdfs.

I can't seem to find an algorithm describing it, nor can I find any libraries with it. I'm willing to do it myself too, as long as I can find good/easy to follow material on it. I know it's possible though since I've seen some incomplete (don't really explain how to do it) .pdfs on google with it.

这是标记点和转换的示例,因为您需要澄清.尽管这个人没有像我前面说的那样使用2个人.

Here's an example of the marked points and the transformation, since you asked for clarification. Though this one isn't using 2 people as I said earlier.


我设法使im.transform方法起作用,但是参数是((box_x, box_y, box_width, box_height), (x0, y0, x1, y1, x2, y2, x3, y3))的列表,第一点是NW,第二个SW,第三个NE和第四个SE.据我所知,(0,0)是屏幕的最左上部分.如果我做对了所有事情,那么这种方法并不能真正满足我的需要.

I managed to get the im.transform method working, but the argument is a list of ((box_x, box_y, box_width, box_height), (x0, y0, x1, y1, x2, y2, x3, y3)), with the first point being NW, the second SW, the third NE and the fourth SE. (0, 0) is the leftmost upper part of the screen as far as I could tell. If I did everything right, then this method doesn't really do what I need.

推荐答案

Blender给出的示例代码对我不起作用.另外,im.transform的PIL文档是不明确的.因此,我深入研究了PIL源代码,并最终弄清楚了如何使用该接口.这是我的完整用法:

Sample code given by Blender doesn't work for me. Also, the PIL documentation for im.transform is ambiguous. So I dig into the PIL source code and finally figure out how to use the interface. Here's my complete usage:

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需要哪种输入.对我来说,输出是:

I suggest executing above code in iPython then print out mesh to understand what kind of input is needed for im.transform. For me the output is:

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]]]

这篇关于是否有用于控制点的python图像变形/图像变形的库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆