Main Content

このページ最新ではありませ。をクリックし,英语のの最新版版を参照参照し。

イメージのエッジ検出

この例では、イメージのエッジ検出を行う単純なソーベル フィルターを実装する MATLAB コードから標準 C ライブラリを生成する方法を示します。また、MATLAB コードがコードの生成に適していることを確認するために C コードを生成する前に MEX 関数を生成してテストする方法も示します。

関数sobelについて

関数sobel.mは,イメージ双行(列)およびしきい値を取得し,イメージと(しきい値に基づいて)検出されたエッジを返します。

typesobel
% 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. function edgeImage = sobel(originalImage, threshold) %#codegen 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);

mex关数の生成

codegenコマンドを使用して MEX 関数を生成します。

codegensobel

C コードを生成する前に、MATLAB で MEX 関数をテストして、その関数が元の MATLAB コードと機能的に等価であることと実行時のエラーが発生しないことを確認しなければなりません。既定で、codegenは、現在のフォルダーにsobel_mexという名前の MEX 関数を生成します。これにより、MATLAB コードと MEX 関数をテストして結果を比較することができます。

元のイメージの読み取り

标准のimreadコマンドを使用ます。

im = imread('hello.jpg'); image(im);

グレースケール バージョンへの変換

正規化された値 (0.0 が黒、1.0 が白) を使って上記のカラー イメージを等価のグレースケール イメージに変換します。

gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;

MEX 関数の実行 (ソーベル フィルター)

正規化されたイメージとしきい値を渡します。

edgeIm = sobel_mex(gray, 0.7);

結果の表示

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

スタンドアロン C コードの生成

codegen-configcoder.config('lib')sobel

-config coder.config('lib')オプションを指定してcodegenを使用,アロンアロンライブラリがさます。既定で,,ライブラリ用にに生成コードコードコードコードcodegen/lib/sobel/フォルダーにあります。

生成された関数の確認

typecodegen/lib/sobel/sobel.c
/* * File: sobel.c * * MATLAB Coder version : 5.1 * C/C++ source code generated on : 24-Aug-2020 19:17:27 */ /* Include Files */ #include "sobel.h" #include "conv2AXPYSameCMP.h" #include "sobel_data.h" #include "sobel_emxutil.h" #include "sobel_initialize.h" #include "sobel_types.h" #include  /* Function Definitions */ /* * Arguments : const emxArray_real_T *originalImage * double threshold * emxArray_uint8_T *edgeImage * Return Type : void */ void sobel(const emxArray_real_T *originalImage, double threshold, emxArray_uint8_T *edgeImage) { emxArray_real_T *H; emxArray_real_T *V; int k; int nx; if (!isInitialized_sobel) { sobel_initialize(); } emxInit_real_T(&H, 2); emxInit_real_T(&V, 2); /* 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. */ conv2AXPYSameCMP(originalImage, H); b_conv2AXPYSameCMP(originalImage, V); nx = H->size[0] * H->size[1]; for (k = 0; k < nx; k++) { H->data[k] = H->data[k] * H->data[k] + V->data[k] * V->data[k]; } emxFree_real_T(&V); nx = H->size[0] * H->size[1]; for (k = 0; k < nx; k++) { H->data[k] = sqrt(H->data[k]); } k = edgeImage->size[0] * edgeImage->size[1]; edgeImage->size[0] = H->size[0]; edgeImage->size[1] = H->size[1]; emxEnsureCapacity_uint8_T(edgeImage, k); nx = H->size[0] * H->size[1]; for (k = 0; k < nx; k++) { edgeImage->data[k] = (unsigned char)((H->data[k] > threshold) * 255U); } emxFree_real_T(&H); } /* * File trailer for sobel.c * * [EOF] */