从视频帧生成点云数据、使用PointNet++模型提取特征,并将特征保存下来的完整实现。

news2024/11/19 6:57:47

文件地址

https://github.com/yanx27/Pointnet_Pointnet2_pytorch?spm=5176.28103460.0.0.21a95d27ollfze

Pointnet_Pointnet2_pytorch\log\classification\pointnet2_ssg_wo_normals文件夹改名为Pointnet_Pointnet2_pytorch\log\classification\pointnet2_cls_ssg

"E:\Pointnet_Pointnet2_pytorch\provider.py" 在provider.py文件头添加

def pc_normalize(pc):
    l = pc.shape[0]
    centroid = np.mean(pc, axis=0)
    pc = pc - centroid
    m = np.max(np.sqrt(np.sum(pc**2, axis=1)))
    pc = pc / m
    return pc

详细介绍了如何从视频帧中生成点云数据并使用PointNet++模型提取特征,最后将特征保存下来。
从视频帧中生成点云数据并提取特征
1. 引言

在计算机视觉领域,点云数据是一种重要的三维数据形式,广泛应用于自动驾驶、机器人导航、物体识别等场景。本文将详细介绍如何从视频帧中生成点云数据,并使用PointNet++模型提取特征,最后将特征保存下来以供后续分析或使用。
2. 环境准备

在开始之前,确保你的环境中安装了以下依赖项:

    Python 3.6+
    PyTorch 1.7+
    Open3D
    OpenCV
    NumPy

你可以使用以下命令安装这些依赖项:

pip install torch torchvision
pip install open3d opencv-python numpy

3. 代码实现

import os
import sys
# 获取当前脚本所在的目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 将 models 目录添加到 sys.path
sys.path.insert(0, os.path.join(current_dir, 'models'))
import numpy as np
import torch
import cv2
import open3d as o3d
from models.pointnet2_cls_ssg import get_model
from provider import pc_normalize
import time
import hashlib


# 打印 sys.path 以确认路径是否正确
print(sys.path)

# 设置设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"设备设置为: {device}")

# 加载预训练模型
#"E:\Pointnet_Pointnet2_pytorch\log\classification\pointnet2_cls_ssg\checkpoints\best_model.pth"
model_path = os.path.join('log', 'classification', 'pointnet2_cls_ssg', 'checkpoints', 'best_model.pth')  # 替换为实际路径
print(f"加载预训练模型: {model_path}")
model = get_model(num_class=40, normal_channel=False).to(device)

# 只加载模型参数
checkpoint = torch.load(model_path, map_location=device)
model.load_state_dict(checkpoint['model_state_dict'])
model.eval()
print("模型加载完成")

# 从视频帧生成点云数据
def frame_to_point_cloud(frame, depth_frame=None):
    if depth_frame is None:
        # 如果没有深度图,使用随机生成的点云数据作为示例
        points = np.random.rand(1024, 3)  # 生成 1024 个点,每个点有 3 个坐标
    else:
        # 使用深度图生成点云
        h, w = depth_frame.shape
        y, x = np.indices((h, w))
        z = depth_frame
        points = np.stack([x, y, z], axis=-1).reshape(-1, 3)
        points = points[~np.isnan(points).any(axis=1)]  # 去除无效点
        if points.shape[0] > 1024:
            points = points[np.random.choice(points.shape[0], 1024, replace=False)]
        elif points.shape[0] < 1024:
            points = np.pad(points, ((0, 1024 - points.shape[0]), (0, 0)), mode='constant')
    print(f"生成点云数据: {points.shape}")
    return points

# 提取特征
def extract_features(model, point_cloud):
    point_cloud = pc_normalize(point_cloud)  # 归一化点云
    point_cloud = torch.from_numpy(point_cloud).float().unsqueeze(0).transpose(2, 1).to(device)
    with torch.no_grad():
        pred, trans_feat = model(point_cloud)  # 只接收两个返回值
    print(f"提取特征完成: {pred.shape}")
    return pred.cpu().numpy()

