深度图数据增强方案-随机增加ROI区域的深度

news2025/5/29 10:34:55

主要思想:随机增加ROI区域的深度,模拟物体处在不同位置的形态。

首先打印一张深度图中的深度信息分布:

import cv2
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns  

def plot_grayscale_histogram(image_path):
    # 读取图像(保留16位深度)
    img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
    print(img)

    if img is None:
        print("错误:无法读取图像,请检查文件路径")
        return

    # 验证图像格式
    if len(img.shape) != 2 or img.dtype != np.uint16:
        print("警告:非单通道16位图像,当前形状:", img.shape, "数据类型:", img.dtype)
        
    # 创建带KDE的直方图
    plt.figure(figsize=(10, 6))
    
    # 使用展平后的图像数据
    sns.histplot(
        x=img.flatten(),  # 将二维数组展平为一维
        bins=50,          # 增加bins数量以更好显示16位数据分布
        color="lightblue",
        edgecolor="black",
        kde=True,
        # stat="density"    # 将计数转换为密度概率
    )

    # 设置标题和标签
    plt.title("Depth Value Distribution", fontsize=14)
    plt.xlabel("Depth Value (16-bit)", fontsize=12)
    plt.ylabel("Density", fontsize=12)
    
    # 添加网格和格式优化
    plt.grid(axis="y", linestyle="--", alpha=0.5)
    plt.xlim(0, 65535)  # 设置16位数据范围
    
    # 显示图形
    plt.show()

    # 显示原始深度图的归一化预览
    normalized = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    cv2.imshow('Normalized Preview', normalized)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == "__main__":
    image_path = "C:/pyprojects/yolo11/Dataset_depth/images/train/1112_0-rgb.png"
    plot_grayscale_histogram(image_path)

结果如下:

然后我们单独画一下中间的ROI区域:

img = img[342:515, 389:873]

现在随机增加ROI区域的深度,模拟不同纵向的位置:

# 本数据集生成的代码
# 数据增强方法:随机增加ROI区域的深度,模拟箱子在不同纵向位置摆放
# 训练集:76665张,测试集:18975张

import cv2
import os
import numpy as np
import shutil

image_file_dir = "C:/pyprojects/yolo11/fheiaunjk/images"
min_val = 0  # 最小偏移量
max_val = 500   # 最大偏移量
output_dir = "C:/pyprojects/yolo11/output"

# 正确拼接输出路径
img_output_path = os.path.join(output_dir, "images")  # 正确写法
label_output_path = os.path.join(output_dir, "labels")  # 正确写法

# 直接创建目标目录(无需使用 os.path.dirname)
os.makedirs(img_output_path, exist_ok=True)    # 创建 output/images
os.makedirs(label_output_path, exist_ok=True)  # 创建 output/labels

for filename in os.listdir(image_file_dir):
    # 1. 构建图片完整路径
    image_file_path = os.path.join(image_file_dir, filename)
    
    # 2. 构建标签文件路径
    labels_dir = image_file_dir.replace("images", "labels")
    base_name = os.path.splitext(filename)[0]  # 去掉文件扩展名
    label_file_path = os.path.join(labels_dir, f"{base_name}.txt")  # 正确路径
    
    # 3. 检查标签文件是否存在
    if not os.path.exists(label_file_path):
        print(f"警告:标签文件 {label_file_path} 不存在")
        continue
    
    # 4. 读取图片并检查有效性
    image = cv2.imread(image_file_path, cv2.IMREAD_UNCHANGED)
    if image is None:
        print(f"错误:无法读取图片 {image_file_path}")
        continue
    
    # 5. 获取图像尺寸(兼容单通道/多通道)
    if len(image.shape) == 2:  # 单通道(H, W)
        image_height, image_width = image.shape
        print(f"图像尺寸:{image_width}x{image_height}")
    else:  # 多通道(H, W, C)
        print(f"错误:图片 {image_file_path} 不是深度图")
        continue

    with open(label_file_path, 'r') as f:
        lines = f.readlines()

    i = 0

    # 绘制每个检测框
    for k, line in enumerate(lines):
        parts = line.strip().split()
        if len(parts) < 5:
            continue
        
        # 解析YOLO格式数据
        class_id = int(parts[0])
        x_center = float(parts[1]) * image_width
        y_center = float(parts[2]) * image_height
        width = float(parts[3]) * image_width
        height = float(parts[4]) * image_height
        
        # 计算坐标
        x1 = int(x_center - width/2)
        y1 = int(y_center - height/2)
        x2 = int(x_center + width/2)
        y2 = int(y_center + height/2)

        # --- 生成单个随机数 ---
        for m in range(5):
            i = k * 5 + m
            random_offset = np.random.randint(min_val, max_val + 1)  # 生成一个随机整数
            region = image[y1 : y2, x1 : x2]
            modified_region = np.clip(region.astype(np.int32) + random_offset, 0, 65535).astype(np.uint16)
            image[y1 : y2, x1 : x2] = modified_region
            image_output_path = os.path.join(img_output_path, f"{base_name}_{i}.png")
            cv2.imwrite(image_output_path, image)  # 写入图片

            # 拷贝标签
            output_label_path = os.path.join(label_output_path, f"{base_name}_{i}.txt")
            print(output_label_path)
            shutil.copy2(label_file_path, output_label_path)

