当前位置: 首页 > news >正文

「图像 merge」无中生有制造数据

在进行一个新项目的时候,往往缺少一些真实数据,导致没办法进行模型训练,这时候就需要算法工程师自行制作一些数据了,比如这篇文章分享的 bag 目标检测,在检测区域没有真实的 bag数据

此时,就可以采用图像拼接的方式将凑集到的 bag图像粘贴到场景图像中【前提,目标图一般为“大头贴”】,当然场景图片并不是所有的位置都可以粘贴,一般有特定区域,比如 地面、墙壁、某设备等,因此还需要采用标注工具将这些目标区域标注出来,算法通过读取对应的目标区域,随机设定区域内的坐标点进行粘贴,将目标图粘贴到场景图当中

当然并不是任何形式的目标图都可以粘贴,为了更好的融合场景当中,还需要将目标从 大头贴当中给 扣出来,即除了目标区域,其他区域设置为透明格式,这样拼接的效果才“更”加真实一些【还是很假的!!!】

具体的操作过程如何所示,代码附最后,如有 bug 还望见谅!

1、制作底片模版

博主采用的 LabelImg标注工具,将底片待粘贴区域标注好

标注完成的 txt 内容
在这里插入图片描述

labelImg 的显示界面
在这里插入图片描述


2、将对应的大头贴目标头图处理

从 jpg 图像将目标 “扣” 出来,此处采用的像素抠图,将白色区域设置为透明,此处并不通用,不同目标的小伙伴自行修改代码,png的图像格式可以保存 alpha通道

在这里插入图片描述


#  !/usr/bin/env  python
#  -*- coding:utf-8 -*-
# @Time   :  2023.11
# @Author :  绿色羽毛
# @Email  :  lvseyumao@foxmail.com
# @Blog   :  https://blog.csdn.net/ViatorSun
# @Note   :  jpg2png.pyimport os
import cv2
import numpy as np
import os.path as ospfile_path = "/media/yinzhe/DataYZ/DataSet/DataSet/bag_masknew"
save_path = file_path + "_out"if not osp.exists(save_path):os.makedirs(save_path)img_lst = []
for path, dirs, files in os.walk(file_path):for file in files:if os.path.splitext(file)[1] in ['.jpg', ".png", ".JPG", ".jpeg"]:  # 扫描指定格式文件img_dir = osp.join(path, file)img_save = osp.join(save_path, file)img = cv2.imread(img_dir)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)                               # 转换为RGB格式png_img = osp.join(save_path, file.split(".")[0] + ".png")white_mask = cv2.inRange(img, (200, 200, 200), (255, 255, 255))  	# 提取白色部分img = cv2.cvtColor(img, cv2.COLOR_RGB2BGRA)img[:,:,3][white_mask == 255] = 0                       			# 将白色部分变成透明cv2.imwrite(png_img, img)

3、将底片与透明目标进行叠加融合

叠加融合的方法有很多种,此处只采用了最简单的叠加方式,也可以考虑 cv2.seamlessClone
最终成果如下图所示

在这里插入图片描述

除了生成合成图片,标注信息也同步生成

在这里插入图片描述

注意! 此处的标注信息是按照标注框尺寸保存的【此处隐藏bug后续优化】
提示:可以根据目标区域的非透明区域进行保存

在这里插入图片描述

