メインコンテンツ

アプリケーションにおける C の main の例の使用

R2026b

この例では、イメージのエッジ検出を行う単純なソーベル フィルターを実装する MATLAB® コードから C 実行可能ファイルをビルドする方法を示します。実行可能ファイルはディスクからイメージを読み取り、ソーベル フィルター アルゴリズムを適用して、変更されたイメージを保存します。

この例では、実行可能ファイルをビルドする際に使用する main 関数の例を生成して変更する方法を示します。

前提条件

この例を実行するには、次の製品をインストールします。

  • MATLAB

  • MATLAB Coder™

  • C コンパイラ (ほとんどのプラットフォーム用に、既定の C コンパイラが MATLAB に付属しています)。サポートされているコンパイラのリストは、サポートされるコンパイラを参照してください。

    mex -setup を使用して既定のコンパイラを変更できます。既定のコンパイラの変更を参照してください。

チュートリアル ファイル: ソーベル フィルター

この例を開いて、このチュートリアルのファイル sobel.mhello.jpg を取得します。

チュートリアル ファイルの説明

この例では次のファイルを使用します。

ファイル名ファイルの種類説明
sobel.m関数のコードMATLAB によるソーベル フィルター アルゴリズムの実装。sobel.m はイメージ (double 行列) およびしきい値を入力として取得します。アルゴリズムはイメージのエッジを (しきい値に基づいて) 検出します。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. 変更したイメージを表示するには、行列 edgeIm の形式を関数 repmat で変更し、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. 変更したイメージを表示するには、行列 edgeImMex の形式を関数 repmat で変更し、image コマンドに渡せるようにします。

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

    このイメージは MATLAB 関数を使用して作成されたイメージと同じです。

sobel.m 用の main 関数の例の生成

アプリケーション用にカスタム main 関数を作成することはできますが、main 関数の例は生成されたコードを組み込む際に役立つテンプレートを提供します。

ソーベル フィルター用に main 関数の例を生成するには、次の手順に従います。

  1. C スタティック ライブラリ用に構成オブジェクトを作成します。

    cfg = coder.config('lib');

    C/C++ ソース コード、スタティック ライブラリ、ダイナミック ライブラリおよび実行可能ファイルの構成オブジェクトに対して、設定 GenerateExampleMain は main 関数の例の生成を制御します。この設定は main 関数の例を生成してもコンパイルはしない '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]
 */

メイン ファイルの例のコピー

ファイル main.cmain.hexamples サブフォルダーで変更しないでください。変更すると、コードの再生成時に MATLAB Coder でメイン ファイルの例が再生成されません。生成されたファイルに対する変更が検出されたことを警告します。

ファイル main.cmain.h をフォルダー codegen/lib/sobel/examples から別の場所へコピーします。この例では、ファイルを現在の作業フォルダーへコピーします。新しい場所でファイルを変更します。

生成された main 関数の例の変更

main 関数の例は動的に割り当てられたデータなどのデータを宣言して、ゼロ値に初期化します。これは、ゼロ値に設定された引数でエントリポイント関数を呼び出しますが、エントリポイント関数から返される値は使用しません。

C の main 関数はアプリケーションの要件を満たしていなければなりません。この例では、ソーベル フィルター アプリケーションの要件を満たすように main 関数の例を変更しています。

この例では、ソーベル フィルター アプリケーションが次を実行するように、ファイル 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. 3 つの引数をチェックする 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 に代入し、入力を文字列から double の数値に変換します。

    threshold = atof(argv[2]);
  8. 名前が filename に指定されているグレースケール イメージ データを含んだファイルを開きます。データ ストリームのアドレスを fd に代入します。

    fd = fopen(filename, "rb");
  9. 実行可能ファイルが filename を開くことを検証するには、fd の値が NULL の場合にプログラムを終了する if ステートメントを記述します。

    if (fd == NULL) {
       exit(-1);
    }
  10. 入力引数 fdthreshold を指定して main_sobel を呼び出し、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. グレースケール イメージ行列 gray の次元と一致するように変数 idx0 および idx1 の値を変更します。これらの変数は 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. emxArray edgeImage のアドレスを入力として受け取り、出力タイプ void をもつ関数 saveImage を定義します。

    static void saveImage(emxArray_uint8_T *edgeImage)
    {
    }
  2. 変数 idx0 と変数 idx1 を関数 argInit_d1024xd1024_real_T で定義する場合と同じように定義します。

    int idx;
    int idx1;
  3. emxArray から読み取るデータを格納するように変数 element を定義します。

    uint8_T element;
  4. 変更されたイメージの書き込み用にバイナリ ファイル edge.bin を開きます。edge.bin のアドレスを FILE *fd に代入します。

    FILE *fd = fopen("edge.bin", "wb");
  5. 実行可能ファイルが edge.bin を開くことを検証するには、fd の値が NULL の場合にプログラムを終了する if ステートメントを記述します。

    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 関数の例では、関数 main_sobel はグレースケールのデータと変更されたイメージに emxArrays を作成します。これは、グレースケール イメージの emxArray を初期化する関数 argInit_d1024xd1024_real_T を呼び出します。main_sobel は、emxArrays と、初期化関数 argInit_real_T が関数 sobel に返すしきい値 0 の両方を渡します。関数 main_sobel が終了すると、関数 sobel の結果を破棄します。

ソーベル フィルター アプリケーションの場合、関数 main_sobel を次に変更します。

  • グレースケール イメージ データのアドレスとしきい値を入力として受け取ります。

  • argInit_d1024xd1024_real_T を使用してアドレスからデータを読み取ります。

  • しきい値 threshold でデータをソーベル フィルター アルゴリズムに渡します。

  • saveImage を使用して結果を保存します。

関数 main_sobel で次を実行します。

  1. 引数 FILE *fddouble threshold をもつ関数と入力引数を置き換えます。

    static void main_sobel(FILE *fd, double threshold)
  2. 入力引数 fdargInit_d1024xd1024_real_T の関数呼び出しに渡します。

    originalImage = argInit_d1024xd1024_real_T(fd);
  3. 関数呼び出し内のしきい値の入力を threshold をもつ sobel に置き換えます。

    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 *fddouble 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. 構成オブジェクトと変更された main 関数を使用して、ソーベル フィルターに C スタンドアロンの実行可能ファイルを生成します。

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

既定では、MATLAB を Windows® プラットフォームで実行している場合、実行可能ファイル sobel.exe は現在の作業フォルダーに生成されます。MATLAB を Windows 以外のプラットフォームで実行している場合、ファイルの拡張子はそのプラットフォームに対応する拡張子になります。既定の設定では、実行可能ファイルの生成されたコードはフォルダー 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. 行列 grayfopenfwrite コマンドを使用してバイナリ ファイルに書き込みます。アプリケーションはこのバイナリ ファイルを読み取ります。

    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. fopenfread コマンドを使用して、ファイル 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 関数のイメージと一致します。

参考

トピック