当前位置: 首页 > 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. …...

个人职业规划

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

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...