本期将带大家带来一期可以称作番外篇的一期:暂且称为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,例如:
cv::mat h = cv::findhomography(points1, points2, cv_ransac, 5); 或是:using namespace cv;mat h = findhomography(points1, points2, cv_ransac, 5 ); 同时,由于当前或是之后的opencv源码中导出的外部符号,可能会和stl或是其他库中的名字冲突。这就建议用户在使用时,要显示指定已避免冲突,例如:
mat a(100, 100, cv_32f);randu(a, scalar::all(1), scalar::rand()));cv::log(a, a);a /= std::log(2.); 接下来要讲的是一个opencv中的重要结构mat。
如果你想要使用opencv的话,mat是你无论如何躲不过的一步。通俗点讲,这个结构体代表了一种n维数组,并且能够抽象表达成矩阵/图像/光流图等。
其公共属性如下:
attribute
description
matallocator* allocator
custom allocator
int cols
the image’s width
int rows
the image’s height, the cols & rows will be (-1, -1) when the matrix has more than 2 dimensions
uchar* data
pointer to the data
uchar* dataend
-
uchar* datalimit
-
uchar* datastart
-
int dims
the matrix dimensionality, >=2
int flags
-
int* refcount
pointer to the reference counter
msize size
-
msize step
-
作为一个名副其实的c++类,opencv为其编写了多种构造函数,这也使得有多种方式能够创建一个cv::mat对象,用的比较多的几种方式如下:
1.使用cv::create(nrows, ncols, type) 或是 cv::mat(nrows, ncols, type[, fill,_vale])如有雷同,那必然不是巧合。
// make 7x7 complex matrix filled with 1+3j.cv::mat m(7,7,cv_32fc2,scalar(1,3));// and now turn m to 100x60 15-channel 8-bit matrix.// the old content will be deallocatedm.create(100,60,cv_8uc(15)); 2.使用拷贝构造函数,时间复杂度为o(1),因为这种方式将只拷贝header并增加引用计数,数据部分将公用,也称作浅拷贝。当然也可以使用深拷贝,cv::clone()可以做到这一点。
3.仅构造头部,并使用用户预分配数据:void init_mat_with_ptr(const unsigned char* pixels, int width, int height, int step){ cv::mat img(height, width, cv_8uc3, pixels, step); cv::gaussianblur(img, img, cv::size(7,7), 1.5, 1.5);} 4.使用matlab格式的矩阵初始化法,cv::zeros(), cv::ones(), cv::eye()
5.对象与数据空间的释放:cv::release()
了解了opencv的基础知识,下面是基于mcuxpresso的代码实测部分。这里我们基于sdk中的“hello world”工程搭建我们的第一个opencv代码。小编先卖个关子,详细的工程配置方法将在下期为大家揭秘。
首先,要选取测试图,小编随便在手机里找了一张图片并裁成500*500的jpg图像,之后会对其进行解码随后将其放缩成(320, 240)。
为了方便我们在没有文件系统的mcu平台使用测试图像,需要借助一条汇编指令.incbin, 并且声明两个全局符号告诉代码数据位置:
.global img_start .global img_endimg_start: .incbin data/picture.jpgimg_end:
接下来是main函数:
// decode the imagestd::vector data(img_start, img_start + img_len);cv::mat img_encode(data);cv::mat img = cv::imdecode(img_encode, cv::imread_unchanged);// resize the decoded imagecv::mat resizeimg;cv::resize(img, resizeimg, cv::size(320, 240), cv::inter_linear); 编译下载后,让我们看看转出的数据是不是正确,我们就需要将数据传输到pc上进行验证:
1. 在mcuxpresso ide中添加一个memory窗口并且键入resizeimage.data:
2. 点击export,输入起止地址,ide会自动计算长度。选择保存类型为raw binary, 并选择本地保存位置
3. 点击ok下载数据
4. 为了验证数据的准确性,我们直接编写一个简单的上位机opencv的基于python的预览程序,代码中的文件名对应第2步保存的文件:
import numpy as npimport cv2 as cv img_raw_data = np.fromfile(“your_path/your_file_name.bin”, dtype=”uint8”)img = np.reshape(img_raw_data, (240, 320, 3)) # the new shapecv.imshow(“img”, img)cv.waitkey(0) 注意:这里假设电脑上已经安装了python,并且安装了numpy以及opencv代码库
5. 程序执行之后,让我们看看最终结果:
至此,我们就用了一个简单的代码验证了我们所编译的opencv库的正确性。下期小编将为大家揭秘,如何从0开始构建一个完整的opencv测试例程。
IP应用研讨会:Imagination大学计划助力学术材料共享利用
科大讯飞AI助残行动一直在路上
5G的商业化进入正循环,驱动核心网从5G迈向5.5G
韩国NAND闪存芯片出口额恢复增长
尚德拒绝政府救助:施正荣犯众怒或被扫地出门
OpenCV的基础使用方法及运行成果
华为P10最新消息:华为P10退货有戏?余承东发微博反思华为P10闪存门事件
AI时代,EDA下一步的进化方向是什么?
疫情防控再升级,无感测温保障您的出行安全
英特尔新汉联手,带领制造业踏上工业4.0
ADI SAR ADC产品组合提供模拟输入架构
三大显示器发展现状和未来趋势
三相电机不能正常停止运转的问题
常用的发射管数据
继电器型号命名和分类方法,继电器常用触点组合形式
TDK两种磁传感器技术的领域竞争优势
Gartner:联发科动能表现 优于高通
浅谈平板数字胃肠机的优势
浅谈雷曼像素引擎显示技术
玻色量子与千方科技正式达成战略合作