基于imx6ull平台opencv的图像采集和显示屏LCD显示功能

2024-08-25 18:36

本文主要是介绍基于imx6ull平台opencv的图像采集和显示屏LCD显示功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、概述
  • 二、环境要求
    • 2.1 硬件环境
    • 2.2 软件环境
  • 三、开发流程
    • 3.1 编写测试
    • 3.2 验证功能

一、概述

本文档是针对imx6ull平台opencv的图像采集和显示屏LCD显示功能,opencv通过摄像头采集视频图像,将采集的视频图像送给显示屏LCD进行显示。

  • 测试结果如下图所示:

在这里插入图片描述

二、环境要求

2.1 硬件环境

  • 硬件:正点原子-I.MX6U ALPHA开发板
  • 摄像头:正点原子-OV5640单目摄像头
  • 显示屏:正点原子-4.3寸-800x480显示屏
  • 虚拟机:VMware

2.2 软件环境

  • Ubuntu系统要求:20.04
  • opencv版本: 4.7.0
  • 交叉工具链版本:交叉工具链版本:gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf
  • 开发语言: C++

注意: 其中,需要有OV5640单目摄像头和4.3寸-800x480显示屏的驱动。

三、开发流程

关于imx6ull平台下opencv的移植及交叉编译器环境请参看:基于imx6ull开发板 移植opencv4.7.0

3.1 编写测试

选择一个目录,我这里选择的是opencv_lcd_imx6ull,创建一个opencv_lcd.cpp文件,内容如下:

#include <opencv2/opencv.hpp>
#include <opencv2/videoio/videoio.hpp>
#include <opencv2/core/utils/logger.hpp>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>/**** 静态全局变量 ****/
static int width;                       //LCD X分辨率
static int height;                      //LCD Y分辨率
static unsigned short *screen_base = NULL;        //映射后的显存基地址
static unsigned long line_length;       //LCD一行的长度(字节为单位)using namespace std;
using namespace cv;int main() {struct fb_fix_screeninfo fb_fix;struct fb_var_screeninfo fb_var;unsigned int screen_size;// 打开LCD设备int fb = open("/dev/fb0", O_RDWR);if (fb < 0) {perror("open fb0 failed");return -1;}/* 获取参数信息 */// 获取LCD屏幕信息if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) < 0) {perror("ioctl FBIOGET_VSCREENINFO failed");return -1;}// 获取LCD帧缓冲区信息if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) < 0) {perror("ioctl FBIOGET_FSCREENINFO failed");return -1;}// 初始化OpenCVcv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_SILENT);//括号内数字为1是调用usb摄像头,为0则是调用电脑自带摄像头cv::VideoCapture capture(1);unsigned short *screen_ptr = screen_base;// 设置摄像头的分辨率cv::Size resolution(800, 480);capture.set(cv::CAP_PROP_FRAME_WIDTH, resolution.width);capture.set(cv::CAP_PROP_FRAME_HEIGHT, resolution.height);// 加载预先训练好的人脸识别模型cv::CascadeClassifier faceCascade;faceCascade.load("haarcascade_frontalface_default.xml");// 将图像数据写入LCD屏幕screen_size = fb_fix.line_length * fb_var.yres;line_length = fb_fix.line_length;width = fb_var.xres;height = fb_var.yres;screen_base = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);if (MAP_FAILED == (void *)screen_base) {perror("mmap failed");return -1;}memset(screen_base, 0xFF, screen_size);unsigned short *fb_line_buf = NULL; //行缓冲区:用于存储写入到LCD显存的一行数据cv::Mat image;  //定义一个Mat变量,用于存储每一帧的图像capture >> image;  //读取当前帧printf("%d %d %d\r\n", image.cols, image.rows, image.channels());fb_line_buf = malloc(image.cols * 2);//【2】循环显示每一帧while(1)  {  // cv::Mat image;  //定义一个Mat变量,用于存储每一帧的图像capture >> image;  //读取当前帧// printf("%d %d %d\r\n", image.cols, image.rows, image.channels());screen_ptr = screen_base;if (image.empty()) continue; // 如果没有读取到帧,退出循环for (size_t y = 0; y < image.rows; y++){char* row_ptr = image.ptr<char>(y);for (size_t x = 0; x < image.cols; ++x) {//这是获得像素数据数组的头指针,注意像素数据可能会有多个通道所以才需要用数组存储char* data_ptr = &row_ptr[x * image.channels()];// //对当前像素逐个通道输出颜色值// for (int i = 0; i < image.channels(); ++i) {//     cout << int(data_ptr[i])<<endl;// }// BGR888转为RGB565fb_line_buf[x] = ((data_ptr[2] & 0xF8) << 8) |((data_ptr[1] & 0xFC) << 3) |((data_ptr[0] & 0xF8) >> 3);}memcpy(screen_ptr, fb_line_buf, image.cols * 2);//将一行数据刷入显存screen_ptr += width;   //定位到显存下一行}}  // 解除内存映射munmap(screen_base, screen_size);// 关闭LCD设备close(fb);return 0;
}

