多图合成一图:

import os
import tqdm
import glob
import json
import math
import random
import numpy as np
from pathlib import Path
from PIL import Image, ImageDrawforesuffix = '_foreground.jpg'
pseudosuffix = '_pseudo.jpg'
jsonsuffix = '.jpg.json'# 旋转图片,没有黑边
def rotateImage(img):image = np.asarray(img)rotated = np.rot90(image)   # 逆时针旋转!'''# 通道特殊处理# Image 通道是 “RGB”# numpy 通道是 “BGR”r, g, b = rotated[:, :, 0], rotated[:, :, 1], rotated[:, :, 2]h, w = r.shapenew = np.zeros((h, w, 3))new[:, :, 0] = rnew[:, :, 1] = gnew[:, :, 2] = b'''newimage = Image.fromarray(np.uint8(rotated))return newimage# 规划拼接区域
def splitArea(count, width, height):if count == 2:# 左右拼接if width >= height:##########   A   ###########   B   ##########w, h = width // 2, heightx1, y = w // 2, h // 2x2 = x1 * 3boxlist = [(x1, y, w, h), (x2, y, w, h)]# 上下拼接else:##############  A  #  B  ##############w, h = width, height//2x, y1 = w // 2, h // 2y2 = y1 * 3boxlist = [(x, y1, w, h), (x, y2, w, h)]elif count == 3:if width >= height:##############     #  B  ##  A  ########     #  C  ##############w, h1, h2 = width // 2, height, height // 2x1, y1, y2 = w // 2, h1 // 2, h2 // 2x2 = x1 * 3y3 = y2 * 3boxlist = [(x1, y1, w, h1), (x2, y2, w, h2), (x2, y3, w, h2)]# 上下拼接else:##############     A     ###############  B  #  C  ##############w1, w2, h = width, width // 2, height // 2x1, x2, y1 = w1 // 2, w2 // 2, h // 2y2 = y1 * 3x3 = x2 * 3boxlist = [(x1, y1, w1, h), (x2, y2, w2, h), (x3, y2, w2, h)]elif count == 4:##############  A  #  C  ###############  B  #  D  ##############w, h = width//2, height//2x1, y1 = w // 2, h // 2x2, y2 = x1 * 3, y1 * 3boxlist = [(x1, y1, w, h), (x1, y2, w, h), (x2, y1, w, h), (x2, y2, w, h)]else:passreturn boxlist# 旋转坐标点
def processPoints(pointList, boundingbox, lx, ly, fw, fh, w, h):pointlist = []offsetx, offsety = boundingbox[0], boundingbox[1]for point in pointList:# 把衣服框从原图中抠出来x, y = point[0]-offsetx, point[1]-offsety# 旋转"""点point1绕点point2旋转angle后的点======================================在平面坐标上,任意点P(x1,y1),绕一个坐标点Q(x2,y2)旋转θ角度后,新的坐标设为(x, y)的计算公式:x= (x1 - x2)*cos(θ) - (y1 - y2)*sin(θ) + y2 ;y= (x1 - x2)*sin(θ) + (y1 - y2)*cos(θ) + x2 ;======================================将图像坐标(x,y)转换到平面坐标(x`,y`):x`=xy`=height-y:param point1::param point2: base point (基点):param angle: 旋转角度,正:表示逆时针,负:表示顺时"""tfw, tfh = fw, fhif (w >= h and fw < fh) or (w < h and fw >= fh):x1, y1 = x, yrotx, roty = tfw // 2, tfh // 2# # 将图像坐标转换到平面坐标y1 = tfh - y1roty = tfh - roty# 逆时针x = (x1 - rotx) * math.cos(math.pi/2) - (y1 - roty) * math.sin(math.pi/2) + rotyy = (x1 - rotx) * math.sin(math.pi/2) + (y1 - roty) * math.cos(math.pi/2) + rotx# 旋转之后,长宽对调,将平面坐标转换到图像坐标tfw, tfh = tfh, tfwy = tfh - y# 缩放ratiox, ratioy = w / tfw, h / tfhx *= ratioxy *= ratioy# # 拼接到新图的新区域x += lxy += lypointlist.append([int(x), int(y)])return pointlist# 拼接
def joint(baseimage, forelist, imagesavepath, savejsonpath=None, threshold=50, debug=False):# 获取基底图片尺寸base = Image.open(baseimage)if debug:print(f"baseimage mode is :{base.mode}")base.show()# 设置拼接坐标count = len(forelist)assert count >= 2, "ERROR: the count of foregrounds is not enough !"assert count <= 4, "ERROR: the count of foregrounds is too many !"width, height = base.sizeboxlist = splitArea(count, width, height)if savejsonpath is not None:# 拼接原图,从基底图片中截取一小部分进行放大,作为新的图片的背景box=(0, 0, threshold, threshold)background = base.crop(box)background = background.resize((width, height))else:# 拼接pseudo 和 foreground,直接生成纯黑背景background = Image.new("RGB", (width, height), "#000000")if debug:background.show()# 拼接前景图片jsonlist = []for idx, (fore, box) in enumerate(zip(forelist, boxlist)):fimg = Image.open(fore)boundingbox = fimg.getbbox()fimg = fimg.crop(boundingbox)if debug:print(fore)fimg.show()# 获取拼接区域cx, cy, w, h = boxfw, fh = fimg.sizeif (w >= h and fw < fh) or (w < h and fw >= fh):fimg = rotateImage(fimg)if debug:print(fore, "旋转了")fimg.show()fimg = fimg.resize((w, h))if debug:fimg.show()# 获取maskmask, _, _ = fimg.split()mask = np.array(mask)mask[mask > 10] = 255mask[mask <= 10] = 0mask = Image.fromarray(mask)# 拼接lx, ly = cx-w//2, cy-h//2rx, ry = cx+w//2, cy+h//2background.paste(fimg, (lx, ly, rx, ry), mask)# 修改该json文件if savejsonpath is not None:readpath = fore.replace(foresuffix, jsonsuffix)with open(readpath, 'r') as reader:jsonfile = json.load(reader)# 如果只有一件衣服的图片中存在多个标注连通域,则警告if len(jsonfile) > 1 or len(jsonfile) == 0:with open('./runningLog.json', 'a') as writer:info = f"WARNING: {fore}\n"writer.write(info)# 遍历每个标注区域for object in jsonfile:savejson = dict()savejson['name'] = object['name']savejson['color'] = object['color']savejson['labelIdx'] = idx + 1savejson['points'] = processPoints(object['points'], boundingbox, lx, ly, fw, fh, w, h)jsonlist.append(savejson)# 保存图片及json文件background.save(imagesavepath)if len(jsonlist) > 0:with open(savejsonpath, 'w') as writer:json.dump(jsonlist, writer)if debug:background.show()if __name__ == '__main__':imageroot = './hx_clothes_1122/hx_clothes_imgs'maskroot = './hx_clothes_1122/hx_clothes_masks'idx = 0for _ in tqdm.tqdm(range(4)):imagelist = os.listdir(imageroot)while len(imagelist) > 1:idx += 1if len(imagelist) < 4:count = len(imagelist)          # 如果剩余图片不足4张,则都拼一块else:count = random.randint(2, 4)    # 随机产生【2,4】闭区间上的一个整数forelist = []psedolist = []jsonlist = []imglist = []for i in range(count):img = random.choice(imagelist)imgpath = os.path.join(imageroot, img)imglist.append(imgpath)forename = img.replace('.jpg', foresuffix)forepath = os.path.join(maskroot, forename)forelist.append(forepath)pseudoname = img.replace('.jpg', pseudosuffix)pseudopath = os.path.join(maskroot, pseudoname)psedolist.append(pseudopath)jsonname = img.replace('.jpg', jsonsuffix)jsonpath = os.path.join(maskroot, jsonname)jsonlist.append(jsonpath)imagelist.remove(img)saveimagename = f"hx_clothes_1122/joint_images/aug_{idx}.jpg"savejsonname = f"hx_clothes_1122/joint_masks/aug_{idx}.jpg.json"saveforename = f"hx_clothes_1122/joint_masks/aug_{idx}_foreground.jpg"savepseudoname = f"hx_clothes_1122/joint_masks/aug_{idx}_pseudo.jpg"joint(imglist[0], forelist, saveimagename, savejsonname)        # , debug=Truejoint(forelist[0], forelist, saveforename)joint(psedolist[0], psedolist, savepseudoname)with open('./runningLog.json', 'a') as writer:info = f"{json.dumps(imglist)}\n===> {str(idx)}\n\n"writer.write(info)# breakprint(f"\r剩余:{len(imagelist)}", end='', flush=True)# break