#  !/usr/bin/env  python
#  -*- coding:utf-8 -*-
# @Time   :  2023.10
# @Author :  绿色羽毛
# @Email  :  lvseyumao@foxmail.com
# @Blog   :  https://blog.csdn.net/ViatorSun
# @Note   :  ps_merge_img.pyimport os
import cv2
import random
from random import sample
import numpy as np
import argparse  def read_label_txt(label_dir):labels = []with open(label_dir) as fp:for f in fp.readlines():labels.append(f.strip().split(' '))return labelsdef rescale_yolo_labels(labels, img_shape):height, width, nchannel = img_shaperescale_boxes = []for box in list(labels):x_c = float(box[1]) * widthy_c = float(box[2]) * heightw = float(box[3]) * widthh = float(box[4]) * heightx_left = x_c - w * .5y_left = y_c - h * .5x_right = x_c + w * .5y_right = y_c + h * .5rescale_boxes.append([box[0], int(x_left), int(y_left), int(x_right), int(y_right)])return rescale_boxesdef xyxy2xywh(image, bboxes):height, width, _ = image.shapeboxes = []for box in bboxes:if len(box) < 4:continuecls = int(box[0])x_min = box[1]y_min = box[2]x_max = box[3]y_max = box[4]w = x_max - x_minh = y_max - y_minx_c = (x_min + x_max) / 2.0y_c = (y_min + y_max) / 2.0x_c = x_c / widthy_c = y_c / heightw = float(w) / widthh = float(h) / heightboxes.append([cls, x_c, y_c, w, h])return boxesdef cast_color(img, value):img_t = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)h,s,v = cv2.split(img_t)# 增加图像对比度v2 = np.clip(cv2.add(2*v,value),0,255)img2 = np.uint8(cv2.merge((h,s,v2)))img_cast = cv2.cvtColor(img2,cv2.COLOR_HSV2BGR)             # 改变图像对比度return img_castdef brightness(img, value):img_t = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)h,s,v = cv2.split(img_t)# 增加图像亮度v1 = np.clip(cv2.add(1*v,value),0,255)img1 = np.uint8(cv2.merge((h,s,v1)))img_brightness = cv2.cvtColor(img1,cv2.COLOR_HSV2BGR)       # 改变图像亮度亮度return img_brightnessdef add_alpha_channel(img):""" 为jpg图像添加alpha通道 """b_channel, g_channel, r_channel = cv2.split(img)  				# 拆分jpg图像通道alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255  # 创建Alpha通道img_new = cv2.merge((b_channel, g_channel, r_channel, alpha_channel))  # 融合通道return img_newdef merge_img(jpg_img, png_img, y1, y2, x1, x2):""" 将png透明图像与jpg图像叠加y1,y2,x1,x2为叠加位置坐标值"""# 判断jpg图像是否已经为4通道if jpg_img.shape[2] == 3:jpg_img = add_alpha_channel(jpg_img)'''当叠加图像时,可能因为叠加位置设置不当,导致png图像的边界超过背景jpg图像,而程序报错这里设定一系列叠加位置的限制,可以满足png图像超出jpg图像范围时,依然可以正常叠加'''yy1 = 0yy2 = png_img.shape[0]xx1 = 0xx2 = png_img.shape[1]if x1 < 0:xx1 = -x1x1 = 0if y1 < 0:yy1 = - y1y1 = 0if x2 > jpg_img.shape[1]:xx2 = png_img.shape[1] - (x2 - jpg_img.shape[1])x2 = jpg_img.shape[1]if y2 > jpg_img.shape[0]:yy2 = png_img.shape[0] - (y2 - jpg_img.shape[0])y2 = jpg_img.shape[0]# 获取要覆盖图像的alpha值,将像素值除以255,使值保持在0-1之间alpha_png = png_img[yy1:yy2, xx1:xx2, 3] / 255.0alpha_jpg = 1 - alpha_png# 开始叠加for c in range(0, 3):jpg_img[y1:y2, x1:x2, c] = ((alpha_jpg * jpg_img[y1:y2, x1:x2, c]) + (alpha_png * png_img[yy1:yy2, xx1:xx2, c]))return jpg_imgdef random_add_patches_on_objects(image, mask_lst, rescale_boxes, paste_number):img = image.copy()new_bboxes = []cl = 0random.shuffle(rescale_boxes)for i, rescale_bbox in enumerate(rescale_boxes[:int(len(mask_lst))]):     # 待ps图像 目标框中p_img = mask_lst[i]bbox_h, bbox_w, bbox_c = p_img.shapeobj_xmin, obj_ymin, obj_xmax, obj_ymax = rescale_bbox[1:]obj_w = obj_xmax - obj_xmin + 1         # 目标框尺寸obj_h = obj_ymax - obj_ymin + 1while not (bbox_w < obj_w and bbox_h < obj_h):                  # 如果目标框小于 mask尺寸,对mask进行缩放以确保可以放进 bbox中new_bbox_w = int(bbox_w * random.uniform(0.5, 0.8))new_bbox_h = int(bbox_h * random.uniform(0.5, 0.8))bbox_w, bbox_h = new_bbox_w, new_bbox_hsuccess_num = 0while success_num < paste_number:center_search_space = [obj_xmin, obj_ymin, obj_xmax - new_bbox_w - 1, obj_ymax - new_bbox_h - 1] # 选取生成随机点区域if center_search_space[0] >= center_search_space[2] or center_search_space[1] >= center_search_space[3]:print('============== center_search_space error!!!! ================')success_num += 1continuenew_bbox_x_min = random.randint(center_search_space[0], center_search_space[2])  # 随机生成点坐标new_bbox_y_min = random.randint(center_search_space[1], center_search_space[3])new_bbox_x_left, new_bbox_y_top, new_bbox_x_right, new_bbox_y_bottom = new_bbox_x_min, new_bbox_y_min, new_bbox_x_min + new_bbox_w - 1, new_bbox_y_min + new_bbox_h - 1new_bbox = [cl, int(new_bbox_x_left), int(new_bbox_y_top), int(new_bbox_x_right), int(new_bbox_y_bottom)]success_num += 1new_bboxes.append(new_bbox)p_img = cv2.resize(p_img, (new_bbox_w, new_bbox_h))img = merge_img(img, p_img, new_bbox_y_top, new_bbox_y_bottom+1, new_bbox_x_left, new_bbox_x_right+1)return img, new_bboxesif __name__ == "__main__":# 用来装载参数的容器parser = argparse.ArgumentParser(description='PS')# 给这个解析对象添加命令行参数parser.add_argument('-i', '--images', default= '/media/yinzhe/DataYZ/DataSet/DataSet/bag_model',type=str, help='path of images')parser.add_argument('-t', '--mask', default= '/media/yinzhe/DataYZ/DataSet/DataSet/bag_mask',type=str, help='path of masks')parser.add_argument('-s', '--saveImage',default= '/media/yinzhe/DataYZ/DataSet/DataSet/bag_save', type=str, help='path of ')parser.add_argument('-c', '--scale', default= 0.2, type=float, help='number of img')parser.add_argument('-n', '--num', default= 5, type=int, help='number of img')args = parser.parse_args()  # 获取所有参数mask_filedirs = args.maskimages_path = args.imagessave_path = args.saveImagescale, num = args.scale, args.nummask_paths = []if not os.path.exists(save_path):os.makedirs(save_path)# 读取所有的 mask 模版mask_lst = []for t_path in os.listdir(mask_filedirs):mask = cv2.imread(os.path.join(mask_filedirs, t_path), cv2.IMREAD_UNCHANGED)if (mask.shape[2] != 4):  # RGB alphabreakmask_lst.append(mask)# template_paths = random.shuffle(template_paths) #打乱顺序for image_path in os.listdir(images_path) :if "txt" in image_path:continueimage = cv2.imread(os.path.join(images_path, image_path))pre_name = image_path.split('.')[0]bbox_lst = read_label_txt(os.path.join(images_path, pre_name + ".txt"))if image is None or len(bbox_lst) == 0:print("empty image !!! or empty label !!!")continue# yolo txt转化为x1y1x2y2rescale_bboxes = rescale_yolo_labels(bbox_lst, image.shape)  # 转换坐标表示# maskes_path = sample(mask_paths, int(len(bbox_lst) * scale))#for i in range(num):maskes = sample(mask_lst, int(len(bbox_lst) * scale))img, bboxes = random_add_patches_on_objects(image, maskes, rescale_bboxes, 1)boxes = xyxy2xywh(img, bboxes)img_name = pre_name + '_' + str(i) + '.jpg'print('handle img:', img_name)cv2.imwrite(os.path.join(save_path, img_name), img)with open(os.path.join(save_path, img_name[:-4] + ".txt"), 'a') as f:for box in boxes:mess = str(3) + " " + str(box[1]) + " " + str(box[2]) + " " + str(box[3] * 0.6) + " " + str(box[4]* 0.6) + "\n"f.write(mess)

