主要内容

在应用程序中使用示例 C 主函数

R2026b

此示例说明如何从 MATLAB® 代码编译 C 可执行文件,该代码实现一个简单的索贝尔滤波器以对图像执行边缘检测。该可执行文件从磁盘读取一个图像,应用索贝尔滤波算法,然后保存修改后的图像。

此示例说明如何生成和修改可在编译可执行文件时使用的示例主函数。

前提条件

要完成此示例,请安装以下产品:

  • MATLAB

  • MATLAB Coder™

  • C 编译器(对于大多数平台,MATLAB 随附提供了一个默认 C 编译器)。要查看支持的编译器列表,请参阅支持的编译器。

    可以使用 mex -setup 更改默认编译器。请参阅更改默认编译器。

教程文件:索贝尔滤波器

打开此示例以获取本教程的文件:sobel.m 和 hello.jpg。

教程文件的描述

您在此示例中使用的文件包含:

文件名文件类型描述
sobel.m函数代码索贝尔滤波算法的 MATLAB 实现。sobel.m 接受图像(表示为双精度矩阵)和阈值作为输入。该算法检测图像中的边缘(基于阈值)。sobel.m 返回修改后且显示边缘的图像。
hello.jpg图像文件索贝尔滤波器修改的图像。
function edgeImage = sobel(originalImage, threshold) %#codegen

% edgeImage = sobel(originalImage, threshold)
% Sobel edge detection. Given a normalized image (with double values)
% return an image where the edges are detected w.r.t. threshold value.

assert(all(size(originalImage) <= [1024 1024]));
assert(isa(originalImage, 'double'));
assert(isa(threshold, 'double'));

