在应用程序中使用一个示例C Main
这个例子展示了如何从MATLAB中构建一个C可执行文件®该代码实现了一个简单的Sobel滤波器来对图像进行边缘检测。可执行文件从磁盘读取图像,应用Sobel滤波算法,然后保存修改后的图像。
该示例演示了如何生成和修改一个示例主函数,您可以在构建可执行文件时使用该函数。
先决条件
要完成此示例,请安装以下产品:s manbetx 845
MATLAB
MATLAB编码器™
C编译器(对于大多数平台,MATLAB提供了一个默认的C编译器)。有关支持的编译器列表,请参见万博1manbetx万博1manbetx支持编译器.
您可以使用
墨西哥人设置
更改默认编译器。看到改变默认的编译器.
创建一个文件夹并复制相关文件
您在这个例子中使用的文件是:
文件名称 | 文件类型 | 描述 |
---|---|---|
sobel.m |
函数代码 | MATLAB实现的一个Sobel滤波算法。sobel.m 将图像(表示为双矩阵)和阈值作为输入。该算法检测图像中的边缘(基于阈值)。sobel.m 返回显示边缘的修改图像。 |
hello.jpg |
图像文件 | Sobel过滤器修改的图像。 |
将示例文件复制到本地工作文件夹。
创建本地工作文件夹。例如,
c: \编码器\ edge_detection
.导航到工作文件夹。
复制文件
sobel.m
而且hello.jpg
从示例文件夹索贝尔
到您的工作文件夹。拷贝文件(fullfile (docroot,“工具箱”,“编码器”,“例子”,“索贝尔”))
在图像上运行Sobel Filter
将原始图像读入MATLAB矩阵并显示出来。
我= imread (“hello.jpg”);
显示图像作为与索贝尔滤波结果比较的基础。
图像(im);
Sobel滤波算法作用于灰度图像。将彩色图像转换为具有标准化值的等效灰度图像(黑色为0.0,白色为1.0)。
灰色=(0.2989 *双(im(:,: 1)) + 0.5870 *双(im(:,: 2)) + 0.1140 *双(im (:,:, 3))) / 255;
为了运行Sobel滤波器的MATLAB函数,传递灰度图像矩阵
灰色的
和函数的阈值索贝尔
.本例使用0.7作为阈值。edgeIm = sobel(灰色,0.7);
要显示修改后的图像,请重新格式化矩阵
edgeIm
与函数repmat
这样你就可以把它传递给图像
命令。im3 = repmat(edgeIm, [1 1 3]);图像(im3);
生成并测试MEX函数
要测试生成的代码在函数上等价于原始的MATLAB代码,并且不会发生运行时错误,请生成MEX函数。
codegen报告索贝尔
codegen
生成一个MEX函数sobel_mex
在当前工作文件夹中。为了运行Sobel滤波器的MEX函数,传递灰度图像矩阵
灰色的
和函数的阈值sobel_mex
.本例使用0.7作为阈值。edgeImMex = sobel_mex(灰色,0.7);
要显示修改后的图像,请重新格式化矩阵
edgeImMex
与函数repmat
这样你就可以把它传递给图像
命令。im3Mex = repmat(edgeImMex, [1 1 3]);图像(im3Mex);
此图像与使用MATLAB函数创建的图像相同。
为sobel.m生成一个示例Main函数
虽然可以为应用程序编写自定义的main函数,但示例main函数提供了一个模板来帮助您合并生成的代码。
为Sobel过滤器生成一个主函数示例:
为C静态库创建一个配置对象。
cfg = coder.config (“自由”);
对于C/ c++源代码、静态库、动态库和可执行程序的配置对象,设置
GenerateExampleMain
控制示例主函数的生成。设置为“GenerateCodeOnly”
默认情况下,它生成示例main函数,但不编译它。对于本例,不要更改GenerateExampleMain
设置。使用配置对象生成一个C静态库。
codegen报告配置cfg索贝尔
为静态库生成的文件位于该文件夹中codegen / lib /索贝尔
.示例主文件位于子文件夹中codegen / lib /索贝尔/例子
.
复制示例主文件
不修改文件c
而且main.h
在例子
子文件夹。如果你这样做,当你重新生成代码时,MATLAB编码器不重新生成示例主文件。它警告您,它检测到对生成文件的更改。
复制文件c
而且main.h
从文件夹中codegen / lib /索贝尔/例子
到另一个位置。对于本例,将文件复制到当前工作文件夹。修改新位置中的文件。
修改生成的示例主函数
示例main函数声明并初始化数据(包括动态分配的数据)为零值。它调用参数设置为零值的入口点函数,但不使用从入口点函数返回的值。
C main函数必须满足应用程序的要求。这个示例修改了示例main函数,以满足Sobel过滤器应用程序的要求。
这个示例修改文件c
这样Sobel过滤器应用:
从二进制文件读入灰度图像。
应用Sobel滤波算法。
将修改后的图像保存到一个二进制文件。
修改功能main
修改函数主要
:
接受包含灰度图像数据和阈值的文件作为输入参数。
调用这个函数
main_sobel
以灰度图像数据流的地址和阈值作为输入参数。
在函数主要
:
删除声明
命令行参数个数(空白)
而且(空白)argv
.声明的变量
文件名
保存包含灰度图像数据的二进制文件的名称。const char *文件名;
声明的变量
阈值
保持阈值。双阈值;
声明的变量
fd
保存应用程序从中读取的灰度图像数据的地址文件名
.文件* fd;
添加一个
如果
语句,该语句检查三个实参。if (argc != 3) {printf("预期的2个参数:文件名和阈值\n");退出(1);}
为输入参数赋值
argv [1]
用于包含灰度图像数据的文件文件名
.文件名= argv [1];
为输入参数赋值
argv [2]
的阈值阈值
,将输入从字符串转换为数字双精度。阈值= atof (argv [2]);
中指定名称的灰度图像数据
文件名
.将数据流的地址分配给fd
.Fd = fopen(filename, "rb");
验证可执行文件是否可以打开
文件名
,写一如果
的值时退出程序的-statementfd
是零
.if (fd == NULL) {exit(-1);}
替换函数调用
main_sobel
通过调用main_sobel
与输入参数fd
而且阈值
.main_sobel (fd,阈值);
调用后关闭灰度图像文件
sobel_terminate
.文件关闭(fd);
修改初始化函数argInit_d1024xd1024_real_T
在示例主文件中,函数argInit_d1024xd1024_real_T
为传递给Sobel过滤器的图像创建一个动态分配的可变大小数组(emxArray)。这个函数将emxArray初始化为默认大小,并将emxArray的元素初始化为0。它返回初始化的emxArray。
对于Sobel过滤器应用程序,修改函数以将灰度图像数据从二进制文件读入emxArray。
在函数argInit_d1024xd1024_real_T
:
替换输入参数
无效
与参数文件* fd
.这个变量指向函数读入的灰度图像数据。静态emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd)
更改变量的值
idx0
而且idx1
匹配灰度图像矩阵的尺寸灰色的
.这些变量保存emxArray的尺寸的大小值argInit_d1024xd1024_real_T
创建。Int idx0 = 484;Int idx1 = 648;
MATLAB以列为主格式存储矩阵数据,而C以行为主格式存储矩阵数据。相应地声明维度。
的值
emxCreate_real_T
函数的图像大小。result = emxCreate_real_T(484, 648);
定义一个变量
元素
保存从灰度图像数据读入的值。双元素;
改变
为
-循环构造从归一化图像读入数据点元素
通过添加一个从文件中读
通往内心的命令为
循环。Fread (&element, 1, sizeof(element), fd);
在
为
循环,分配元素
为emxArray数据设置的值。Result ->data[idx0 + Result ->size[0] * idx1] = element;
写函数saveImage
MATLAB函数sobel.m
但Sobel过滤器应用程序与二进制文件接口。
要将Sobel滤波算法修改的图像保存到二进制文件中,请创建一个函数saveImage
.这个函数saveImage
将emxArray中的数据写入二进制文件。它使用的结构与函数使用的结构类似argInit_d1024xd1024_real_T
.
在文件中c
:
定义的函数
saveImage
它接受emxArray的地址edgeImage
作为输入,并具有输出类型void。(emxArray_uint8_T *edgeImage) {}
定义的变量
idx0
而且idx1
就像在函数中定义的一样argInit_d1024xd1024_real_T
.int idx;int idx1;
定义的变量
元素
存储从emxArray读取的数据。uint8_T元素;
打开二进制文件
edge.bin
用于写入修改后的图像。指定的地址edge.bin
来文件* fd
.FILE *fd = fopen("edge.bin", "wb");
验证可执行文件是否可以打开
edge.bin
,写一如果
的值时退出程序的-statementfd
是零
.if (fd == NULL) {exit(-1);}
写一个嵌套
为
-循环构造就像函数中的那个argInit_d1024xd1024_real_T
.For (idx0 = 0;idx0 < edgeImage - >大小[0 u];Idx0 ++) {for (idx1 = 0;idx1 < edgeImage - >大小[1 u];Idx1 ++) {}}
内部的内在的
为
-loop,将修改后的图像数据赋值给元素
.element = edgeImage->data[idx0 + edgeImage->size[0] * idx1];
在为
元素
,将值写入元素
到文件edge.bin
.Fwrite (&element, 1, sizeof(element), fd);
后
为
循环构造,近fd
.文件关闭(fd);
修改函数main_sobel
在示例的main函数中,函数main_sobel
为灰度和修改后的图像的数据创建emxArrays。它调用函数argInit_d1024xd1024_real_T
初始化灰度图像的emxArray。main_sobel
通过emxArrays和初始化函数的阈值0argInit_real_T
返回到函数索贝尔
.当这个函数main_sobel
结束时,它丢弃函数的结果索贝尔
.
如果是Sobel filter应用,请修改该函数main_sobel
:
以灰度图像数据的地址和阈值作为输入。
从地址中读取数据
argInit_d1024xd1024_real_T
.将数据传递给具有阈值的Sobel滤波算法
阈值
.使用
saveImage
.
在函数main_sobel
:
用参数替换函数的输入参数
文件* fd
而且双阈值
.void main_sobel(FILE *fd, double threshold)
传递输入参数
fd
函数调用argInit_d1024xd1024_real_T
.originalImage之下= argInit_d1024xd1024_real_T (fd);
替换函数调用中输入的阈值
索贝尔
与阈值
.索贝尔(originalImage之下,阈值,edgeImage);
在调用函数之后
索贝尔
,调用函数saveImage
与输入edgeImage
.saveImage (edgeImage);
修改函数声明
要匹配您对函数定义所做的更改,请对函数声明进行以下更改:
改变函数的输入
* argInit_d1024xd1024_real_T
来文件* fd
.静态emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd);
改变函数的输入
main_sobel
来文件* fd
而且双阈值
.void main_sobel(FILE *fd, double threshold);
添加的功能
saveImage
.静态void saveImage(emxArray_uint8_T *edgeImage);
修改包含文件
中使用的输入/输出函数c
,添加头文件stdio . h
到包含的文件列表。
# include < stdio . h >
修改后的文件内容c
生成Sobel过滤器应用程序
导航到工作文件夹,如果您当前不在其中。
为C独立可执行文件创建配置对象。
cfg = coder.config (exe”);
使用配置对象和修改后的main函数为Sobel过滤器生成一个C独立可执行文件。
codegen报告配置cfg索贝尔cmain.h
默认情况下,如果你在Windows上运行MATLAB®平台,可执行sobel.exe
在当前工作文件夹中生成。如果您在Windows以外的平台上运行MATLAB,则文件扩展名是该平台对应的扩展名。默认情况下,为可执行文件生成的代码在文件夹中codegen / exe /索贝尔
.
运行Sobel过滤器应用程序
创建MATLAB矩阵
灰色的
如果它目前不在你的MATLAB工作区中:我= imread (“hello.jpg”);
灰色=(0.2989 *双(im(:,: 1)) + 0.5870 *双(im(:,: 2)) + 0.1140 *双(im (:,:, 3))) / 255;
编写矩阵
灰色的
方法转换为二进制文件打开外部文件
而且写入文件
命令。应用程序读取这个二进制文件。fid = fopen (“gray.bin”,' w ');写入文件(fid,灰色,“双”);文件关闭(fid);
运行可执行文件,将文件传递给它
gray.bin
阈值为0.7。要在Windows平台上的MATLAB中运行这个例子:
系统(“sobel.exe gray.bin 0.7”);
可执行文件生成文件
edge.bin
.
显示结果图像
读取文件
edge.bin
转化为MATLAB矩阵edgeImExe
使用打开外部文件
而且从文件中读
命令。fd = fopen (“edge.bin”,“r”);edgeImExe = fread(fd, size(灰色),“uint8”);文件关闭(fd);
通过矩阵
edgeImExe
的函数repmat
然后显示图像。im3Exe = repmat(edgeImExe, [1 1 3]);图像(im3Exe);
该图像与MATLAB和MEX函数生成的图像相匹配。