0523更新:增加ROI区域边缘平滑功能,避免边缘出现明显的锯齿或突变:

# 本数据集生成的代码
# 数据增强方法:随机增加ROI区域的深度,模拟不同纵向位置摆放

import cv2
import os
import numpy as np
import shutil

image_file_dir = "Dataset_depth/images/val"
min_val = 0  # 最小偏移量
max_val = 500   # 最大偏移量
output_dir = "/home/hary/ctc/ultralytics-main/output"

# 正确拼接输出路径
img_output_path = os.path.join(output_dir, "images")  # 正确写法
label_output_path = os.path.join(output_dir, "labels")  # 正确写法

# 直接创建目标目录(无需使用 os.path.dirname)
os.makedirs(img_output_path, exist_ok=True)    # 创建 output/images
os.makedirs(label_output_path, exist_ok=True)  # 创建 output/labels

for filename in os.listdir(image_file_dir):
    # 1. 构建图片完整路径
    image_file_path = os.path.join(image_file_dir, filename)
    
    # 2. 构建标签文件路径
    labels_dir = image_file_dir.replace("images", "labels")
    base_name = os.path.splitext(filename)[0]  # 去掉文件扩展名
    label_file_path = os.path.join(labels_dir, f"{base_name}.txt")  # 正确路径
    
    # 3. 检查标签文件是否存在
    if not os.path.exists(label_file_path):
        print(f"警告:标签文件 {label_file_path} 不存在")
        continue
    
    # 4. 读取图片并检查有效性
    image = cv2.imread(image_file_path, cv2.IMREAD_UNCHANGED)
    if image is None:
        print(f"错误:无法读取图片 {image_file_path}")
        continue
    
    # 5. 获取图像尺寸(兼容单通道/多通道)
    if len(image.shape) == 2:  # 单通道(H, W)
        image_height, image_width = image.shape
        print(f"图像尺寸:{image_width}x{image_height}")
    else:  # 多通道(H, W, C)
        print(f"错误:图片 {image_file_path} 不是深度图")
        continue

    with open(label_file_path, 'r') as f:
        lines = f.readlines()

    i = 0

    # 绘制每个检测框
    for k, line in enumerate(lines):
        parts = line.strip().split()
        if len(parts) < 5:
            continue
        
        # 解析YOLO格式数据
        class_id = int(parts[0])
        x_center = float(parts[1]) * image_width
        y_center = float(parts[2]) * image_height
        width = float(parts[3]) * image_width
        height = float(parts[4]) * image_height
        
        # 计算坐标
        x1 = int(x_center - width/2)
        y1 = int(y_center - height/2)
        x2 = int(x_center + width/2)
        y2 = int(y_center + height/2)

        # --- 生成单个随机数 ---
        for m in range(1):
            i = k * 1 + m
            random_offset = np.random.randint(min_val, max_val + 1)  # 生成一个随机整数
            
            # 保存原始ROI区域
            original_roi = image[y1:y2, x1:x2].copy()

            # 生成随机偏移后的ROI
            modified_roi = np.clip(original_roi.astype(np.int32) + random_offset, 0, 65535).astype(np.uint16)

            # 创建羽化遮罩(核心修改部分)
            height, width = original_roi.shape[:2]
            mask = np.zeros((height, width), dtype=np.float32)

            # 创建椭圆渐变遮罩(比实际区域稍小)
            cv2.ellipse(mask, 
                    (int(width/2), int(height/2)),
                    (int(width/2*0.8), int(height/2*0.8)),  # 控制羽化范围
                    0, 0, 360, 1.0, -1)

            # 添加高斯模糊柔化边缘
            mask = cv2.GaussianBlur(mask, (0, 0), sigmaX=width/8, sigmaY=height/8)
            mask = mask / np.max(mask)  # 归一化到[0,1]

            # 混合原始和修改后的区域
            blended_roi = original_roi.astype(np.float32) * (1 - mask) + \
                        modified_roi.astype(np.float32) * mask

            # 写回图像并保持数据类型
            image[y1:y2, x1:x2] = np.clip(blended_roi, 0, 65535).astype(np.uint16)

            image_output_path = os.path.join(img_output_path, f"{base_name}_{i}.png")
            cv2.imwrite(image_output_path, image)  # 写入图片

            # 拷贝标签
            output_label_path = os.path.join(label_output_path, f"{base_name}_{i}.txt")
            print(f"{output_label_path} has created!")
            shutil.copy2(label_file_path, output_label_path)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2386182.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

