主要内容

生成使用半精度数据类型的Sobel边缘检测代码

这个例子展示了如何从Matlab®函数中生成一个独立的C++库,该函数通过使用半精度浮点数来执行图像的Sobel边缘检测。Sobel边缘算法接受表示为矩阵的图像,并返回强调对应于其边缘的高空间频率区域的图像。此示例还显示了如何使用MEX函数测试genenrated代码。

Sobel边缘检测算法

在Sobel边缘检测算法中,对灰度图像执行二维空间梯度操作。该操作强调与图像中边缘相对应的高空间频率区域。

类型sobelEdgeDetectionAlg
函数edgeImg = sobelEdgeDetectionAlg(img,thresh) %#codegen %% Copyright 2018 The MathWorks, Inc. kern = half([1 2 1;0 0 0;1 2 1]);%寻找水平和垂直梯度。h = conv2 (img(:,: 2),克恩,“相同”);v = conv2 (img(:,: 2),克恩”、“相同”);求梯度的大小。e =√h。* h + v * v); % Threshold the edges edgeImg = uint8((e > thresh) * 240); end

Sobel边缘算法计算水平梯度h垂直梯度呢v用两个正交滤波核对输入图像进行处理马斯克斯蒙面的.滤波操作后,算法计算梯度大小,并应用阈值来找到图像中与边缘对应的区域。

读取图像和打包数据到RGBA打包列主要顺序

使用伊姆雷德函数读取图像。伊姆雷德表示图像的RGB通道,每个像素对应一个整数。整数的取值范围是0 ~ 255。简单地将输入转换为一半类型可能会在卷积期间导致溢出。为了避免这个问题,将图像缩放到0到1之间。

我= imread (“peppers.png”);figure();image(im);imPacked=half(im)/255;thresh=half(100)/255;

生成墨西哥人

为C++生成一个C++ MEX函数sobelEdgeDetectionAlg函数的codegen命令。

cfg=coder.config(墨西哥人的);cfg。TargetLang =“c++”;cfg。GenerateReport = true;codegen配置cfgarg游戏{imPacked,打}sobelEdgeDetectionAlg
代码生成成功:要查看报告,打开('codegen/mex/sobelEdgeDetectionAlg/html/report.mldatx')

运行生成的MEX并显示检测到的边缘

在生成c++代码之前,必须首先在MATLAB环境中测试MEX函数,以确保它在功能上与原始MATLAB代码等效,并且不会发生运行时错误。默认情况下,codegen生成一个名为sobelEdgeDetectionAlg_mex在当前文件夹中。这允许您测试MATLAB代码和MEX函数,并比较结果。

out_disp = sobelEdgeDetectionAlg_mex (imPacked,打);图();显示亮度图像(out_disp);

生成静态C++库

使用codegen命令生成一个c++静态库。默认情况下,生成的库位于文件夹中codegen/lib/sobelEdgeDetectionAlg/

cfg=coder.config(“自由”);cfg。TargetLang =“c++”;cfg。GenerateReport = true;codegen配置cfgarg游戏{imPacked,打}sobelEdgeDetectionAlg
代码生成成功:要查看报告,打开('codegen/lib/sobelEdgeDetectionAlg/html/report.mldatx')

检查生成的函数

类型codegen/lib/sobelEdgeDetectionAlg/sobelEdgeDetectionAlg.cpp
////文件:sobelEdgeDetectionAlg.cpp///MATLAB编码器版本:5.3//C/C++源代码生成日期:2021年9月1日08:15:38///包括文件#包括“sobelEdgeDetectionAlg.h”#包括“conv2MovingWindowSameCM.h”#包括“rtwhalf.h”#包括“sobelEdgeDetectionAlg#u data.h”#包括“sobelEdgeDetectionAlg#u initialize.h”#包含//函数定义////sobelEdgeDetection示例用于边缘检测的MATLAB函数。//版权所有2018 The MathWorks,Inc.///参数:const real16_T img[589824]//real16_T thresh//unsigned char edgeImg[196608]//返回类型:void//void sobelEdgeDetectionAlg(const real16_T img[589824],real16_T thresh,unsigned char edgeImg[196608]){静态const real16_T hv[9]{real16_T(1.0F),real16_T(0.0F),real16_T(-1.0F),real16_T(2.0层F)(2.0层F)(2.0层F)(2.0层F)(2.0层F)、real16层T(1.0层F)、real16层T(0.0层F)、real16层T(0.0层F)、real16层T(0.0层F)、real16层T(2.0层F)、real16层T(1.0层F)、real16层T(1.0层F)、real16层T(0.0层T(0.0 0层F)、real16层T(0.0.0 0 0 0层T)、0.0.0层T(0.0.0层T)、0.0层T(0.0.0.0 0 0 0 0 0 0 0 0 0 0层F、0.0.0层T、0.0.0层T(0.0.0 0.0 0 0 0 0 0 0 0 0层)、0层、0层T(0.0.0.0.0.0.0、0 0];静态真实16_T v[196608];如果(!isInitialized_sobelEdgeDetectionAlg){sobelEdgeDetectionAlg_Initialized()}//查找水平和垂直梯度。编码器::conv2MovingWindowSameCM(*(real16_T(*)[196608])&img[196608],hv,h);编码器::conv2MovingWindowSameCM(*(real16_T(*)[196608])&img[196608],hv1,v);//查找梯度的大小//确定边缘的阈值(int k{0};k<196608;k++){real16_T b_h;real16_T h1;b_h=h[k];h1=v[k];b_h=static_cast(std::sqrt(static_cast(b_h*b_h+h1*h1));h[k]=b_h;edgeImg[k]=static_cast((b_h>thresh)*u);/u)}/////

另请参阅

||

相关话题