k = [1 2 1; 0 0 0; -1 -2 -1];
H = conv2(double(originalImage),k, 'same');
V = conv2(double(originalImage),k','same');
E = sqrt(H.*H + V.*V);
edgeImage = uint8((E > threshold) * 255);

Photograph of the sentence "Hello!" hand-written in large letters on a notepad

对图像运行索贝尔滤波器

  1. 将原始图像读入 MATLAB 矩阵并显示该图像。

    im = imread('hello.jpg');
  2. 显示该图像以便与索贝尔滤波器结果进行比较。

    image(im);

    Color photograph of the sentence "Hello!", which is hand-written in large letters on a notepad

  3. 索贝尔滤波算法对灰度图像进行运算。使用归一化值(0.0 代表黑色、1.0 代表白色),将彩色图像转换为等效的灰度图像。

    gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;
  4. 要运行针对索贝尔滤波器的 MATLAB 函数,请将灰度图像矩阵 gray 和阈值传递给函数 sobel。此示例使用 0.7 作为阈值。

    edgeIm = sobel(gray, 0.7);
  5. 要显示修改后的图像,请使用 repmat 函数重新格式化矩阵 edgeIm,以便将其传递给 image 命令。

    im3 = repmat(edgeIm, [1 1 3]);
    image(im3);

    Greyscale rendering of the color photograph after Sobel filtering. The notepad, the letters in the word "Hello," and the exclamation point are outlined in white on a black background.

生成并测试 MEX 函数

  1. 要测试生成的代码是否在功能上等效于原始 MATLAB 代码并且不会发生运行时错误,请生成一个 MEX 函数。

    codegen -report sobel

    codegen 在当前工作文件夹中生成名为 sobel_mex 的 MEX 函数。

  2. 要运行针对索贝尔滤波器的 MEX 函数,请将灰度图像矩阵 gray 和阈值传递给函数 sobel_mex。此示例使用 0.7 作为阈值。

    edgeImMex = sobel_mex(gray, 0.7);
  3. 要显示修改后的图像,请使用 repmat 函数重新格式化矩阵 edgeImMex,以便将其传递给 image 命令。

    im3Mex = repmat(edgeImMex, [1 1 3]);
    image(im3Mex);

    此图像与使用 MATLAB 函数创建的图像相同。

为 sobel.m 生成示例主函数

虽然您可以针对您的应用程序编写自定义主函数,但示例主函数提供了一个模板来帮助您合并生成的代码。

要为索贝尔滤波器生成示例主函数,请执行下列操作:

  1. 为 C 静态库创建一个配置对象。

    cfg = coder.config('lib');

    对于 C/C++ 源代码、静态库、动态库和可执行文件的配置对象,GenerateExampleMain 的设置可控制示例主函数的生成。默认情况下,该设置设为 'GenerateCodeOnly',即生成示例主函数但不编译它。对于此示例,请勿更改 GenerateExampleMain 设置的值。

  2. 使用该配置对象生成一个 C 静态库。

    codegen -report -config cfg sobel

生成的静态库文件位于文件夹 codegen/lib/sobel 中。示例主文件位于子文件夹 codegen/lib/sobel/examples 中。

/*
 * File: main.c
 *
 */

/*************************************************************************/
/* This automatically generated example C main file shows how to call    */
/* entry-point functions that MATLAB Coder generated. You must customize */
/* this file for your application. Do not modify this file directly.     */
/* Instead, make a copy of this file, modify it, and integrate it into   */
/* your development environment.                                         */
/*                                                                       */
/* This file initializes entry-point function arguments to a default     */
/* size and value before calling the entry-point functions. It does      */
/* not store or use any values returned from the entry-point functions.  */
/* If necessary, it does pre-allocate memory for returned values.        */
/* You can use this file as a starting point for a main function that    */
/* you can deploy in your application.                                   */
/*                                                                       */
/* After you copy the file, and before you deploy it, you must make the  */
/* following changes:                                                    */
/* * For variable-size function arguments, change the example sizes to   */
/* the sizes that your application requires.                             */
/* * Change the example values of function arguments to the values that  */
/* your application requires.                                            */
/* * If the entry-point functions return values, store these values or   */
/* otherwise use them as required by your application.                   */
/*                                                                       */
/*************************************************************************/

/* Include Files */
#include "main.h"
#include "sobel.h"
#include "sobel_emxAPI.h"
#include "sobel_terminate.h"
#include "sobel_types.h"

/* Function Declarations */
static emxArray_real_T *argInit_d1024xd1024_real_T(void);

static double argInit_real_T(void);

static void main_sobel(void);

/* Function Definitions */
/*
 * Arguments    : void
 * Return Type  : emxArray_real_T *
 */
static emxArray_real_T *argInit_d1024xd1024_real_T(void)
{
  emxArray_real_T *result;
  double *result_data;
  int idx0;
  int idx1;
  /* Set the size of the array.
Change this size to the value that the application requires. */
  result = emxCreate_real_T(2, 2);
  result_data = result->data;
  /* Loop over the array to initialize each element. */
  for (idx0 = 0; idx0 < result->size[0U]; idx0++) {
    for (idx1 = 0; idx1 < result->size[1U]; idx1++) {
      /* Set the value of the array element.
Change this value to the value that the application requires. */
      result_data[idx0 + result->size[0] * idx1] = argInit_real_T();
    }
  }
  return result;
}

/*
 * Arguments    : void
 * Return Type  : double
 */
static double argInit_real_T(void)
{
  return 0.0;
}

/*
 * Arguments    : void
 * Return Type  : void
 */
static void main_sobel(void)
{
  emxArray_real_T *originalImage;
  emxArray_uint8_T *edgeImage;
  emxInitArray_uint8_T(&edgeImage, 2);
  /* Initialize function 'sobel' input arguments. */
  /* Initialize function input argument 'originalImage'. */
  originalImage = argInit_d1024xd1024_real_T();
  /* Call the entry-point 'sobel'. */
  sobel(originalImage, argInit_real_T(), edgeImage);
  emxDestroyArray_uint8_T(edgeImage);
  emxDestroyArray_real_T(originalImage);
}

/*
 * Arguments    : int argc
 *                char **argv
 * Return Type  : int
 */
int main(int argc, char **argv)
{
  (void)argc;
  (void)argv;
  /* The initialize function is being called automatically from your entry-point
   * function. So, a call to initialize is not included here. */
  /* Invoke the entry-point functions.
You can call entry-point functions multiple times. */
  main_sobel();
  /* Terminate the application.
You do not need to do this more than one time. */
  sobel_terminate();
  return 0;
}

/*
 * File trailer for main.c
 *
 * [EOF]
 */

复制示例主文件

不要修改 examples 子文件夹中的 main.c 和 main.h 文件。如果修改这些文件,则当您重新生成代码时,MATLAB Coder 不会重新生成示例主文件。它会发出警告,提示检测到生成文件发生了更改。

将文件 main.c 和 main.h 从文件夹 codegen/lib/sobel/examples 复制到另一个位置。对于此示例,请将文件复制到当前工作文件夹中。修改新位置中的文件。

修改生成的示例主函数

示例主函数声明数据(包括动态分配的数据)并将数据初始化为零值。它调用入口函数(其参量设置为零值),但它不使用从入口函数返回的值。

C 主函数必须满足您的应用程序的要求。此示例修改示例主函数以满足索贝尔滤波器应用程序的要求。

此示例修改文件 main.c 以便索贝尔滤波器应用程序:

  • 从二进制文件中读入灰度图像。

  • 应用索贝尔滤波算法。

  • 将修改后的图像保存为二进制文件。

修改 main 函数

将 main 函数修改为:

  • 接受包含灰度图像数据的文件和阈值作为输入参量。

  • 使用灰度图像数据流的地址和阈值作为输入参量调用函数 main_sobel。

在函数 main 中:

  1. 删除 (void)argc 和 (void)argv 声明。

  2. 声明变量 filename 以保存包含灰度图像数据的二进制文件的名称。

    const char *filename;
  3. 声明变量 threshold 以保存阈值。

    double threshold;
  4. 声明变量 fd 以保存应用程序从 filename 读入的灰度图像数据的地址。

    FILE *fd;
  5. 添加一个用于检查三个参量的 if 语句。

    if (argc != 3) {
          printf("Expected 2 arguments: filename and threshold\n");
          exit(-1);
    }
  6. 将包含灰度图像数据的文件的输入参量 argv[1] 赋给 filename。

    filename = argv[1];
  7. 将阈值的输入参量 argv[2] 赋给 threshold,从而将输入从字符串转换为双精度数值。

    threshold = atof(argv[2]);
  8. 打开包含其名称在 filename 中指定的灰度图像数据的文件。将数据流的地址赋给 fd。

    fd = fopen(filename, "rb");
  9. 要验证可执行文件可以打开 filename,请编写一个 if 语句,其功能是在 fd 的值为 NULL 时退出程序。

    if (fd == NULL) {
       exit(-1);
    }
  10. 将对 main_sobel 的函数调用替换为带输入参量 fd 和 threshold 调用 main_sobel。

    main_sobel(fd, threshold);
  11. 调用 sobel_terminate 后关闭灰度图像文件。

    fclose(fd);
int main(int argc, char **argv)
{
  const char *filename;
  double threshold;
  FILE *fd;
  if (argc != 3) {
      printf("Expected 2 arguments: filename and threshold\n");
      exit(-1);
  }
  filename = argv[1];
  threshold = atof(argv[2]);
  
  fd = fopen(filename, "rb");
  if (fd == NULL) {
   exit(-1);
  }

  main_sobel(fd, threshold);
  fclose(fd);
  sobel_terminate();
  
  return 0;
}

修改初始化函数 argInit_d1024xd1024_real_T

在示例主文件中,函数 argInit_d1024xd1024_real_T 为传递给索贝尔滤波器的图像创建一个动态分配的可变大小数组 (emxArray)。此函数将 emxArray 初始化为默认大小,并将 emxArray 的元素初始化为 0。它返回初始化后的 emxArray。

对于索贝尔滤波器应用程序,请修改该函数以将灰度图像数据从二进制文件读入 emxArray 中。

在函数 argInit_d1024xd1024_real_T 中:

  1. 将输入参量 void 替换为参量 FILE *fd。此变量指向该函数读入的灰度图像数据。

    static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd)
  2. 更改变量 idx0 和 idx1 的值,以匹配灰度图像矩阵 gray 的维度。这些变量保留 argInit_d1024xd1024_real_T 创建的 emxArray 的维度的大小值。

    int idx0 = 484;
    int idx1 = 648;

    MATLAB 以列优先格式存储矩阵数据,而 C 以行优先格式存储矩阵数据。请相应地声明维度。

  3. 将 emxCreate_real_T 函数的值更改为图像大小。

    result = emxCreate_real_T(484, 648);
  4. 定义变量 element 以保存从灰度图像数据读入的值。

    double element;
  5. 通过向内部 for 循环添加 fread 命令,更改 for 循环构造以将数据点从归一化图像读入 element 中。

    fread(&element, 1, sizeof(element), fd);
  6. 在 for 循环内,将 element 指定为 emxArray 数据的值集合。

    result->data[idx0 + result->size[0] * idx1] = element;