数据集增广 之 多个图片贴到一张图上,以及生成相应的json文件相关推荐

  1. 怎么将自己的头像p到特定的背景图_怎么使用PS抠图,把扣出来的图片P到另张图上...

    很多人都知道相片不好看,要用PS修改一下,可是PS具体叫什么可能有些人都叫不上来,它的全名叫 Photoshop . 至于Photoshop的用途也有很多.Photoshop主要处理以像素所构成的数字 ...

  2. 使用Python中的matplotlib将多个图片显示到一张图内

    在我们写论文或是汇报时,经常需要整合所得到的可视化数据结果,插入我们的论文中.如下所示的情况,我们需要将四个相关的弹性模量预测结果在一张图里展示. 使用matplotlib库中的子图(subplot) ...

  3. php css定位到图片上,CSS_浅谈css中图片定位之所有图标放在一张图上,如今做网页为了使网站丰富多 - phpStudy...

    浅谈css中图片定位之所有图标放在一张图上 如今做网页为了使网站丰富多彩,富于表现力,往往需要应用大量的图片/图标.如何处理这些图片,使其尽量不影响网页载入,解析等速度,是一个不大不小的问题.如果你的 ...

  4. ajax 异步插入图片到数据库(多图上传)

    额 大概就这么个样子...截个图 点浏览  选择几张图片 选择完了 确定一下 然后插入数据库 同时在页面中显示插入的图片,代码 也没啥.看下 index.php <html><hea ...

  5. android 异形图片布局,杜蕾斯一张图说明异形全面屏手机进化史!刘海屏到水滴屏很形象...

    原标题:杜蕾斯一张图说明异形全面屏手机进化史!刘海屏到水滴屏很形象 全面屏手机最大的优势就是屏占比高,很多手机厂商都把提高屏占作为目标,于是现在就有了各种各样的异形屏.异形屏设计是一种妥协的产物,主要 ...

  6. 图片变色_一张图看懂手机CMF史,附带手机渐变色工艺解析

    自智能手机面世以来,功能的开发似乎已经到了极致,更多的革命开始转移到外观上,其中,颜色作为美观第一要素,从vivo X20的梦幻粉.OPPO R15的星云色,到华为P20的极光色,再到OPPO Fin ...

  7. Visio将多页图片打印到一张纸上

    工具 Visio 方法/步骤 打开Visio中画好的多页图纸 选择"文件 -> 打印 ->页面设置",如图所示 选择"调整为 1页宽 x 1页高 -> ...

  8. 动手深度学习13——计算机视觉:数据增广、图片分类

    文章目录 一.数据增广 1.1 为何进行数据增广? 1.2 常见图片增广方式 1.2.1 翻转 1.2.2 切割(裁剪) 1.2.3 改变颜色 1.2.4 综合使用 1.3 使用图像增广进行训练 1. ...

  9. 【pytorch】图片增广

    前言 在神经网络的训练过程中,往往需要大量的图片,大量的数据,否则可能会造成过拟合与欠拟合.然而并非都能找到合适的数据,因为标注标签的成本太高了,因此非常有必要利用好手上现有的数据. 图片增广 通俗的 ...