相关文章:

「图像 merge」无中生有制造数据

在进行一个新项目的时候&#xff0c;往往缺少一些真实数据&#xff0c;导致没办法进行模型训练&#xff0c;这时候就需要算法工程师自行制作一些数据了&#xff0c;比如这篇文章分享的 bag 目标检测&#xff0c;在检测区域没有真实的 bag数据 此时&#xff0c;就可以采用图像拼…...

RK3588之ArmSoM-W3 + MPP实现多路硬解码拉流

简介 学习完MPP的解码Demo之后&#xff0c;想必大家都想通过一个项目来进行RK3588-MPP的解码实战。本篇文章就基于ArmSoM-W3开发板&#xff0c;开发一个多路硬解码项目&#xff0c;实现四路MPP硬解码拉流显示实现的效果如下&#xff1a; RK3588四路MPP硬解码拉流 环境介绍 硬件…...

【Rust日报】2023-10-29 隆重推出 Rerun 0.10!

Lapce代码编辑器发布v0.3.0 Lapce代码编辑器新发布v0.3.0&#xff01; https://lapce.dev/ 距离我们上次发布已经过去很长一段时间了。我们正忙着在自己的 UI 工具包Floem中重写 Lapce &#xff0c;这将使我们以后对 UI 部分代码的开发变得更容易、更快。 另一件值得注意的事情…...

