[Engineering application interface] Merge multiple pictures (implemented by python)

For reprint, please indicate the source.
For more high-quality content and detailed test procedures, you can click on the original text link to read and learn.

Function

Merge the foreground and background two pictures, you can set the transparency, zoom factor, and position of the foreground of the picture, you can adaptively adjust the background size and output the bounding box position of the picture, which is used for labeling data

accomplish

  1. Using the PIL package, the two images arepaste
  2. Modify the transparency of the image by modifying alphathe value of
  3. Process the size of the image to obtain the final image size
  4. Adjust the size of the background according to the size of the adjusted foreground image
  5. Process the foreground bounding box to get reasonable boundary coordinates

the code

2022.11.25 Fix the problem of opposite length and width

def xywh2xyxyxyxy(x,y,w,h):
    return [[x,y],[x+w,y],[x+w,y+h],[x,y+h]]

def merge_image(fore_image, back_image, pos=(0,0),alpha=1.0,factor=1.0,padding=False,func=lambda x:x):
    """将两个图片进行合并,支持自定义透明度 alpha, 缩放factor, 背景图缩放开关 padding, 前景图回调函数 func

    Args:
        fore_image (PIL.Image): 前景图
        back_image (PIL.Image): 背景图
        pos (tuple, list): 左上角位置. Defaults to (0,0).
        alpha (float, optional): 前景透明度. Defaults to 1.0.
        factor (float, optional): 前景缩放因子. Defaults to 1.0.
        padding (bool, optional): 背景自适应缩放. Defaults to False.
        func (Functional, optional): 前景处理回调函数. Defaults to lambdax:x.

    Returns:
        PIL.Image: 合并后的图片
    """
    assert alpha <= 1.0, "Alpha must be less or equel than 1.0"
    final_image = back_image.copy() 
    fore_image_temp = fore_image.copy()   
    
    # 设置缩放因子 透明度
    fore_h, fore_w = fore_image_temp.size
    print(fore_w,fore_h)
    fore_new_w = int(fore_w / factor)
    fore_new_h = int(fore_h / factor)
    for i in range(fore_new_w):
        for k in range(fore_new_h):
            color = fore_image_temp.getpixel((i, k))
            color = color[:-1] + (int((color[-1]*alpha)%255), )
            fore_image_temp.putpixel((i, k), color)
    fore_image_temp = fore_image_temp.resize((fore_new_w, fore_new_h), Image.Resampling.LANCZOS)
    fore_image_temp = func(fore_image_temp)

    # 背景图不够大将会被resize
    if padding:
        back_limit_w = fore_new_w + pos[0]
        back_limit_h = fore_new_h + pos[1]
    else:
        back_limit_w = fore_new_w
        back_limit_h = fore_new_h
    
    # 设置背景图片大小
    back_h,back_w = final_image.size
    # 设置背景图大小
    if back_w < back_limit_w:
        back_new_w = back_limit_w
        print(f"背景图宽度过小, {back_w} < {back_limit_w}")
    if back_h < back_limit_h:
        back_new_h = back_limit_h
        print(f"背景图高度过小, {back_h} < {back_limit_h}")
    final_image = final_image.resize((back_new_w,back_new_h),Image.Resampling.LANCZOS)
    
    final_image.paste(fore_image_temp, pos, mask=fore_image_temp)
    fore_final_h, fore_final_w = fore_image_temp.size
    back_final_h, back_final_w =final_image.size
    label_x = pos[0] if pos[0]>0 else 0
    label_y = pos[1] if pos[1]>0 else 0
    label_w = pos[0]+fore_final_w-label_x if pos[0]+fore_final_w < back_final_w else back_final_w-label_x
    label_h = pos[1]+fore_final_h-label_y if pos[1]+fore_final_h < back_final_h else back_final_h-label_y
    
    return final_image, xywh2xyxyxyxy(label_x,label_y,label_w,label_h)

demo

Guess you like

Origin blog.csdn.net/liferecords/article/details/128036396