
こんな悩みを解決します。
記事の内容
imageJの機能を使って輪郭を抽出する方法
記事の信頼性
この記事を書いている私は、ソフトウェア(画像処理)エンジニアとして自動車メーカーでC言語やPythonを使って製品開発をしています。
10年近くimageJを愛用していますので、imageJを活用したさまざまな画像処理の方法を皆さんにお伝えします。
輪郭抽出のことを、画像処理の分野ではエッジ検出といいます。
画像内の物体のエッジを見つけるための技術です。
エッジは画像内の輝度が大きく変化する領域から検出され、画像解析の前処理として使われたり、白線検出や外観検査装置で位置ずれを検出するため等、さまざまなアプリケーションで使われています。
この記事を読むことで、imageJの機能を使い、以下の画像のような大きなエッジを検出することができるようになります。
imageJで輪郭を抽出する方法
やり方は次の流れです。
処理の流れ
- ノイズを除去する
- 微分フィルタを使って勾配強度を計算する
- 二値化(閾値処理)で強いエッジを抽出する
- モルフォロジー演算でエッジを整形する
簡単に解説すると、
エッジを検出するのに邪魔になるノイズとかを先に消す
→画像から勾配の大きさを計算する
→勾配の小さいエッジは捨てる
→エッジを整形する
以上です。
ノイズを除去する
ノイズは画像解析に不要な情報なので、できるかぎり前段で除去しましょう。
ノイズ除去はガウシアンフィルタかメディアンフィルタを使います。
使い分けは以下のとおり。
ザラザラとした細かく弱いノイズを消したいとき
ガウシアンフィルタを使いましょう
注目画素に近いほど大きな重みがかかるので、エッジを残しつつノイズを低減できます。
ごま塩ノイズのように強いノイズを消したいとき
メディアンフィルタを使いましょう
周辺画素の中央値を注目画素に置き換えるので、エッジのボケを抑えつつも強いノイズを低減できます。
この記事で使用する画像は、白黒の小さなゴミが画像解析の邪魔になるので、メディアンフィルタを適用します。
imageJの使い方は次の通りです。
Radiusは適用するフィルタの半径[pix]です。ノイズの密度に合わせて調整してください。
微分フィルタを使って勾配強度を計算する
ノイズ除去のあとは、画像からエッジを抽出します。
imageJでは、エッジ検出処理としてsobelフィルタが実装されていますので、活用していきます。
エッジ検出処理(sobelフィルタ)をすると、エッジ画像がつくられます。
この画像は、ピクセルごとに0-255の勾配強度が入っており、値が大きいほど勾配が強い(輝度変化が大きい)領域といえます。
imageJの使い方は次の通りです。
閾値など調整の余地はないので、簡単です。
二値化(閾値処理)で強いエッジを抽出する
エッジ検出処理によって、各ピクセルの勾配強度が求まりました。
この記事では、大きなエッジを検出することが目的なので、勾配強度の低いピクセルを除去していきます。
そのやり方は、二値化(閾値処理)です。
検出したいエッジと検出したくないエッジを、なるべく綺麗に分けられる勾配強度の値を決めます。(=閾値決め)
以下の図は、エッジ画像のヒストグラムに対して、検出したくない強度の範囲(下限閾値と上限閾値)を決めます。
ポイントは、検出したいエッジを消さないギリギリの閾値を設定してください。
設定する場所はここです。
モルフォロジー演算でエッジを整形する
最後に、エッジを整形します。
モルフォロジー演算を使いますので、使い方を簡単に解説します。
モルフォロジー演算とは
- 収縮(Erosion)
境界を侵食するイメージ→小さなエッジは消える - 膨張(Dilation)
境界を膨らますイメージ→エッジは太く強調 - オープニング(Opening)
収縮のあとに膨張する処理→ノイズ除去に有効 - クロージング(Closing)
膨張のあとに収縮する処理→エッジの中の穴を埋めるのに有効
モルフォロジー演算を使って、このようにエッジを整形してください。
設定する場所はここです。