保存已转换粘贴图像的坐标

时间:2017-06-14 22:49:39

标签: python python-imaging-library pillow

我在背景图片上粘贴了随机生成的条形码。

此条形码已随机旋转,倾斜和缩放。

然后,将此条形码随机放置在背景图像上。

我试图找出实际条形码的坐标,忽略扩展的黑色面具。

我是矩阵和图像处理的初学者,所以任何帮助,尤其是数学方面的帮助,都会受到赞赏。

这是我使用pdf417gen库生成条形码以及条形码的坐标。

import numpy as np
import os
import random
import sys

from pdf417gen import encode, render_image
from PIL import Image

def generate_barcode(self):
    barcode = encode("random text data", columns=5, security_level=5)
    scale = 5
    ratio = 3
    padding = 5

    barcode_image = render_image(barcode, scale=scale, ratio=ratio, padding=padding)
    barcode_coords = np.array([
        [(barcode_image.width - padding) / float(barcode_image.width), (barcode_image.height - padding) / float(barcode_image.height)],
        [padding / float(barcode_image.width), (barcode_image.height - padding) / float(barcode_image.height)],
        [padding / float(barcode_image.width), padding / float(barcode_image.height)],
        [(barcode_image.width - padding) / float(barcode_image.width), padding / float(barcode_image.height)]
    ])

    return (barcode_coords, barcode_image)

一旦我有条形码的图像和坐标,我会执行以下操作。

  1. 转换条形码的图像
  2. 尝试将坐标与图片的转换匹配
  3. 将图像粘贴到背景图像上
  4. 然后使用坐标
  5. 绘制红色轮廓

    红色轮廓应勾勒出条形码的图像。

    我在这里转换条形码图像并将其粘贴到背景图像上。

    def composite_images(self, background_image, barcode_coords, barcode_image):
        coords = barcode_coords
        barcode = barcode_image
    
        # instantiating the transformation variables
        scale = random.randrange(4, 50) / 100.0
        size = int( min(background_image.size) * scale) # background_image.size returns (width, height)
        barcode = barcode.resize((int(size * 2.625), size)) # width:height ratio is 2.625:1
        rotation = random.randrange(0, 360)
        xstretch = random.randrange(0, 100) / 100.0
        ystretch = random.randrange(0, 100) / 100.0
        xshear = random.randrange(0, 100) / 100.0
        yshear = random.randrange(0, 100) / 100.0
    
        # set affine transform on the barcode coordinates
        affine_transform = get_affine_transform(rotation, xstretch, ystretch, xshear, yshear)
        coords = transform_coords(coords, affine_transform, True)
        expand_mask = transform_coords(np.array([  # shifts expand mask based on transformation
            [0.0, 0.0],
            [float(size * 2.625), 0.0],
            [float(size * 2.625), float(size)],
            [0.0, float(size)]
        ]), mat, False)
    
        minx = min(expand_mask[:,0])
        maxx = max(expand_mask[:,0])
        miny = min(expand_mask[:,1])
        maxy = max(expand_mask[:,1])
    
        mat_inv = np.linalg.inv(np.array([  # the inverse matrix
            [mat[0,0], mat[0,1], -minx],
            [mat[1,0], mat[1,1], -miny],
            [0,0,1.0]
        ]))
        image_matrix = (mat_inv[0,0], mat_inv[0,1], mat_inv[0,2], 
            mat_inv[1,0], mat_inv[1,1], mat_inv[1,2])
        new_size = (int(maxx-minx), int(maxy-miny))
    
        # set affine transform on the barcode image using data from coordinates affine transformation
        barcode = barcode.transform(new_size, method=Image.AFFINE, data=image_matrix)
    
        # paste the barcode image onto a random position on background image
        region_x = random.randrange(0, background_image.width - size)
        region_y = random.randrange(0, background_image.height - size)
        background_image.paste(barcode, (region_x, region_y))
    
        coords *= scale
        coords += [region_x / float(background_image.width), region_y / float(background_image.height)]
    
        return(coords, background_image)
    
    def get_affine_transform(self, rotation, xstretch, ystretch, xshear, yshear):
        theta = -(rotation / 180.0) * np.pi
        return np.array([
            [np.cos(theta) * xstretch, -np.sin(theta) * xshear],
            [np.sin(theta) * ystretch, np.cos(theta) * yshear]
        ])
    
    def transform_coords(self, coords, affine_transform, center):
        if center:
            coords -= (.5, .5) # center on origin
        coords = np.dot(coords, affine_transform.T)
        if center:
            coords += (.5, .5) # reset centering
        return coords
    

    现在我使用composite_images()返回的坐标和图像(带粘贴的条形码)绘制红色轮廓。

    def draw_red_outline(self, box_coords, image):
        outline = box_coords * [image.width, image.height]
        outline = outline.astype(int)
        outline = tuple(map(tuple, outline))
    
        draw = ImageDraw.Draw(image)
        draw.poly(outline, outline=(255,0,0,0))
        del draw
    
        image.show()
    

    我不确定我的数学出错了。

1 个答案:

答案 0 :(得分:0)

要获取转换点的坐标,您可以执行以下操作:

获得转换矩阵后:

transformed_img = cv2.warpPerspective(source_img, m, image_shape)

您将其应用于图片:

transformed_img = cv2.warpPerspective(source_img, m, image_shape)

并且变换后的图像包含您想要计算的坐标和一些黑色区域的结果。

所以,解决4点中的每一点'坐标(如果没有0坐标)如下:

point = np.array([w, h]) #width and hight of the source point (before transform)
homg_point = [point[0], point[1], 1] # homogeneous coords
transf_homg_point = m.dot(homg_point) # transform
transf_homg_point /= transf_homg_point1[2] # scale
transf_point = transf_homg_point[:2] # remove Cartesian coords
print(transf_point) #check the result

tranformation coordinates

相关问题