两个mysql的maven依赖要用哪个?

背景 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> </dependency>和 <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId> &l…

Kafka Consumer工作流程

Kafka Consumer工作流程图 1、启动与加入组 消费者启动后&#xff0c;会向 Kafka 集群中的某个 Broker 发送请求&#xff0c;请求加入特定消费者组。这个 Broker 中的消费者协调器&#xff08;Consumer Coordinator&#xff09;负责管理消费者组相关事宜。 2、组内分区分配&am…

大腾智能 PDM 系统:全生命周期管理重塑制造企业数字化转型路径

在当今激烈的市场竞争中&#xff0c;产品迭代速度与质量已成为企业生存与发展的核心命脉。面对客户需求多元化、供应链协同复杂化、研发成本管控精细化等挑战&#xff0c;企业亟需一套能够贯穿产品全生命周期的数字化解决方案。 大腾智能PDM系统通过构建覆盖设计、研发、生产、…

【短距离通信】【WiFi】WiFi7关键技术之4096-QAM、MRU

目录 3. 4096-QAM 3.1 4096-QAM 3.2 QAM 的阶数越高越好吗&#xff1f; 4. MRU 4.1 OFDMA 和 RU 4.2 MRU 资源分配 3. 4096-QAM 摘要 本章主要介绍了Wi-Fi 7引入的4096-QAM对数据传输速率的提升。 3.1 4096-QAM 对速率的提升 Wi-Fi 标准一直致力于提升数据传输速率&a…

线程池实战——数据库连接池

引言 作者在前面写了很多并发编程知识深度探索系列文章&#xff0c;反馈得知友友们收获颇丰&#xff0c;同时我也了解到友友们也有了对知识如何应用感到很模糊的问题。所以作者就打算写一个实战系列文章&#xff0c;让友友们切身感受一下怎么应用知识。话不多说&#xff0c;开…

基于moonshot模型的Dify大语言模型应用开发核心场景

基于moonshot模型的Dify大语言模型应用开发核心场景学习总结 一、Dify环境部署 1.Docker环境部署 这里使用vagrant部署&#xff0c;下载vagrant之后&#xff0c;vagrant up登陆&#xff0c;vagrant ssh&#xff0c;在vagrant 中使用 vagrant centos/7 init 快速创建虚拟机 安装…