AI智能识别如何助力PDF,轻松实现文档处理?

AI智能识别如何助力PDF&#xff0c;轻松实现文档处理&#xff1f; 随着科技的不断发展&#xff0c;人工智能&#xff08;AI&#xff09;在各个领域都发挥着重要的作用。其中&#xff0c;文档智能&#xff08; Document AI &#xff09;在金融、医疗、教育、保险、能源、物流等…...

【SA8295P 源码分析】114 - 将Android GVM userdata文件系统从 EXT4 修改为 F2FS

【SA8295P 源码分析】114 - 将Android GVM userdata文件系统从 EXT4 修改为 F2FS 一、代码修改方法1. BoardConfig.mk2. 修改 fstab二、开机进入 adb 验证2.1 验证 userdata 修改 f2fs 文件系统格式成功2.2 测试 f2fs 文件系统性能:androbench.apk系列文章汇总见:《【SA8295P…...

LeetCode 387 字符串中的第一个唯一字符 简单

题目 - 点击直达 1. 387 字符串中的第一个唯一字符1. 题目详情1. 原题链接2. 题目要求3. 基础框架 2. 解题思路1. 思路分析2. 时间复杂度3. 代码实现 1. 387 字符串中的第一个唯一字符 1. 题目详情 给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返…...

线程池--简单版本和复杂版本

目录 一、引言 二、线程池头文件介绍 三、简单版本线程池 1.创建线程池 2.添加任务到线程池 3.子线程执行回调函数 4.摧毁线程池 5.简单版线程池流程分析 四、复杂版本线程池 1.结构体介绍 2.主线程 3.子线程 4.管理线程 一、引言 多线程版服务器一个客户端就需要…...

docker进阶

文章目录 docker 进阶Part1 常用命令总结docker version 查看docker客户端和服务端信息docker info 查看更加详细信息docker images 列出所有镜像基本用法常用选项 docker search 搜索镜像基本用法示例用法 docker pull 拉取镜像基本用法示例用法 docker rmi 删除镜像基本用法示…...

Unity HoloLens 2 应用程序发布

设置3D 启动器画面&#xff0c;glb格式的模型 VS中可以直接生成所有大小的图标...