static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd)
{
  emxArray_real_T *result;
  double *result_data;
  int idx0 = 484;
  int idx1 = 648;
  /* Set the size of the array.
Change this size to the value that the application requires. */
  double element;
  result = emxCreate_real_T(484, 648);
  result_data = result->data;
  /* Loop over the array to initialize each element. */
  for (idx0 = 0; idx0 < result->size[0U]; idx0++) {
    for (idx1 = 0; idx1 < result->size[1U]; idx1++) {
      /* Set the value of the array element.
Change this value to the value that the application requires. */
      fread(&element, 1, sizeof(element), fd);
      result_data[idx0 + result->size[0] * idx1] = element;
    }
  }
  return result;
}

编写 saveImage 函数

MATLAB 函数 sobel.m 与 MATLAB 数组交互,而索贝尔滤波器应用程序与二进制文件交互。

要将用索贝尔滤波算法修改后的图像保存为二进制文件,请创建函数 saveImage。函数 saveImage 将来自 emxArray 的数据写入二进制文件。它使用的构造类似于函数 argInit_d1024xd1024_real_T 所使用的构造。

在文件 main.c 中:

  1. 定义函数 saveImage,它将 emxArray edgeImage 的地址作为输入,输出类型为 void。

    static void saveImage(emxArray_uint8_T *edgeImage)
    {
    }
  2. 定义变量 idx0 和 idx1,就像在函数 argInit_d1024xd1024_real_T 中定义它们一样。

    int idx;
    int idx1;
  3. 定义变量 element 以存储从 emxArray 读取的数据。

    uint8_T element;
  4. 打开二进制文件 edge.bin 以写入修改后的图像。将 edge.bin 的地址赋给 FILE *fd。

    FILE *fd = fopen("edge.bin", "wb");
  5. 要验证可执行文件可以打开 edge.bin,请编写一个 if 语句,其功能是在 fd 的值为 NULL 时退出程序。

    if (fd == NULL) {
       exit(-1);
    }
  6. 编写一个嵌套的 for 循环构造,该构造类似于函数 argInit_d1024xd1024_real_T 中的构造。

    for (idx0 = 0; idx0 < edgeImage->size[0U]; idx0++)
    {
        for (idx1 = 0; idx1 < edgeImage->size[1U]; idx1++)
        {
        }
    }
  7. 在内部 for 循环内,将来自修改后的图像数据的值赋给 element。

    element = edgeImage->data[idx0 + edgeImage->size[0] * idx1];
  8. 在为 element 赋值后,将来自 element 的值写入文件 edge.bin。

    fwrite(&element, 1, sizeof(element), fd);
  9. 在 for 循环构造后,关闭 fd。

    fclose(fd);
