数据集增广 之 多个图片贴到一张图上,以及生成相应的json文件
多图合成一图:
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文件相关推荐
- 怎么将自己的头像p到特定的背景图_怎么使用PS抠图,把扣出来的图片P到另张图上...
很多人都知道相片不好看,要用PS修改一下,可是PS具体叫什么可能有些人都叫不上来,它的全名叫 Photoshop . 至于Photoshop的用途也有很多.Photoshop主要处理以像素所构成的数字 ...
- 使用Python中的matplotlib将多个图片显示到一张图内
在我们写论文或是汇报时,经常需要整合所得到的可视化数据结果,插入我们的论文中.如下所示的情况,我们需要将四个相关的弹性模量预测结果在一张图里展示. 使用matplotlib库中的子图(subplot) ...
- php css定位到图片上,CSS_浅谈css中图片定位之所有图标放在一张图上,如今做网页为了使网站丰富多 - phpStudy...
浅谈css中图片定位之所有图标放在一张图上 如今做网页为了使网站丰富多彩,富于表现力,往往需要应用大量的图片/图标.如何处理这些图片,使其尽量不影响网页载入,解析等速度,是一个不大不小的问题.如果你的 ...
- ajax 异步插入图片到数据库(多图上传)
额 大概就这么个样子...截个图 点浏览 选择几张图片 选择完了 确定一下 然后插入数据库 同时在页面中显示插入的图片,代码 也没啥.看下 index.php <html><hea ...
- android 异形图片布局,杜蕾斯一张图说明异形全面屏手机进化史!刘海屏到水滴屏很形象...
原标题:杜蕾斯一张图说明异形全面屏手机进化史!刘海屏到水滴屏很形象 全面屏手机最大的优势就是屏占比高,很多手机厂商都把提高屏占作为目标,于是现在就有了各种各样的异形屏.异形屏设计是一种妥协的产物,主要 ...
- 图片变色_一张图看懂手机CMF史,附带手机渐变色工艺解析
自智能手机面世以来,功能的开发似乎已经到了极致,更多的革命开始转移到外观上,其中,颜色作为美观第一要素,从vivo X20的梦幻粉.OPPO R15的星云色,到华为P20的极光色,再到OPPO Fin ...
- Visio将多页图片打印到一张纸上
工具 Visio 方法/步骤 打开Visio中画好的多页图纸 选择"文件 -> 打印 ->页面设置",如图所示 选择"调整为 1页宽 x 1页高 -> ...
- 动手深度学习13——计算机视觉:数据增广、图片分类
文章目录 一.数据增广 1.1 为何进行数据增广? 1.2 常见图片增广方式 1.2.1 翻转 1.2.2 切割(裁剪) 1.2.3 改变颜色 1.2.4 综合使用 1.3 使用图像增广进行训练 1. ...
- 【pytorch】图片增广
前言 在神经网络的训练过程中,往往需要大量的图片,大量的数据,否则可能会造成过拟合与欠拟合.然而并非都能找到合适的数据,因为标注标签的成本太高了,因此非常有必要利用好手上现有的数据. 图片增广 通俗的 ...
最新文章
- 利用卷积神经网络对脑电图解码及可视化
- 区域链 信息存储的服务器,利用区块链储存明显优于传统的中心化服务器
- WIN7只能上QQ打不开网页,使用CMD输入netsh winsock reset
- java设计模式——工厂方法模式
- C++ 线程池的思想
- 使用Hadoop Streaming 完成MapReduce(Python代码)
- 一个 Task 不够,又来一个 ValueTask ,真的学懵了!
- angularJS中,怎么阻止事件冒泡
- linux文件系统概念目录结构
- 可以分屏的软件_Mac上的分屏功能,让你办公更高效
- SqlServer2008r2卸载
- web开发 java如何连接数据库并取得数据,实现 增,删,改,查
- 数据分析工具测评!被Excel打过的“耳光”,现在可以还回去了
- 大家都来测试测试自己的flex水平
- 【证明】—— 二叉树的相关证明
- 我和一位快递小哥的故事
- 2.4GHz频段天线的选择
- xp系统计算机描述无法输入,电脑xp系统的输入法怎么设置
- C在mac上用不了malloc.h头文件的解决方法
- Roblox、Epic Games和Meta,详解三巨头如何引爆元宇宙
热门文章
- 【转】采购订单行项目检查增强
- 【MM模块】Physics Inventory 库存盘点差异
- 【PP生产订单】入门介绍(七)
- 获取SAP HR模块中员工照片及照片URL的方法
- SAP FI 会计凭证过账bapi BAPI_ACC_DOCUMENT_POST
- SAP为什么并购sybase
- 2020前三季度各省市人均收入来了!看看你的家乡排第几?
- FILA之后又有Amer,安踏能成为“世界的安踏”吗?
- oracle如何创建一个定时任务,怎么创建定时任务
- 气门组的结构组成有哪些_你知道电线电缆是由哪些结构材料组成的吗?