华为OD机试真题——字符串序列判定(2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 B卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

工商总局可视化模版-Echarts的纯HTML源码

概述 基于ECharts的工商总局数据可视化HTML模版&#xff0c;帮助开发者快速搭建专业级工商广告数据展示平台。这款模版设计规范&#xff0c;功能完善&#xff0c;适合各类工商监管场景使用。 主要内容 本套模版采用现代化设计风格&#xff0c;主要包含以下核心功能模块&…

Spring AI 和 Elasticsearch 作为你的向量数据库

作者&#xff1a;来自 Elastic Josh Long, Philipp Krenn 及 Laura Trotta 使用 Spring AI 和 Elasticsearch 构建一个完整的 AI 应用程序。 Elasticsearch 原生集成了业界领先的生成式 AI 工具和服务提供商。查看我们关于超越 RAG 基础或使用 Elastic 向量数据库构建生产级应用…

集群聊天服务器学习 配置开发环境(VScode远程连接虚拟机Linux开发)(2)

配置远程开发环境 第一步&#xff1a;Linux系统运行sshd服务 第二步&#xff1a;在vscode上安装Remote Deve I opment插件&#xff0c;其依赖插件会自动安装 第三步&#xff1a;配置远程Linux主机的信息 第四步&#xff1a;在vscode上开发远程连接Linux 第一步&#xff1a;…

rabbitmq的使用介绍

一.队列工作模式介绍 1.WorkQueues模型 生产者直接把消息发送给队列&#xff0c;然后消费者订阅队列 特点: 消息不会重复, 分配给不同的消费者. 代码实现&#xff1a; 消费者代码&#xff1a; Component Slf4j public class SpringRabbitListener {RabbitListener(queues &q…

系统编程day04

一.进程的基本概念 一.定义 进程是一个程序执行的过程&#xff08;也可以说是正在运行的程序&#xff09;&#xff0c;是系统分配资源的基本单位&#xff0c;由cpu对各个进程指挥调度&#xff0c;在单核cpu的情况下,各个进程可以通过一定规则在cpu上并发运行。 二.PCB块 1.PC…

Arduino Uno KY-037声音传感器实验

KY-037声音传感器实验 KY-037声音传感器实验1、 实验内容2、KY-037声音传感器介绍3、实验注意事项4、代码和实验现象 KY-037声音传感器实验 1、 实验内容 通过对KY-037声音传感器吹气&#xff0c;控制LED的打开和关闭&#xff0c;吹一下LED打开&#xff0c;在吹一下LED关闭。…

基于音频Transformer与动作单元的多模态情绪识别算法设计与实现(在RAVDESS数据集上的应用)

摘要&#xff1a;情感识别技术在医学、自动驾驶等多个领域的广泛应用&#xff0c;正吸引着研究界的持续关注。本研究提出了一种融合语音情感识别&#xff08;SER&#xff09;与面部情感识别&#xff08;FER&#xff09;的自动情绪识别系统。在SER方面&#xff0c;我们采用两种迁…

什么是VR实景?有哪些高价值场景?

在数字化浪潮的推动下&#xff0c;虚拟现实技术正以前所未有的速度改变着我们的生活方式和工作模式。 其中&#xff0c;VR实景作为VR技术的一个重要应用场景&#xff0c;独特的沉浸感和交互性&#xff0c;在众多领域展现出应用潜力和高价值场景。什么是VR实景&#xff1f;VR实…

同一无线网络下的设备IP地址是否相同?

在家庭和办公网络普及的今天&#xff0c;许多人都会好奇&#xff1a;连接同一个Wi-Fi的设备是否共享相同的IP地址&#xff1f;这个问题看似简单&#xff0c;实则涉及多个角度。本文将为您揭示其中的技术奥秘。 用一个无线网IP地址一样吗&#xff1f;同一无线网络&#xff08;如…

第2周 PINN核心技术揭秘: 如何用神经网络求解偏微分方程

1. PDEs与传统数值方法回顾 (Review of PDEs & Traditional Numerical Methods) 1.1 什么是偏微分方程 (Partial Differential Equations, PDEs)? 偏微分方程是描述自然界和工程领域中各种物理现象(如热量传播、流体流动、波的振动、电磁场分布等)的基本数学语言。 1.…

【C语言】习题练手套餐 2

每日习题分享。 字符串函数的运用 首先回顾一下字符串函数。 字符串长度 strlen(const char *s);功能&#xff1a;计算字符串的长度&#xff0c;不包含终止符\0。 字符串连接 char *strcat(char *dest, const char *src); char *strncat(char *dest, const char *src, si…

[项目总结] 基于Docker与Nginx对项目进行部署

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

神经正切核推导(2)

对神经正切核的理解和推导&#xff08;1&#xff09;-CSDN博客 这篇文章包括很多概念的理解 声明&#xff1a; 本篇文章来自于Neural Tangent Kernel &#xff08;NTK&#xff09;基础推导 - Gearlesskai - 博客园 旨在对上述推导过程进行再推导与理解 手写推导部分与其他颜…