Prewitt演算子は画像処理、特にエッジ検出アルゴリズムで使用されます。技術的には、これは離散微分演算子であり、画像強度関数の勾配の近似値を計算し、画像の各ポイントで Prewitt 演算子の結果は対応する勾配ベクトルまたはこのベクトルのノルムのいずれかになります。Prewitt 演算子は、画像を水平方向と垂直方向に小さく分離可能な整数値のフィルターで畳み込むことに基づいているため、 Sobel 演算子や Kayyali演算子[1]のように計算コストが比較的低くなります。一方、Prewitt 演算子によって生成される勾配近似値は比較的粗く、特に画像内の高周波変動に対しては粗くなります。Prewitt 演算子は、Judith MS Prewitt によって開発されました。[2]
簡略化された説明
簡単に言えば、演算子は各ポイントでの画像の強度の勾配を計算し、明るい部分から暗い部分への最大の増加方向とその方向の変化率を示します。したがって、結果は、そのポイントで画像がどの程度「急激に」または「滑らかに」変化するかを示し、したがって、画像のその部分がエッジを表す可能性と、そのエッジの方向がどの程度になるかを示します。実際には、大きさ (エッジの可能性) の計算の方が方向の計算よりも信頼性が高く、解釈も簡単です。
数学的には、2 変数関数 (ここでは画像強度関数) の勾配は、各画像ポイントで、水平方向と垂直方向の導関数によって与えられる成分を持つ2Dベクトルです。各画像ポイントで、勾配ベクトルは強度が最大限に増加する方向を指し、勾配ベクトルの長さはその方向の変化率に対応します。これは、一定の画像強度領域にある画像ポイントでの Prewitt 演算子の結果がゼロ ベクトルであり、エッジ上のポイントではエッジを横切って暗い値から明るい値を指すベクトルであることを意味します。
処方
数学的には、演算子は 2 つの 3×3 カーネルを使用して、元の画像と畳み込み、導関数の近似値 (1 つは水平方向の変化用、もう 1 つは垂直方向の変化用) を計算します。 をソース画像として定義し、 とを各ポイントで水平方向と垂直方向の導関数の近似値を含む 2 つの画像とすると、後者は次のように計算されます。
ここで は2 次元畳み込み演算を表します。
プレウィットカーネルは平均化カーネルと微分カーネルの積として分解できるため、平滑化を伴う勾配を計算します。したがって、それは分離可能なフィルタです。たとえば、次のように記述できます 。
ここで、 x座標は「左」方向に増加するものとして定義され、y座標は「上」方向に増加するものとして定義されます。画像の各ポイントで、結果として得られる勾配近似値を組み合わせて、勾配の大きさを求めることができます。
この情報を使用して、勾配の方向を計算することもできます。
たとえば、右側が暗い垂直エッジの場合 、 Θは 0 になります。
例
コード例
% MATLAB コード | ゼロから学ぶ Prewitt 演算子
% 入力イメージの読み取り
input_image = imread ( '[入力イメージファイル名].[ファイル形式]' );
% 入力画像の表示
input_image = uint8 ( input_image ); figure , imshow ( input_image ); title ( '入力画像' );
% トゥルーカラー RGB 画像をグレースケール画像に変換します。
input_image = rgb2gray ( input_image );
% 画像をdoubleに変換します
input_image = double ( input_image );
% フィルターされたイメージ行列をゼロで事前割り当てします。filtered_image = zeros ( size ( input_image ));
% プレウィット演算子マスク
Mx = [ - 1 0 1 ; - 1 0 1 ; - 1 0 1 ]; My = [ - 1 - 1 - 1 ; 0 0 0 ; 1 1 1] ;
% エッジ検出プロセス
% i = 1 かつ j = 1 の場合、filtered_image ピクセル
% の位置は、filtered_image(2, 2) になります
% マスクは 3x3 なので、
filtered_image(size(input_image, 1) - 2
%、size(input_image, 2) - 2)まで移動する必要があります
% したがって、境界は考慮しません。
for i = 1 : size ( input_image , 1 ) - 2 for j = 1 : size ( input_image , 2 ) - 2
% 勾配近似
Gx = sum ( sum ( Mx .* input_image ( i : i + 2 , j : j + 2 ))); Gy = sum ( sum ( My .* input_image ( i : i + 2 , j : j + 2 ))); % ベクトルの大きさを計算filtered_image ( i + 1 , j + 1 ) = sqrt ( Gx .^ 2 + Gy .^ 2 ); end end
% フィルタリングされた画像を表示する
filtered_image = uint8 ( filtered_image ); figure , imshow ( filtered_image ); title ( 'フィルタリングされた画像' );
% しきい値を定義します
。thresholdValue = 100 ; % [0 255] の間で変化します。output_image = max ( filtered_image , thresholdValue ); output_image ( output_image == round ( thresholdValue )) = 0 ;
% 出力画像の表示
output_image = im2bw ( output_image ); figure , imshow ( output_image ); title ( 'エッジ検出された画像' );
参照
参考文献
[1]
- ^ Geeks for geeks (2023 年 7 月 28 日)。「MATLAB – ゼロから Prewitt 演算子を使用して画像エッジ検出」