opencv_lcd_imx6ull目录下,创建一个build_arm.sh文件,内容如下:

/tools/ToolsChain/nxp/imx6ull/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ opencv_lcd.cpp -o opencv_lcd \
-I /data/Workspace_Linux/software_lib/opencv-x.x.x/output/opencv-4.7.0/imx6ull/include/opencv4 \
-L /data/Workspace_Linux/software_lib/opencv-x.x.x/output/opencv-4.7.0/imx6ull/lib \
-lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_videoio -lopencv_imgcodecs -lopencv_face -lopencv_dnn  -lopencv_features2d -lopencv_flann -lopencv_calib3d -lopencv_objdetect \
-fpermissive

注意:

  • 交叉工具链:/tools/ToolsChain/nxp/imx6ull/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++;
  • opencv头文件路径:/data/Workspace_Linux/software_lib/opencv-x.x.x/output/opencv-4.7.0/imx6ull/include/opencv4,开发者根据自己的路径进行配置;
  • opencv库路径:/data/Workspace_Linux/software_lib/opencv-x.x.x/output/opencv-4.7.0/imx6ull/lib,开发者根据自己的路径进行配置。

3.2 验证功能

  • 源码编译并上传
    opencv_lcd_imx6ull目录下,将build_arm.sh文件更改成可执行文件,并运行如下图所示:
./build_arm.sh

在这里插入图片描述
进入imx6ull开发板的/mnt/test_opencv目录下(若没有改目录则创建该目录),创建opencv_lcd目录,如下图所示:
在这里插入图片描述

opencv_lcd文件通过tfp上传到imx6ull开发板的/mnt/test_opencv/opencv_lcd目录下,如下图所示:
在这里插入图片描述
在这里插入图片描述

  • opencv库上传到imx6ull开发板
    进入/data/Workspace_Linux/software_lib/opencv-x.x.x/output/opencv-4.7.0/imx6ull目录下,将opencv库相关的内容进行打包,如下图所示:
    在这里插入图片描述
    进入imx6ull开发板的/mnt/test_opencv目录下(若没有改目录则创建该目录),创建opencv目录,如下图所示:
    在这里插入图片描述
    opencv.tar文件通过tfp上传到imx6ull开发板的/mnt/test_opencv/opencv目录下,如下图所示:
    在这里插入图片描述
    进入imx6ull开发板的/mnt/test_opencv/opencv目录下,执行以下命令,将opencv.tar文件进行解压,如下图所示:
tar -xf opencv.tar

在这里插入图片描述

  • opencv库配置环境搭建

执行以下命令进行opencv库环境配置,如下图所示:

export LD_LIBRARY_PATH=/mnt/test_opencv/opencv/lib:$LD_LIBRARY_PATH

在这里插入图片描述

  • 运行应用程序

进入imx6ull开发板的/mnt/test_opencv/opencv_lcd目录下,更改opencv_lcd为可执行文件,并运行,运行结果如下:
在这里插入图片描述
在这里插入图片描述
最后,基于imx6ull平台opencv的图像采集和显示屏LCD显示功能验证完成了。

这篇关于基于imx6ull平台opencv的图像采集和显示屏LCD显示功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1106339

相关文章

SpringBoot整合DeepSeek实现AI对话功能

《SpringBoot整合DeepSeek实现AI对话功能》本文介绍了如何在SpringBoot项目中整合DeepSeekAPI和本地私有化部署DeepSeekR1模型,通过SpringAI框架简化了... 目录Spring AI版本依赖整合DeepSeek API key整合本地化部署的DeepSeek

Python实现多路视频多窗口播放功能

《Python实现多路视频多窗口播放功能》这篇文章主要为大家详细介绍了Python实现多路视频多窗口播放功能的相关知识,文中的示例代码讲解详细,有需要的小伙伴可以跟随小编一起学习一下... 目录一、python实现多路视频播放功能二、代码实现三、打包代码实现总结一、python实现多路视频播放功能服务端开

css实现图片旋转功能

《css实现图片旋转功能》:本文主要介绍了四种CSS变换效果:图片旋转90度、水平翻转、垂直翻转,并附带了相应的代码示例,详细内容请阅读本文,希望能对你有所帮助... 一 css实现图片旋转90度.icon{ -moz-transform:rotate(-90deg); -webkit-transfo

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

Java CompletableFuture如何实现超时功能

《JavaCompletableFuture如何实现超时功能》:本文主要介绍实现超时功能的基本思路以及CompletableFuture(之后简称CF)是如何通过代码实现超时功能的,需要的... 目录基本思路CompletableFuture 的实现1. 基本实现流程2. 静态条件分析3. 内存泄露 bug

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

如何设置vim永久显示行号

《如何设置vim永久显示行号》在Linux环境下,vim默认不显示行号,这在程序编译出错时定位错误语句非常不便,通过修改vim配置文件vimrc,可以在每次打开vim时永久显示行号... 目录设置vim永久显示行号1.临时显示行号2.永www.chinasem.cn久显示行号总结设置vim永久显示行号在li

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英