美文网首页
一个备忘录:非方形图片裁剪填充成方形

一个备忘录:非方形图片裁剪填充成方形

作者: Valar_Morghulis | 来源:发表于2022-10-11 15:41 被阅读0次

这是一个私人备忘录,目的是流程规范。给定一批不一定为方形的图片及其标签(alpha),裁剪填充成方形。
将图像缩放至标签尺寸,并根据图像宽高将样本分成三类:方形图片,高瘦图片(高>宽),矮胖图片(高<宽)。
裁剪过程要完整裁剪出主体,对于不能完整裁剪出主体的图片就不裁剪,而是选择填充(pad)。填充函数中[-h:, :w, :]是根据具体图像内容设置的

import cv2
import numpy as np
import os
import random
import shutil
from pathlib import Path
    
def batch_opencv_resize_as(raw_folder, refence_folder, save_folder):
    os.makedirs(save_folder, exist_ok = True)
    for file in os.listdir(refence_folder): 
        afa = cv2.imread(refence_folder + file , 1)
        
        if Path(raw_folder + file).is_file():
            img = cv2.imread(raw_folder + file)
        else:
            img = cv2.imread(raw_folder + file.strip("jpg")+ "png")
      
        if img.shape == afa.shape:
            shutil.copy(raw_folder + file, save_folder)
        else:
            h, w, c = afa.shape
            img = cv2.resize(img, (w, h), interpolation=cv2.INTER_AREA)
            cv2.imwrite(save_folder + file, img)
            
            
def pad(raw_img, raw_afa):
    h, w = raw_afa.shape
    maxside = max(h,w)
    padimg = np.ones((maxside, maxside, 3)) * 127
    padafa = np.zeros((maxside, maxside))
    padimg[-h:, :w, :] = raw_img
    padafa[-h:, :w] = raw_afa
    return padimg, padafa
   
            
def crop_or_pad_by_alpha(img, alpha):
    h, w = img.shape[0], img.shape[1]
    alpah_temp = np.copy(alpha).astype(np.uint8)
    a = np.where(alpah_temp > 30)
    
    if np.max(alpha) <= 30:   # nobody img, center crop
        crop_x0 = 0
        crop_x1 = w
        crop_y0 = (h-w)//2
        crop_y1 = crop_y0 + w
        out_img = img[crop_y0:crop_y1, crop_x0:crop_x1, :]
        out_afa = alpha[crop_y0:crop_y1, crop_x0:crop_x1]
        return out_img, out_afa
    
    if w > h:
        x0 = min(a[1])
        x1 = max(a[1])
        portrait_w = x1 - x0
        if not portrait_w > h:
            crop_size = h
            crop_y0 = 0
            crop_y1 = h
            crop_x0 = x0 - random.randint(0, (crop_size - portrait_w))
            crop_x1 = crop_x0 + crop_size 
            if crop_x0 < 0 :
                crop_x0 = 0
                crop_x1 = crop_size
            if crop_x1 > w:
                crop_x1 = w
                crop_x0 = w - crop_size
            out_img = img[crop_y0:crop_y1, crop_x0:crop_x1, :]
            out_afa = alpha[crop_y0:crop_y1, crop_x0:crop_x1]
        else:
            out_img, out_afa = pad(img, alpha)
    else:  # w < h
        y0 = min(a[0])
        y1 = max(a[0])
        portrait_h = y1 - y0
        if portrait_h < w:
            crop_size = w
            crop_x0 = 0
            crop_x1 = w
            crop_y0 = y0 - random.randint(0, (crop_size - portrait_h))
            crop_y1 = crop_y0 + crop_size
            if crop_y0 < 0:
                crop_y0 = 0
                crop_y1 = crop_size
            if crop_y1 > h:
                crop_y1 = h
                crop_y0 = h - crop_size
            out_img = img[crop_y0:crop_y1, crop_x0:crop_x1, :]
            out_afa = alpha[crop_y0:crop_y1, crop_x0:crop_x1]
        else:
            out_img, out_afa = pad(img, alpha)
        
    return out_img, out_afa
    
            
def batch_crop_or_pad(raw_img_folder, raw_afa_folder, save_root):
    save_img_folder = save_root + "./imgs/"
    save_afa_folder = save_root + "./afas/"
    os.makedirs(save_img_folder, exist_ok = True)
    os.makedirs(save_afa_folder, exist_ok = True)

    for file in os.listdir(raw_afa_folder):
        afa = cv2.imread(raw_afa_folder+file, 0)
        h, w = afa.shape
        if h == w:
            shutil.copy(raw_img_folder + file, save_img_folder + "./imgs/")
            shutil.copy(raw_afa_folder + file, save_afa_folder + "./afas/")
        else:
            img = cv2.imread(raw_img_folder + file, 1)
            cropad_img, cropad_afa = crop_or_pad_by_alpha(img,afa) 
            cv2.imwrite(save_img_folder + file, cropad_img)
            cv2.imwrite(save_afa_folder + file, cropad_afa)
            
batch_crop_or_pad("./imgs/", "./afas/", "./cropad/")

对于不能完整裁剪出主体的,如果不想要padding,而是使用中心裁剪或靠上裁剪(优先中心裁剪,把头也裁掉的就用靠上裁剪),则更改为:

import cv2
import numpy as np
import os
import random
import shutil
   
def center_crop(img, afa):
    h, w, c = img.shape
    if h > w:
        crop_x0 = 0
        crop_x1 = w
        crop_y0 = (h-w)//2
        crop_y1 = crop_y0 + w
    else:
        crop_y0 = 0
        crop_y1 = h
        crop_x0 = (w-h)//2
        crop_x1 = crop_x0 + h
    out_img = img[crop_y0:crop_y1, crop_x0:crop_x1, :]
    out_afa = afa[crop_y0:crop_y1, crop_x0:crop_x1]
    return out_img, out_afa