static void saveImage(emxArray_uint8_T *edgeImage)
{
  int idx0;
  int idx1;
  uint8_T element;
 
  FILE *fd = fopen("edge.bin", "wb");
 if (fd == NULL) {
   exit(-1);
 }
  /* Loop over the array to save each element. */
  for (idx0 = 0; idx0 < edgeImage->size[0U]; idx0++) {
    for (idx1 = 0; idx1 < edgeImage->size[1U]; idx1++) {
      element = edgeImage->data[idx0 + edgeImage->size[0] * idx1];
      fwrite(&element, 1, sizeof(element), fd);
    }
  }
  fclose(fd);
}

修改 main_sobel 函数

在示例主函数中,函数 main_sobel 为灰度图像和修改后的图像的数据创建 emxArray。它调用函数 argInit_d1024xd1024_real_T 以初始化灰度图像的 emxArray。main_sobel 将 emxArray 和初始化函数 argInit_real_T 返回的阈值 0 传递给函数 sobel。当函数 main_sobel 结束时,它会丢弃函数 sobel 的结果。

对于索贝尔滤波器应用程序,请将函数 main_sobel 修改为:

  • 将灰度图像数据的地址和阈值作为输入。

  • 使用 argInit_d1024xd1024_real_T 从地址读取数据。

  • 使用阈值 threshold 将数据传递给索贝尔滤波算法。

  • 使用 saveImage 保存结果。

