《机器人实践开发③:Foxglove可视化机器人的眼睛-视频》

导语:

视频是机器人感知系统最核心的模块之一。本篇将讲解 Foxglove 如何处理摄像头视频流,包括编码格式、消息封装、bridge 转发、前端渲染机制,并对常见问题(如卡顿、颜色不对)给出解决方案。


本篇依赖前两篇的内容,请读者前往阅读 👀

《机器人实践开发①:Foxglove 开发环境完整搭建指南(含常见坑位)》
《机器人实践开发②:Foxglove 嵌入式移植 + CMake 集成》

第一种方式比较简单,通过 ros2 的方式推送图片流

注意:

这种方式比较耗流量,在网络不好的情况下会导致异常显示

需要结合 opencv2 处理图片

需要在机器人端运行桥接指令 ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765

cpp 复制代码
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>

class CameraPublisher : public rclcpp::Node {
public:
    CameraPublisher()
            : Node("camera_publisher")
    {
        publisher_ = this->create_publisher<sensor_msgs::msg::Image>("/camera/image_raw", 10);

        cap_.open(0);  // 默认摄像头
        if (!cap_.isOpened()) {
            RCLCPP_ERROR(this->get_logger(), "Cannot open camera");
            rclcpp::shutdown();
        }

        timer_ = this->create_wall_timer(
                std::chrono::milliseconds(33),  // ~30 FPS
                std::bind(&CameraPublisher::publish_frame, this)
        );
    }

private:
    void publish_frame() {
        cv::Mat frame;
        cap_ >> frame;
        if (frame.empty()) {
            RCLCPP_WARN(this->get_logger(), "Empty frame captured");
            return;
        }

        auto msg = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", frame).toImageMsg();
        publisher_->publish(*msg);
        RCLCPP_INFO(this->get_logger(), "Published a frame");
    }

    rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
    cv::VideoCapture cap_;
};

int main(int argc, char * argv[])
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<CameraPublisher>();
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;

编写 CmakeList.txt文件

cpp 复制代码
cmake_minimum_required(VERSION 3.8)
project(camera_publisher)

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(example_interfaces REQUIRED)
find_package(visualization_msgs REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(OpenCV REQUIRED)



add_executable(camera_publisher camera_publisher.cpp)
ament_target_dependencies(camera_publisher rclcpp std_msgs visualization_msgs cv_bridge OpenCV)

install(TARGETS
        camera_publisher
        DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/${PROJECT_NAME})
ament_package()

第二种方式,使用 foxglove sdk 的方式集成,使用 H264/H265视频流的方式,推荐!!

有效的节省带宽,运动特性更好

视频指令可控,帧率/码流/分辨率

功耗低,运行比第一种方式节省 cpu 资源

定义视频类

cpp 复制代码
std::unique_ptr<foxglove::schemas::CompressedVideoChannel>                          visualization_compressed_main_video_channel;

封装视频发送接口

核心接口是visualization_compressed_main_video_channel>log(compressed_video)

注意填充数据 一定要将timestamp 填充对,否则没有看不见视频

cpp 复制代码
int FoxgloveVisualizationService::startVideoChannelService(int index,uint8_t *video_buffer, uint32_t audio_size) {
    auto time_since_epoch = std::chrono::system_clock::now().time_since_epoch();
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch);
    auto nanoseconds =
          std::chrono::duration_cast<std::chrono::nanoseconds>(time_since_epoch - seconds);
    foxglove::schemas::Timestamp timestamp;
    timestamp.sec = static_cast<uint32_t>(seconds.count());
    timestamp.nsec = static_cast<uint32_t>(nanoseconds.count());


    std::vector<std::byte> data(audio_size * sizeof(uint8_t));
    std::memcpy(data.data(), video_buffer, audio_size * sizeof(uint8_t));

    foxglove::schemas::CompressedVideo compressed_video;
    compressed_video.format = "h264";
    compressed_video.timestamp = timestamp;
    compressed_video.frame_id = visualization_frame_id;
    compressed_video.data = data;
    index==0?visualization_compressed_main_video_channel->log(compressed_video):visualization_sub_compressed_video_channel->log(compressed_video);
}

使用工具可视化视频

相关推荐
水文摸鱼怪20 小时前
HHU校园网自动连接监控系统(钉钉机器人版)操作说明书
机器人·钉钉
xiaoduo AI21 小时前
客服机器人支持表情包互动吗?智能体图文自动回复,更贴合年轻客户偏好?
人工智能·机器人
VBsemi-专注于MOSFET研发定制21 小时前
服务机器人调度平台功率MOSFET选型方案——高效、可靠与紧凑型驱动系统设计指南
机器人
一RTOS一1 天前
东土科技加入具身智能数据要素产业联盟全面适配人形机器人训练等关键应用场景
科技·机器人·鸿道操作系统·鸿道实时操作系统·国产嵌入式操作系统选型
SteveSenna1 天前
强化学习4.1:基于价值——Q-learning
人工智能·学习·算法·机器人
Daydream.V1 天前
基于Opencv和Dlib的人脸换脸实现
人工智能·opencv·计算机视觉·仿射变换·换脸·视频换脸·图片换脸
电子科技圈1 天前
赋能高端音频功能促进多样化设备创新——XMOS USB Audio平台实现四大功能升级
人工智能·mcu·音视频·智能家居·边缘计算·语音识别·智能硬件
EasyDSS1 天前
视频高清直播点播/云点播/云直播EasyDSS:一站式视频云平台全链路整合,重塑企业视频应用新生态
音视频
jwybobo20071 天前
AV1 码流 RTP 封装
音视频·av1
愚公搬代码1 天前
【愚公系列】《剪映+DeepSeek+即梦:短视频制作》055-即梦+DeepSeek生成AI视频(文生视频案例)
人工智能·音视频