嘉楠科技
直播中

万物死

9年用户 1389经验值
擅长:MEMS/传感技术
私信 关注
[问答]

请问在k230上怎么使用opencv的imshow显示图像呢?

已经添加了highgui的链接,成功编译并且在板子上运行
期待结果和实际结果
在hdmi屏幕上显示图像
软硬件版本信息
错误日志
hdmi屏幕黑屏无反应

回帖(1)

甘满盛

2025-6-17 18:08:54

在K230开发板上使用OpenCV的imshow函数显示图像时遇到HDMI黑屏问题,可能是由于缺少图形环境或配置错误。以下是解决方案和详细步骤:




根本原因分析



  1. 缺少图形环境:K230嵌入式系统默认无GUI(如X11/Wayland),而imshow依赖这些环境。

  2. OpenCV编译配置:OpenCV未启用适用于嵌入式平台的轻量级后端(如GTK、DirectFB等)。

  3. 硬件加速问题:K230的显示输出(HDMI)需要正确初始化的显示驱动(如DRM/KMS)。

  4. 权限/用户组:当前用户可能无权访问显示设备(如/dev/fb0/dev/dri/card0)。




解决方案


方法1:使用帧缓冲(FrameBuffer)直接输出(推荐)


避免imshow,改用Linux帧缓冲设备/dev/fb0直接显示图像:


#include 
#include
#include
#include
#include

int main() {
    // 读取图像
    cv::Mat image = cv::imread("test.jpg");
    if (image.empty()) return -1;

    // 调整图像尺寸匹配屏幕分辨率(需提前获取屏幕分辨率)
    cv::resize(image, image, cv::Size(1280, 720)); // 替换为实际分辨率

    // 打开帧缓冲设备
    int fb_fd = open("/dev/fb0", O_RDWR);
    if (fb_fd == -1) {
        perror("Error opening framebuffer");
        return -1;
    }

    // 获取屏幕信息
    struct fb_var_screeninfo vinfo;
    if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo)) {
        perror("Error reading screen info");
        close(fb_fd);
        return -1;
    }

    // 将图像写入帧缓冲
    size_t fb_size = vinfo.yres_virtual * vinfo.xres_virtual * 4; // 32位色深
    char* fb_buffer = (char*)mmap(0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
    if (!fb_buffer) {
        perror("Error mapping framebuffer");
        close(fb_fd);
        return -1;
    }

    // 转换颜色空间(BGR→RGB)并拷贝数据
    cv::Mat rgb_image;
    cv::cvtColor(image, rgb_image, cv::COLOR_BGR2RGB);
    memcpy(fb_buffer, rgb_image.data, vinfo.xres * vinfo.yres * 4);

    // 清理资源
    munmap(fb_buffer, fb_size);
    close(fb_fd);
    return 0;
}

注意



  • 将分辨率改为实际值(通过cat /sys/class/graphics/fb0/modes获取)。

  • 确保用户有权访问/dev/fb0(将用户加入video组:sudo usermod -aG video ${USER})。




方法2:启用OpenCV的GTK或Wayland后端




  1. 重新编译OpenCV


    # 安装依赖
    sudo apt-get install libgtk-3-dev wayland-protocols

    # 配置CMake(启用GTK或Wayland)
    mkdir build && cd build
    cmake
    -D WITH_GTK=ON
    -D WITH_QT=OFF
    -D WITH_WAYLAND=ON
    -D BUILD_EXAMPLES=ON
    ..

    make -j4
    sudo make install


  2. 运行时设置环境变量
    export DISPLAY=:0        # 如果使用X11
    export WAYLAND_DISPLAY=wayland-1  # 如果使用Wayland




方法3:通过KMS/DRM接口显示


使用K230的DRM驱动(需内核支持):


#include 
#include
#include

// 实现DRM初始化、Mode设置、Buffer交换等(代码较长)
// 参考:https://github.com/dvdhrm/docs/tree/master/drm-howto

建议:优先使用libdrm库(如libdrm-dev)简化开发。




调试步骤



  1. 检查显示设备状态
    cat /sys/class/graphics/fb0/name   # 确认fb0存在
    dmesg | grep -i drm                # 检查DRM驱动加载

  2. 测试帧缓冲
    sudo apt-get install fbset          # 安装帧缓冲工具
    fbset -i                           # 查看当前配置
    cat /dev/urandom > /dev/fb0        # 测试输出(应显示噪点)

  3. 验证OpenCV
    import cv2
    print(cv2.getBuildInformation())  # 检查编译时GUI支持




常见问题处理



  • 黑屏无反应

    • 检查供电和HDMI线缆。

    • 运行ls -l /dev/fb0确认设备权限(需crw-rw----)。


  • 编译错误
    确保安装了依赖库(libgtk-3-devlibdrm-dev)。

  • 图像不显示
    检查图像路径、分辨率匹配,以及BGR/RGB颜色空间转换。




通过以上方法,应能在K230上实现图像显示。推荐优先使用帧缓冲方案,避免依赖完整的GUI环境。如有疑问,可查阅K230的官方文档:K230 SDK文档

举报

更多回帖

发帖
×
20
完善资料,
赚取积分