最新文章

  1. 利用卷积神经网络对脑电图解码及可视化
  2. 区域链 信息存储的服务器,利用区块链储存明显优于传统的中心化服务器
  3. WIN7只能上QQ打不开网页,使用CMD输入netsh winsock reset
  4. java设计模式——工厂方法模式
  5. C++ 线程池的思想
  6. 使用Hadoop Streaming 完成MapReduce(Python代码)
  7. 一个 Task 不够,又来一个 ValueTask ,真的学懵了!
  8. angularJS中,怎么阻止事件冒泡
  9. linux文件系统概念目录结构
  10. 可以分屏的软件_Mac上的分屏功能,让你办公更高效
  11. SqlServer2008r2卸载
  12. web开发 java如何连接数据库并取得数据,实现 增,删,改,查
  13. 数据分析工具测评!被Excel打过的“耳光”,现在可以还回去了
  14. 大家都来测试测试自己的flex水平
  15. 【证明】—— 二叉树的相关证明
  16. 我和一位快递小哥的故事
  17. 2.4GHz频段天线的选择
  18. xp系统计算机描述无法输入,电脑xp系统的输入法怎么设置
  19. C在mac上用不了malloc.h头文件的解决方法
  20. Roblox、Epic Games和Meta,详解三巨头如何引爆元宇宙

热门文章

  1. 【转】采购订单行项目检查增强
  2. 【MM模块】Physics Inventory 库存盘点差异
  3. 【PP生产订单】入门介绍(七)
  4. 获取SAP HR模块中员工照片及照片URL的方法
  5. SAP FI 会计凭证过账bapi BAPI_ACC_DOCUMENT_POST
  6. SAP为什么并购sybase
  7. 2020前三季度各省市人均收入来了!看看你的家乡排第几?
  8. FILA之后又有Amer,安踏能成为“世界的安踏”吗?
  9. oracle如何创建一个定时任务,怎么创建定时任务
  10. 气门组的结构组成有哪些_你知道电线电缆是由哪些结构材料组成的吗?