このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
この例では、半精度浮動小数点数を使用してイメージのソーベル エッジ検出を実行する MATLAB® 関数からスタンドアロンの C++ ライブラリを生成する方法を説明します。ソーベル エッジ アルゴリズムは、イメージ (行列として表される) を受け取り、そのエッジに対応する高空間周波数領域を強調するイメージを返します。この例では、MEX 関数を使用してソーベル エッジ検出アルゴリズムを生成およびテストする方法も説明します。
ソーベル エッジ検出アルゴリズムでは、グレースケール イメージに対して 2 次元空間勾配演算が実行されます。この演算では、イメージのエッジに対応する高空間周波数領域が強調されます。
type sobelEdgeDetectionAlg
function edgeImg = sobelEdgeDetectionAlg(img,thresh) %#codegen %sobelEdgeDetection Example MATLAB function for edge detection. % Copyright 2018 The MathWorks, Inc. kern = half([1 2 1; 0 0 0; -1 -2 -1]); % Finding horizontal and vertical gradients. h = conv2(img(:,:,2),kern,'same'); v = conv2(img(:,:,2),kern','same'); % Finding magnitude of the gradients. e = sqrt(h.*h + v.*v); % Threshold the edges edgeImg = uint8((e > thresh) * 240); end
ソーベル エッジ アルゴリズムでは、2 つの直交フィルター カーネル maskX
および maskY
を使用して、入力イメージの水平方向の勾配 resX
と垂直方向の勾配 resY
を計算します。フィルター処理の後に、アルゴリズムは勾配の大きさを計算し、エッジと見なされるイメージの領域を検出するためのしきい値を適用します。
標準のimread
コマンドを使用してイメージを読み取ります。imread
は、イメージの RGB チャネルを整数 (ピクセルごとに 1 つの整数) で表します。整数の範囲は 0 ~ 255 です。単純に入力を half 型にキャストすると、畳み込み中にオーバーフローが発生する可能性があります。この場合は、イメージを 0 から 1 の間の値にスケーリングできます。
im = imread('peppers.png');
figure();
image(im);
imPacked = half(im)/255;
thresh = half(100)/255;
codegen
コマンドを使用して C++ MEX 関数を生成します。
cfg = coder.config('mex'); cfg.TargetLang = 'C++'; cfg.GenerateReport = true; codegen -config cfg -args {imPacked,thresh} sobelEdgeDetectionAlg
Code generation successful: To view the report, open('codegen/mex/sobelEdgeDetectionAlg/html/report.mldatx').
C++ コードを生成する前に、MATLAB で MEX 関数をテストして、その関数が元の MATLAB コードと機能的に等価であることと実行時のエラーが発生しないことを確認しなければなりません。既定で、codegen
は、現在のフォルダーに sobelEdgeDetectionAlg_mex
という名前の MEX 関数を生成します。これにより、MATLAB コードと MEX 関数をテストして結果を比較することができます。
out_disp = sobelEdgeDetectionAlg_mex(imPacked,thresh); figure(); imagesc(out_disp);
codegen
コマンドを使用して C++ スタティック ライブラリを生成します。既定では、生成されたライブラリはフォルダー codegen/lib/sobelEdgeDetectionAlg/
に配置されます。
cfg = coder.config('lib'); cfg.TargetLang = 'C++'; cfg.GenerateReport = true; codegen -config cfg -args {imPacked,thresh} sobelEdgeDetectionAlg;
Code generation successful: To view the report, open('codegen/lib/sobelEdgeDetectionAlg/html/report.mldatx').
type codegen/lib/sobelEdgeDetectionAlg/sobelEdgeDetectionAlg.cpp
// // File: sobelEdgeDetectionAlg.cpp // // MATLAB Coder version : 5.1 // C/C++ source code generated on : 24-Aug-2020 19:15:08 // // Include Files #include "sobelEdgeDetectionAlg.h" #include "conv2MovingWindowSameCM.h" #include "rtwhalf.h" #include "sobelEdgeDetectionAlg_data.h" #include "sobelEdgeDetectionAlg_initialize.h" // Function Definitions // // sobelEdgeDetection Example MATLAB function for edge detection. // Copyright 2018 The MathWorks, Inc. // Arguments : const real16_T img[589824] // real16_T thresh // unsigned char edgeImg[196608] // Return Type : void // void sobelEdgeDetectionAlg(const real16_T img[589824], real16_T thresh, unsigned char edgeImg[196608]) { static const real16_T hv[9] = { real16_T(1.0F), real16_T(0.0F), real16_T(-1.0F), real16_T(2.0F), real16_T(0.0F), real16_T(-2.0F), real16_T(1.0F), real16_T (0.0F), real16_T(-1.0F) }; static const real16_T hv1[9] = { real16_T(1.0F), real16_T(2.0F), real16_T(1.0F), real16_T(0.0F), real16_T(0.0F), real16_T(0.0F), real16_T(-1.0F), real16_T (-2.0F), real16_T(-1.0F) }; static real16_T h[196608]; static real16_T v[196608]; int k; if (!isInitialized_sobelEdgeDetectionAlg) { sobelEdgeDetectionAlg_initialize(); } // Finding horizontal and vertical gradients. coder::conv2MovingWindowSameCM(*(real16_T (*)[196608])&img[196608], hv, h); coder::conv2MovingWindowSameCM(*(real16_T (*)[196608])&img[196608], hv1, v); // Finding magnitude of the gradients. for (k = 0; k < 196608; k++) { real16_T b_h; real16_T h1; b_h = h[k]; h1 = v[k]; b_h = b_h * b_h + h1 * h1; h[k] = b_h; } for (k = 0; k < 196608; k++) { h[k] = sqrt_half(h[k]); } // Threshold the edges for (k = 0; k < 196608; k++) { edgeImg[k] = static_cast<unsigned char>((h[k] > thresh) * 240U); } } // // File trailer for sobelEdgeDetectionAlg.cpp // // [EOF] //
codegen
| coder.config
| half