def top_crop(img, afa):
    h, w, c = img.shape
    assert h > w
    crop_x0 = 0
    crop_x1 = w
    crop_y0 = 0
    crop_y1 = w
    out_img = img[crop_y0:crop_y1, crop_x0:crop_x1, :]
    out_afa = afa[crop_y0:crop_y1, crop_x0:crop_x1]
    return out_img, out_afa
            
def crop_or_topcrop_by_alpha(img, alpha):
    h, w = img.shape[0], img.shape[1]
    alpah_temp = np.copy(alpha).astype(np.uint8)
    a = np.where(alpah_temp > 30)
    if np.max(alpha) <= 30:   # nobody img, center crop
        out_img, out_afa = center_crop(img, alpha)
        return out_img, out_afa
    
    if w > h:
        x0 = min(a[1])
        x1 = max(a[1])
        portrait_w = x1 - x0
        if not portrait_w > h:
            crop_size = h
            crop_y0 = 0
            crop_y1 = h
            crop_x0 = x0 - random.randint(0, (crop_size - portrait_w))
            crop_x1 = crop_x0 + crop_size 
            if crop_x0 < 0 :
                crop_x0 = 0
                crop_x1 = crop_size
            if crop_x1 > w:
                crop_x1 = w
                crop_x0 = w - crop_size
            out_img = img[crop_y0:crop_y1, crop_x0:crop_x1, :]
            out_afa = alpha[crop_y0:crop_y1, crop_x0:crop_x1]
        else:
            out_img, out_afa = center_crop(img, alpha)
    else:  # w < h
        y0 = min(a[0])
        y1 = max(a[0])
        portrait_h = y1 - y0
        if portrait_h < w:
            crop_size = w
            crop_x0 = 0
            crop_x1 = w
            crop_y0 = y0 - random.randint(0, (crop_size - portrait_h))
            crop_y1 = crop_y0 + crop_size
            if crop_y0 < 0:
                crop_y0 = 0
                crop_y1 = crop_size
            if crop_y1 > h:
                crop_y1 = h
                crop_y0 = h - crop_size
            out_img = img[crop_y0:crop_y1, crop_x0:crop_x1, :]
            out_afa = alpha[crop_y0:crop_y1, crop_x0:crop_x1]
        else:
            out_img, out_afa = center_crop(img, alpha)
            if np.max(out_afa[0,:]) >= 30:
                out_img, out_afa = top_crop(img, alpha)
    return out_img, out_afa
            
def batch_crop_or_pad(raw_img_folder, raw_afa_folder, save_root):
    save_img_folder = save_root + "imgs/"
    save_afa_folder = save_root + "afas/"
    os.makedirs(save_img_folder, exist_ok = True)
    os.makedirs(save_afa_folder, exist_ok = True)
    for file in os.listdir(raw_afa_folder):
        afa = cv2.imread(raw_afa_folder+file, 0)
        h, w = afa.shape
        if h == w:
            shutil.copy(raw_img_folder + file, save_img_folder )
            shutil.copy(raw_afa_folder + file, save_afa_folder )
        else:
            img = cv2.imread(raw_img_folder + file, 1)
            cropad_img, cropad_afa = crop_or_topcrop_by_alpha(img,afa) 
            cv2.imwrite(save_img_folder + file.replace("png", "jpg"), cropad_img)
            cv2.imwrite(save_afa_folder + file.replace("png", "jpg"), cropad_afa)

相关文章

  • 一个备忘录:非方形图片裁剪填充成方形

    这是一个私人备忘录,目的是流程规范。给定一批不一定为方形的图片及其标签(alpha),裁剪填充成方形。 第1步 将...

  • 图片水印.擦除 图片截屏.........

    画板 图片裁剪 图片擦除 方形图片生产圆形头像 手机截屏 图片水印

  • 自定义正方形圆角

    在最近的机顶盒媒体中心开发中,遇到这样一个需求 需要将每张图片展示为正方形,并且拥有圆角。所以先将图片裁剪为正方形...

  • 如何在Photoshop中裁剪出圆形图像

    通常我们裁剪图像时,只能将图片裁剪成正方形,在本教程中,我们将学习如何使用Photoshop将图像裁剪成一个圆圈!...

  • 图片裁剪

    其实我最主要的目的只是需要将图片裁剪成正方形... ** AGSimpleImageEditorView ** 你...

  • flutter图片裁剪后上传

    裁剪图片 这里推荐flutter 插件:simple_image_crop。用法非常简单,支持圆形和方形选区,支持...

  • iOS图片裁剪

    在iOS开发过程中,经常会遇到上传图片的需求,有时获取到图片之后需要裁剪一下,而系统提供的方法只能裁剪出一个正方形...

  • nodejs 批处理裁剪图片方形为圆形

    原文件需要是方形文件,宽高必须相等 安装pngjs 配置输入和输出目录 执行 github:https://git...

  • 做盲盒

    我从网上学会了心仪已久的盲盒,首先先裁剪一个长方形的纸,然后对折三次成六个长方形条。最后剪三个缺口,然后画上图...

  • angularjs长方形裁剪

    上网搜索了angularjs裁剪,发现只有正方形和圆形 http://www.cnblogs.com/smilec...

网友评论

      本文标题:一个备忘录:非方形图片裁剪填充成方形

      本文链接:https://www.haomeiwen.com/subject/bsgtzrtx.html