在函数 main_sobel 中:

  1. 将函数的输入参量替换为 FILE *fd 和 double threshold 参量。

    static void main_sobel(FILE *fd, double threshold)
  2. 将输入参量 fd 传递给 argInit_d1024xd1024_real_T 的函数调用。

    originalImage = argInit_d1024xd1024_real_T(fd);
  3. 将对 sobel 的函数调用中的阈值输入替换为 threshold。

    sobel(originalImage, threshold, edgeImage);
  4. 调用函数 sobel 后,带 edgeImage 输入调用函数 saveImage。

    saveImage(edgeImage);
static void main_sobel(FILE *fd, double threshold)
{
  emxArray_real_T *originalImage;
  emxArray_uint8_T *edgeImage;
  emxInitArray_uint8_T(&edgeImage, 2);
  /* Initialize function 'sobel' input arguments. */
  /* Initialize function input argument 'originalImage'. */
  originalImage = argInit_d1024xd1024_real_T(fd);
  /* Call the entry-point 'sobel'. */
  sobel(originalImage, threshold, edgeImage);
  saveImage(edgeImage);
    
  emxDestroyArray_uint8_T(edgeImage);
  emxDestroyArray_real_T(originalImage);
}

修改函数声明

为了匹配您对函数定义所做的更改,请对函数声明进行以下更改:

  1. 将函数 *argInit_d1024xd1024_real_T 的输入更改为 FILE *fd。

    static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd);
  2. 将函数 main_sobel 的输入更改为 FILE *fd 和 double threshold。

    static void main_sobel(FILE *fd, double threshold);
  3. 添加函数 saveImage。

    static void saveImage(emxArray_uint8_T *edgeImage);
/* Function Declarations */
static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd);
static void saveImage(emxArray_uint8_T *edgeImage);
static double argInit_real_T(void);
static void main_sobel(FILE *fd, double threshold);

修改包含文件

对于在 main.c 中使用的输入/输出函数,将头文件 stdio.h 添加到包含的文件列表中。

#include <stdio.h>
/* Include Files */
#include <stdio.h>

#include "sobel.h"
#include "main.h"
#include "sobel_terminate.h"
#include "sobel_emxAPI.h"
#include "sobel_initialize.h"

修改后的 main.c 文件的内容

/*
 * File: main.c
 *
 */

/*************************************************************************/
/* This automatically generated example C main file shows how to call    */
/* entry-point functions that MATLAB Coder generated. You must customize */
/* this file for your application. Do not modify this file directly.     */
/* Instead, make a copy of this file, modify it, and integrate it into   */
/* your development environment.                                         */
/*                                                                       */
/* This file initializes entry-point function arguments to a default     */
/* size and value before calling the entry-point functions. It does      */
/* not store or use any values returned from the entry-point functions.  */
/* If necessary, it does pre-allocate memory for returned values.        */
/* You can use this file as a starting point for a main function that    */
/* you can deploy in your application.                                   */
/*                                                                       */
/* After you copy the file, and before you deploy it, you must make the  */
/* following changes:                                                    */
/* * For variable-size function arguments, change the example sizes to   */
/* the sizes that your application requires.                             */
/* * Change the example values of function arguments to the values that  */
/* your application requires.                                            */
/* * If the entry-point functions return values, store these values or   */
/* otherwise use them as required by your application.                   */
/*                                                                       */
/*************************************************************************/

/* Include Files */
#include <stdio.h>
#include "main.h"
#include "sobel.h"
#include "sobel_emxAPI.h"
#include "sobel_terminate.h"
#include "sobel_types.h"

/* Function Declarations */
static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd);
static void saveImage(emxArray_uint8_T *edgeImage);
static double argInit_real_T(void);
static void main_sobel(FILE *fd, double threshold);

/* Function Definitions */
/*
 * Arguments    : void
 * Return Type  : emxArray_real_T *
 */
static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd)
{
  emxArray_real_T *result;
  double *result_data;
  int idx0 = 484;
  int idx1 = 648;
  /* Set the size of the array.
  Change this size to the value that the application requires. */
  double element;
  result = emxCreate_real_T(484, 648);
  result_data = result->data;
  /* Loop over the array to initialize each element. */
  for (idx0 = 0; idx0 < result->size[0U]; idx0++) {
    for (idx1 = 0; idx1 < result->size[1U]; idx1++) {
      /* Set the value of the array element.
  Change this value to the value that the application requires. */
      fread(&element, 1, sizeof(element), fd);
      result_data[idx0 + result->size[0] * idx1] = element;
    }
  }
  return result;
}