# 处理单个视频文件
def process_video(video_path, output_folder):
    cap = cv2.VideoCapture(video_path)
    frame_count = 0
    video_name = os.path.basename(video_path).split('.')[0]
    print(f"开始处理视频: {video_path}")
    all_features = []
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        # 生成点云数据
        point_cloud = frame_to_point_cloud(frame)
        if point_cloud.shape[0] < 1024:  # 确保至少有 1024 个点
            print(f"帧 {frame_count} 点云数据不足,跳过")
            continue  # 如果点不够,跳过此帧

        # 提取特征
        features = extract_features(model, point_cloud)
        print(f"处理帧 {frame_count} 特征: {features}")

        # 保存特征到 all_features 列表中
        all_features.append(features)

        frame_count += 1

    cap.release()
    print(f"视频处理完成: {video_path}")

    # 生成唯一的文件名
    output_file = os.path.join(output_folder, f'{video_name}_features.npy')

    # 将所有特征保存到一个文件中
    np.save(output_file, np.vstack(all_features))
    print(f"特征已保存到: {output_file}")

# 检查视频文件是否已处理
def is_video_processed(video_path, processed_videos):
    video_hash = hashlib.md5(video_path.encode()).hexdigest()
    return video_hash in processed_videos

# 获取已处理的视频文件列表
def get_processed_videos(output_file):
    if not os.path.exists(output_file):
        return set()
    
    processed_videos = set()
    with open(output_file, 'r') as f:
        for line in f:
            processed_videos.add(line.strip())
    return processed_videos

# 记录已处理的视频文件
def record_processed_video(video_path, output_file):
    video_hash = hashlib.md5(video_path.encode()).hexdigest()
    with open(output_file, 'a') as f:
        f.write(video_hash + '\n')

# 处理视频文件夹
def process_video_folder(folder_path, output_folder):
    processed_videos_file = os.path.join(output_folder, 'processed_videos.txt')
    processed_videos = get_processed_videos(processed_videos_file)
    print(f"开始处理视频文件夹: {folder_path}")
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.endswith('.mp4') or file.endswith('.avi'):
                video_path = os.path.join(root, file)
                if is_video_processed(video_path, processed_videos):
                    print(f"视频已处理,跳过: {video_path}")
                    continue
                process_video(video_path, output_folder)
                record_processed_video(video_path, processed_videos_file)

    print("所有视频处理完成")

# 主程序
if __name__ == "__main__":
    # 视频文件夹路径
    input_folder = r'E:\Pointnet_Pointnet2_pytorch\data\voide'
    output_folder = r'E:\Pointnet_Pointnet2_pytorch\data\voide_features'  # 特征保存路径

    # 确保输出文件夹存在
    os.makedirs(output_folder, exist_ok=True)

    # 处理视频文件夹
    process_video_folder(input_folder, output_folder)


3.1 导入必要的库

首先,我们需要导入一些必要的库,包括文件操作、数值计算、深度学习框架、图像处理和点云处理相关的库。
3.2 设置设备

检查是否有可用的GPU,并设置设备。如果存在GPU,将使用GPU进行计算;否则,使用CPU。
3.3 加载预训练模型

我们使用PointNet++模型来提取点云特征。首先,加载预训练模型。这通常涉及以下几个步骤:

    指定模型路径:提供预训练模型的路径。
    加载模型:使用 get_model 函数创建模型实例,并将其移动到指定的设备(CPU或GPU)。
    加载模型参数:从预训练模型文件中加载模型参数,并设置模型为评估模式。

3.4 从视频帧生成点云数据

定义一个函数 frame_to_point_cloud,该函数从视频帧中生成点云数据。如果没有深度图,可以生成随机点云数据作为示例。具体步骤如下:

    生成随机点云:如果没有深度图,生成1024个随机点,每个点有3个坐标。
    使用深度图生成点云:如果有深度图,从深度图中提取点云数据。具体做法是将深度图的每个像素位置(x, y)和对应的深度值z组合成一个三维点(x, y, z)。然后,去除无效点,并确保点云数据的形状为 (1024, 3)。

3.5 提取特征

定义一个函数 extract_features,该函数使用预训练模型提取点云数据的特征。具体步骤如下:

    归一化点云:对点云数据进行归一化处理,使其适合输入到模型中。
    转换为张量:将点云数据转换为PyTorch张量,并移动到指定的设备。
    提取特征:使用预训练模型提取特征,并返回特征向量。

3.6 处理单个视频文件

