查看: 1235|回复: 5

这个秋天,OpenCV和MCU更配哟(实战篇)

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
    发表于 2022-11-17 09:39:53 | 显示全部楼层 |阅读模式
    这个秋天,OpenCV和MCU更配哟(实战篇)


    本文是一个小系列的第三篇,MCU部署OpenCV的“实战篇”,已经发表了“先跑篇”和"配置篇"稍后会陆续还有“进阶篇”、“优化篇”,带您牵手OpenCV,进入OpenCV的广阔世界。

    通过前两期的介绍,相信大家现在手头已经紧紧握着那5个可爱的静态库文件了。

    当然,没有那金刚钻怎么能揽瓷器活。是时候做点什么,让这些可爱的静态库发挥作用了。

    本期小编将带大家带来一期可以称作番外篇的一期:暂且称为OpenCV实战篇,将介绍OpenCV的一些基础使用方法,以及在MCU上实际运行起来的效果。

    首先是OpenCV的简单介绍,前面的文章已经介绍过,OpenCV具有模块化的结构,这意味着其中包含了多种共享/静态库,概括如下:
    ·Core functionality:定义了所要用到的基础数据结构体
    ·Image Processing:包含了多种线性/非线性的图像滤波器,几何图像变换等
    ·Video:视频处理模块,包括运动估计,背景减除等
    ·Calib3d:单目/双目相机支持,3D重建等
    ·Features2D:特征检测
    ·Objdetect:目标检测等,例如人脸、眼睛等
    ·Highgui:简单的UI功能
    ·Video I/O:视频编解码接口
    ·Gpu:gpu加速算法
    所有的OpenCV类/函数都被归在cv命名空间下。因此,应用层想要访问任何代码都需要使用cv::限定符或是直接使用using namespace cv,例如:
    1. cv::Mat H = cv::findHomography(points1, points2, CV_RANSAC, 5);
    复制代码
    或是:
    1. using namespace cv;
    2. Mat H = findHomography(points1, points2, CV_RANSAC, 5 );
    复制代码
    同时,由于当前或是之后的OpenCV源码中导出的外部符号,可能会和STL或是其他库中的名字冲突。这就建议用户在使用时,要显示指定已避免冲突,例如:
    1. Mat a(100, 100, CV_32F);
    2. randu(a, Scalar::all(1), Scalar::all(std::rand()));
    3. cv::log(a, a);
    4. a /= std::log(2.);
    复制代码
    接下来要讲的是一个OpenCV中的重要结构Mat。

    如果你想要使用OpenCV的话,Mat是你无论如何躲不过的一步。通俗点讲,这个结构体代表了一种n维数组,并且能够抽象表达成矩阵/图像/光流图等。

    其公共属性如下:
    12.png
    作为一个名副其实的C++类,OpenCV为其编写了多种构造函数,这也使得有多种方式能够创建一个cv::Mat对象,用的比较多的几种方式如下:
    1. 使用cv::Mat::Create(nrows, ncols, type) 或是 cv::Mat::Mat(nrows, ncols, type[, fill,_vale])如有雷同,那必然不是巧合。
    1. // make 7x7 complex matrix filled with 1+3j.
    2. cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
    3. // and now turn M to 100x60 15-channel 8-bit matrix.
    4. // The old content will be deallocated
    5. M.create(100,60,CV_8UC(15));
    复制代码
    2. 使用拷贝构造函数,时间复杂度为O(1),因为这种方式将只拷贝header并增加引用计数,数据部分将公用,也称作浅拷贝。当然也可以使用深拷贝,cv::Mat::clone()可以做到这一点。

    3. 仅构造头部,并使用用户预分配数据:
    1. void init_mat_with_ptr(const unsigned char* pixels,
    2.                          int width, int height, int step)
    3. {
    4.     cv::Mat img(height, width, CV_8UC3, pixels, step);
    5.     cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5);
    6. }
    复制代码
    4. 使用MATLAB格式的矩阵初始化法,cv::Mat::zeros(), cv::Mat:nes(), cv::Mat::eye()

    5. 对象与数据空间的释放:cv::Mat::release()

    了解了OpenCV的基础知识,下面是基于MCUXPresso的代码实测部分。这里我们基于SDK中的“Hello World”工程搭建我们的第一个OpenCV代码。小编先卖个关子,详细的工程配置方法将在下期为大家揭秘。


    首先,要选取测试图,小编随便在手机里找了一张图片并裁成500*500的jpg图像,之后会对其进行解码随后将其放缩成(320, 240)。
    13.png
    为了方便我们在没有文件系统的MCU平台使用测试图像,需要借助一条汇编指令.incbin, 并且声明两个全局符号告诉代码数据位置:
    1. .global img_start
    2.   .global img_end
    3. img_start:
    4. .incbin "data/picture.jpg"
    5. img_end:
    复制代码
    接下来是main函数:
    1. // decode the image
    2. std::vector<char> data(img_start, img_start + IMG_LEN);
    3. cv::Mat img_encode(data);
    4. cv::Mat img = cv::imdecode(img_encode, cv::IMREAD_UNCHANGED);
    5. // resize the decoded imagecv::Mat resizeImg;
    6. cv::resize(img, resizeImg, cv::Size(320, 240), cv::INTER_LINEAR);
    复制代码
    编译下载后,让我们看看转出的数据是不是正确,我们就需要将数据传输到PC上进行验证:


    1.  在MCUXpresso IDE中添加一个memory窗口并且键入resizeImage.data:
    15.png
    2.    点击Export,输入起止地址,IDE会自动计算长度。选择保存类型为RAW Binary, 并选择本地保存位置

    3.  点击OK下载数据

    4. 为了验证数据的准确性,我们直接编写一个简单的上位机OpenCV的基于Python的预览程序,代码中的文件名对应第2步保存的文件:
    1. import numpy as np
    2. import cv2 as cv
    3. img_raw_data = np.fromfile(“your_path/your_file_name.bin”, dtype=”uint8”)
    4. img = np.reshape(img_raw_data, (240, 320, 3)) # the new shape
    5. cv.imshow(“img”, img)
    6. cv.waitKey(0)
    复制代码
    注意:这里假设电脑上已经安装了Python,并且安装了numpy以及opencv代码库

    5.    程序执行之后,让我们看看最终结果:
    14.png

    至此,我们就用了一个简单的代码验证了我们所编译的OpenCV库的正确性。下期小编将为大家揭秘,如何从0开始构建一个完整的OpenCV测试例程。





    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 11:26
  • 签到天数: 1274 天

    [LV.10]以坛为家III

    21

    主题

    1万

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    13214
    最后登录
    2024-4-19
    发表于 2022-11-17 10:23:14 | 显示全部楼层
    小编, 你就不能选个带屏幕的板子测试么?
    跟着日天混 ,三天饱九顿!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
     楼主| 发表于 2022-11-17 13:59:14 | 显示全部楼层
    sumoon_yao 发表于 2022-11-17 10:23
    小编, 你就不能选个带屏幕的板子测试么?

    小编没有带屏的,有的话高低整一个
    签到签到
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    半小时前
  • 签到天数: 1934 天

    [LV.Master]伴坛终老

    61

    主题

    1万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    17226
    最后登录
    2024-4-20
    发表于 2022-11-17 14:40:38 | 显示全部楼层
    来实战吧。
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-3-5 08:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    91

    主题

    2926

    帖子

    2

    金牌会员

    Rank: 6Rank: 6

    积分
    7799
    最后登录
    2024-4-18
    发表于 2022-11-18 14:15:27 | 显示全部楼层
    先收藏
    加油哦
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 08:30
  • 签到天数: 482 天

    [LV.9]以坛为家II

    8

    主题

    1350

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2896
    最后登录
    2024-4-20
    发表于 2022-11-21 10:00:41 | 显示全部楼层
    厉害,都是大神
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-20 12:21 , Processed in 0.135883 second(s), 27 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表