static void saveImage(emxArray_uint8_T *edgeImage)
{
  int idx0;
  int idx1;
  uint8_T element;
 
  FILE *fd = fopen("edge.bin", "wb");
 if (fd == NULL) {
   exit(-1);
 }
  /* Loop over the array to save each element. */
  for (idx0 = 0; idx0 < edgeImage->size[0U]; idx0++) {
    for (idx1 = 0; idx1 < edgeImage->size[1U]; idx1++) {
      element = edgeImage->data[idx0 + edgeImage->size[0] * idx1];
      fwrite(&element, 1, sizeof(element), fd);
    }
  }
  fclose(fd);
}

/*
 * Arguments    : void
 * Return Type  : double
 */
static double argInit_real_T(void)
{
  return 0.0;
}

/*
 * Arguments    : void
 * Return Type  : void
 */
static void main_sobel(FILE *fd, double threshold)
{
  emxArray_real_T *originalImage;
  emxArray_uint8_T *edgeImage;
  emxInitArray_uint8_T(&edgeImage, 2);
  /* Initialize function 'sobel' input arguments. */
  /* Initialize function input argument 'originalImage'. */
  originalImage = argInit_d1024xd1024_real_T(fd);
  /* Call the entry-point 'sobel'. */
  sobel(originalImage, threshold, edgeImage);
  saveImage(edgeImage);
    
  emxDestroyArray_uint8_T(edgeImage);
  emxDestroyArray_real_T(originalImage);
}

/*
 * Arguments    : int argc
 *                char **argv
 * Return Type  : int
 */
int main(int argc, char **argv)
{
  const char *filename;
  double threshold;
  FILE *fd;
  if (argc != 3) {
      printf("Expected 2 arguments: filename and threshold\n");
      exit(-1);
  }
  filename = argv[1];
  threshold = atof(argv[2]);
  
  fd = fopen(filename, "rb");
  if (fd == NULL) {
   exit(-1);
  }

  /* The initialize function is being called automatically from your entry-point
   * function. So, a call to initialize is not included here. */
  /* Invoke the entry-point functions.
You can call entry-point functions multiple times. */
  main_sobel(fd, threshold);
    fclose(fd);
  /* Terminate the application.
You do not need to do this more than one time. */
  sobel_terminate();
  return 0;
}

/*
 * File trailer for main.c
 *
 * [EOF]
 */

生成索贝尔滤波器应用程序

  1. 导航到工作文件夹(如果当前不在该文件夹中)。

  2. 为 C 独立可执行文件创建一个配置对象。

    cfg = coder.config('exe');
  3. 使用该配置对象和修改后的主函数为索贝尔滤波器生成 C 独立可执行文件。

    codegen -report -config cfg sobel main.c main.h

默认情况下,如果在 Windows® 平台上运行 MATLAB,则会在当前工作文件夹中生成可执行文件 sobel.exe。如果在 Windows 以外的平台上运行 MATLAB,则文件扩展名是该平台的对应扩展名。默认情况下,为可执行文件生成的代码位于文件夹 codegen/exe/sobel 中。

运行索贝尔滤波器应用程序

  1. 创建 MATLAB 矩阵 gray(如果它当前不在 MATLAB 工作区中):

    im = imread('hello.jpg');
    gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;
  2. 使用 fopen 和 fwrite 命令将矩阵 gray 写入一个二进制文件。应用程序读入此二进制文件。

    fid = fopen('gray.bin', 'w');
    fwrite(fid, gray, 'double');
    fclose(fid);
  3. 运行可执行文件,将文件 gray.bin 和阈值 0.7 传递给它。

    要在 Windows 平台上运行 MATLAB 中的示例,请执行以下命令:

    system('sobel.exe gray.bin 0.7');

    可执行文件会生成 edge.bin 文件。

显示生成的图像

  1. 使用 fopen 和 fread 命令将文件 edge.bin 读入 MATLAB 矩阵 edgeImExe。

    fd = fopen('edge.bin', 'r');
    edgeImExe = fread(fd, size(gray), 'uint8');
    fclose(fd);
  2. 将矩阵 edgeImExe 传递给函数 repmat 并显示图像。

    im3Exe = repmat(edgeImExe, [1 1 3]);
    image(im3Exe);

    图像与来自 MATLAB 和 MEX 函数的图像匹配。

另请参阅

主题