3D RPG Course | Core 学习日记三:Navigation智能导航地图烘焙

前言 前面我们已经绘制好了一个简单的地图场景&#xff0c;现在我们需要使用Navigation给地图做智能导航&#xff0c;以实现AI自动寻路&#xff0c;以及设置地图的可行走区域以及不可行走区域&#xff0c;Navigation的基础知识、原理、用法在Unity的官方文档&#xff0c;以及网…...

Linux 启用本地ISO作为软件源

环境&#xff1a;sle12sp5 &#xff08;open SUSE&#xff09; 1、禁用现有的源 查看源&#xff1a;sle12sp5 zypper lr -u ➜ sle12sp5 zypper lr -u Repository priorities are without effect. All enabled repositories share the same prior…...

SpringCloud-Alibaba-Nacos2.0.4

SpringCloud-Alibaba-Nacos2.0.4 SpringCloud Alibaba版本选择&#xff08;截止到2023年3月12日&#xff09; Spring Cloud Alibaba VersionSpring Cloud VersionSpring Boot Version2021.0.4.0*Spring Cloud 2021.0.42.6.11 SpringCloud Alibaba-2021.0.4.0组件版本关系 S…...

docker运行镜像相关配置文件

Dockerfile 文件配置 FROM anapsix/alpine-java:8_server-jre_unlimitedMAINTAINER Lion LiRUN mkdir -p /data/sydatasource/logs \/data/sydatasource/temp \/data/skywalking/agentWORKDIR /data/sydatasourceENV SERVER_PORT8220EXPOSE ${SERVER_PORT}ENV TZAsia/Shanghai …...

引擎系统设计思路 - 用户态与系统态隔离

用户态与系统态隔离&#xff1a; a. 外部用户侧的对象或者逻辑&#xff0c;在外部创建使用。内部系统侧的对象或者逻辑&#xff0c;在内部创建使用。 b. 用户状态下对内部系统的操作要立即响应&#xff0c;但是具体如何实际执行系统内部的机制&#xff0c;则是异步并行的。因为…...

致远OA wpsAssistServlet任意文件读取漏洞复现 [附POC]

文章目录 致远OA wpsAssistServlet任意文件读取漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 致远OA wpsAssistServlet任意文件读取漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用…...

​轻量应用服务器有什么优势?如何评价亚马逊云科技轻量应用服务器?

什么是轻量应用服务器&#xff1f; 随着如今各行各业对云计算的需求越来越多&#xff0c;云服务器也被越来越多的企业所广泛采用。其中&#xff0c;轻量应用服务器是一种简单、高效、可靠的云计算服务&#xff0c;能够为开发人员、企业和个人提供轻量级的虚拟专用服务器&#…...

python的日志模块学习记录