定义一个函数 process_video,该函数处理单个视频文件,逐帧生成点云数据并提取特征。具体步骤如下:

    打开视频文件:使用OpenCV的 cv2.VideoCapture 打开视频文件。
    读取帧:逐帧读取视频。
    生成点云数据:调用 frame_to_point_cloud 函数生成点云数据。
    提取特征:调用 extract_features 函数提取特征。
    保存特征:将提取的特征保存为 .npy 文件。

3.7 处理视频文件夹

定义一个函数 process_video_folder,该函数处理指定文件夹中的所有视频文件。具体步骤如下:

    遍历文件夹:使用 os.walk 遍历指定文件夹中的所有视频文件。
    处理每个视频:调用 process_video 函数处理每个视频文件。

3.8 主程序

在主程序中,指定输入视频文件夹和输出特征文件夹的路径,并调用 process_video_folder 函数处理所有视频文件。
4. 总结

本文详细介绍了如何从视频帧中生成点云数据,并使用PointNet++模型提取特征,最后将特征保存下来。通过这些步骤,你可以将视频数据转换为点云数据,并提取有用的特征,为后续的分析和应用提供支持。

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

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

相关文章

Websocket如何分块处理数据量超大的消息体

若我们服务端一次性最大处理的字节数是1M,而客户端发来了2M的数据&#xff0c;此时服务端的数据就要被切割成两次传输解码。Http协议中有分块传输&#xff0c;而在Websocket也可以分块处理超大的消息体。在jsr356标准中使用javax.websocket.MessageHandler.Partial可以分块处理…

论文复现_How Machine Learning Is Solving the Binary Function Similarity Problem

1. 内容概述 前言&#xff1a;此代码库支持 USENIX Security 22 论文 《How Machine Learning Is Solving the Binary Function Similarity Problem》&#xff0c;作者包括 Andrea Marcelli 等人&#xff0c;提供了相关代码、数据集和技术细节。 关键内容&#xff1a;技术报告…

【视觉SLAM】2-三维空间刚体运动的数学表示

读书笔记&#xff1a;学习空间变换的三种数学表达形式。 文章目录 1. 旋转矩阵1.1 向量运算1.2 坐标系空间变换1.3 变换矩阵与齐次坐标 2. 旋转向量和欧拉角2.1 旋转向量2.2 欧拉角 3. 四元数 1. 旋转矩阵 1.1 向量运算 对于三维空间中的两个向量 a , b ∈ R 3 a,b \in \R^3 …

【WPF】Prism学习(六)

Prism Dependency Injection 1.依赖注入&#xff08;Dependency Injection&#xff09; 1.1. Prism与依赖注入的关系&#xff1a; Prism框架一直围绕依赖注入构建&#xff0c;这有助于构建可维护和可测试的应用程序&#xff0c;并减少或消除对静态和循环引用的依赖。 1.2. P…

多账号登录管理器(淘宝、京东、拼多多等)

目录 下载安装与运行 解决什么问题 功能说明 目前支持的平台 功能演示 登录后能保持多久 下载安装与运行 下载、安装与运行 语雀 解决什么问题 多个账号的快捷登录与切换 功能说明 支持多个电商平台支持多个账号的登录保持支持快捷切换支持导入导出支持批量删除支持…

UniAPP快速入门教程(一)

一、下载HBuilder 首先需要下载HBuilder开发工具&#xff0c;下载地址:https://www.dcloud.io/hbuilderx.htmlhttps://www.dcloud.io/hbuilder.html 选择Windows正式版.zip文件下载。下载解压后直接运行解压目录里的HBuilderX.exe就可以启动HBuilder。 UniApp的插件市场网址…

PyAEDT:Ansys Electronics Desktop API 简介

在本文中&#xff0c;我将向您介绍 PyAEDT&#xff0c;这是一个 Python 库&#xff0c;旨在增强您对 Ansys Electronics Desktop 或 AEDT 的体验。PyAEDT 通过直接与 AEDT API 交互来简化脚本编写&#xff0c;从而允许在 Ansys 的电磁、热和机械求解器套件之间无缝集成。通过利…

SpringBoot源码解析(四):解析应用参数args

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args 目录…

【Linux】指令 + 重定向操作

Linux基本指令 一.Linux基本指令1.mv&#xff08;重要&#xff09;2.cat3.more和less&#xff08;重要&#xff09;4.head和tail5.date6.cal7.find&#xff08;重要&#xff09; 二.Linux相关知识点1. Linux系统中&#xff1a;一切皆文件2. 重定向操作1. 输出重定向2. 追加重定…

【精通 Readline 库】:优化 Shell 外壳程序的艺术

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

ESP-IDF VScode 项目构建/增加组件 新手友好!!!

项目构建 1.新建文件夹&#xff0c;同时在该文件夹内新建.c和.h文件 如图所示&#xff0c;在components中新建ADC_User.c、ADC_User.h、CMakeLists.txt文件。当然这里你也可以不在components文件夹内新建文件&#xff0c;下面会说没有在components文件夹内新建文件构建项目的方…

玩转N1盒子:速刷OpenWRT软路由系统并实现公网访问管理

文章目录 前言1. 制作刷机固件U盘1.1 制作刷机U盘需要准备以下软件&#xff1a;1.2 制作步骤 2. N1盒子降级与U盘启动2.1 N1盒子降级2.2 N1盒子U盘启动设置2.3 使用U盘刷入OpenWRT2.4 OpenWRT后台IP地址修改2.5 设置旁路由&无线上网 3. 安装cpolar内网穿透3.1 下载公钥3.2 …

机器学习4

九、线性回归 1、概念 假设存在多个点&#xff0c;需要使用一条线来保障尽量拟合这些点&#xff0c;寻找这条线就叫回归。 机器学习中一种有监督学习的算法,回归问题主要关注的是因变量(需要预测的值)和一个或多个数值型的自变量(预测变量)之间的关系。 2、损失函数 存…

【Java EE初阶---多线程(初阶)】初识计算机

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java &#xff0c;Java数据结构 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 文章目录…

网络安全之国际主流网络安全架构模型

目前&#xff0c;国际主流的网络安全架构模型主要有&#xff1a; ● 信息技术咨询公司Gartner的ASA&#xff08;Adaptive Security Architecture自适应安全架构&#xff09; ● 美国政府资助的非营利研究机构MITRE的ATT&CK&#xff08;Adversarial Tactics Techniques &…

生成式人工智能(AIGC)在软件开发设计模式课程教学中的应用

一、引言 软件设计模式作为软件工程领域的核心组成部分&#xff0c;对于提升软件系统的质量和可维护性至关重要。然而&#xff0c;传统的软件设计模式课程教学方法面临着诸多挑战&#xff0c;例如教师准备教学案例的过程繁琐&#xff0c;学生理解和应用具体案例难度较大&#…

丹摩征文活动|摩智算平台深度解析:Faster R-CNN模型的训练与测试实战

目录 文章前言Faster R-CNN的简介Faster RCNN的训练与测试提前准备1.1 mobaxterm&#xff08;远程连接服务器&#xff09;1.2 本文的源码下载 目标检测模型 Faster-Rcnn2.1云服务器平台 数据上传内置JupyterLab的使用本地连接使用DAMODEL实例获取实例的SSH访问信息通过SSH连接通…

【实用教程】如何利用 JxBrowser 在 Kotlin 中实现屏幕共享

JxBrowser是一个跨平台的 JVM 库&#xff0c;它允许您将基于 Chromium 的 Browser 控件集成到 Compose、Swing、JavaFX、SWT 应用程序中&#xff0c;并使用 Chromium 的数百种功能。为了在 Kotlin 中实现屏幕共享&#xff0c;我们利用了 Chromium 的 WebRTC 支持以及 JxBrowser…

无人机动力系统节能技术的未来发展趋势——CKESC电调小课堂12.1

无人机动力系统节能技术的未来发展趋势包括以下几个方面&#xff1a; 1. 能源类型多元化与高效化 新型电池技术的发展&#xff1a;锂离子电池的性能将不断提升&#xff0c;能量密度增加、充放电速度加快、循环寿命延长。同时&#xff0c;固态电池技术有望取得突破并应用于无人…

【汇编语言】数据处理的两个基本问题(二) —— 解密汇编语言:数据长度与寻址方式的综合应用

文章目录 前言1. 指令要处理的数据有多长&#xff1f;1.1 通过寄存器指明数据的尺寸1.1.1 字操作1.1.2 字节操作 1.2 用操作符X ptr指明内存单元的长度1.2.1 访问字单元1.2.2 访问字节单元1.2.3 为什么要用操作符X ptr指明 1.3 其他方法 2. 寻址方式的综合应用2.1 问题背景&…