logging模块是Python的内置日志模块满足日常需要 使用方法 *** 1.导入*** import logging from logging import config*** 2.配置日志配置项(基本配置一般不能满足需要&#xff0c;一般使用字典配置如下)*** # 日志基本配置方法&#xff0c;一般不能满足需要 logging.basic…...

【java】redisTemplate mock时报空指针

原方法&#xff1a; Boolean locked redisTemplate.opsForValue().setIfAbsent(redisKey, "", 400, TimeUnit.SECONDS);mock方法 mock方法&#xff1a; 需要每个函数都mock。 Mock RedisTemplate redisTemplate;... ValueOperations<String, String> value…...

Hadoop PseudoDistributed Mode 伪分布式

Hadoop PseudoDistributed Mode 伪分布式加粗样式 hadoop101hadoop102hadoop103192.168.171.101192.168.171.102192.168.171.103namenodesecondary namenoderecource managerdatanodedatanodedatanodenodemanagernodemanagernodemanagerjob historyjob logjob logjob log 1. …...

个人职业规划

职业规划 软件体系结构 内容 组件 关系 视图 技术 抽象 封装 信息隐藏 模块化 事务分离 耦合和内聚 充分性、完整性和原始性 策略和实现的分离 接口和实现的分离 单一引用点 分而治之 结构 层 管道和过滤器 黑板 系统 分布式系统 代理者 交互式系统 …...

【win | docker开启远程配置】使用 SSH 隧道访问 Docker的前操作

在主机A pycharm如何连接远程主机B win docker? 需要win docker配置什么&#xff1f; 快捷配置-主机B win OpenSSH SSH Server https://blog.csdn.net/z164470/article/details/121683333 winR,打开命令行&#xff0c;输入net start sshd,启动SSH。 或者右击我的电脑&#…...

chili3d 笔记17 c++ 编译hlr 带隐藏线工程图

这个要注册不然emscripten编译不起来 --------------- 行不通 ---------------- 结构体 using LineSegment std::pair<gp_Pnt, gp_Pnt>;using LineSegmentList std::vector<LineSegment>; EMSCRIPTEN_BINDINGS(Shape_Projection) {value_object<LineSegment&g…...

鸿蒙图片缓存(一)

移动端开发过程中图片缓存功能是必备&#xff0c;iOS和安卓都有相关工具库&#xff0c;鸿蒙系统组件本身也自带缓存功能&#xff0c;但是遇到复杂得逻辑功能还是需要封装图片缓存工具。 系统组件Image 1. Image的缓存策略 Image模块提供了三级Cache机制&#xff0c;解码后内…...

pe文件结构(TLS)

TLS 什么是TLS? TLS是 Thread Local Storage 的缩写&#xff0c;线程局部存储。主要是为了解决多线程中变量同步的问题 如果需要要一个线程内部的各个函数调用都能访问&#xff0c;但其它线程不能访问的变量&#xff08;被称为static memory local to a thread 线程局部静态变…...

中型零售业数据库抉择:MySQL省成本,SQL SERVER?

针对中型零售企业&#xff08;20台固定POS数十台移动POS&#xff0c;含库存管理与结算业务&#xff09;的操作系统与数据库选型&#xff0c;需平衡性能、成本、扩展性及运维效率。结合行业实践与系统需求&#xff0c;建议如下&#xff1a; &#x1f5a5;️ ​​一、操作系统选型…...

html文字红色粗体,闪烁渐变动画效果,中英文切换版本

1. 代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>红色粗体闪烁文字表格 - 中英文切换</t…...

STM32H562----------ADC外设详解

1、ADC 简介 STM32H5xx 系列有 2 个 ADC,都可以独立工作,其中 ADC1 和 ADC2 还可以组成双模式(提高采样率)。每个 ADC 最多可以有 20 个复用通道。这些 ADC 外设与 AHB 总线相连。 STM32H5xx 的 ADC 模块主要有如下几个特性: 1、可配置 12 位、10 位、8 位、6 位分辨率,…...

PHP 复制商品扩展实操:轻松切换一号通、99api ,实现商品复制功能

目前已有一号通、99api复制商品扩展 复制商品扩展入口 namespace crmeb\services\copyproduct;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use think\facade\Config; use think\Container;/*** Class Product* package crmeb\services\copyp…...

区块链架构深度解析:从 Genesis Block 到 Layer 2

# 区块链架构深度解析&#xff1a;从 Genesis Block 到 Layer 2 目录 一、Genesis Block&#xff1a;区块链的起点 二、Layer 0&#xff1a;区块链的底层网络架构 三、Layer 1&#xff1a;核心协议层 &#x1f680; 四、Layer 2&#xff1a;扩展性解决方案 五、未来展望&a…...

黑马Java面试笔记之 微服务篇(SpringCloud)

一. SpringCloud 5大组件 SpringCloud 5大组件有哪些&#xff1f; 总结 五大件分别有&#xff1a; Eureka&#xff1a;注册中心Ribbon&#xff1a;负载均衡Feign&#xff1a;远程调用Hystrix&#xff1a;服务熔断Zuul/Gateway&#xff1a;网关 如果项目用到了阿里巴巴&#xff…...