OpenCVで用意されている平滑化処理について

OpenCVで用意されている平滑化処理についてプログラミング
ゆうすけ
ゆうすけ

OpenCVの平滑化処理ってどれを使えば良いんですか?

資格マフィア
資格マフィア

OpenCVでは平滑化処理として4種類用意されている。
それぞれ特徴のある「ぼかし」を可能にするぞ。

 

✔️ 本記事のテーマ

 OpenCVの平滑化処理について

 

✔️ 読者さんへの前置きメッセージ

本記事は「OpenCVの平滑化処理の特徴や違い」について書いています。

 

この記事を読むことで
cv2.blur / GaussianBlur / GaussianBlur / bilateralFilter の違い
について理解できます。

 

画像処理における平滑化とは、簡単いうと画像をぼかすことです。

画像をぼかすことで特徴量やエッジを調整することができるため、
前処理として使用されることが多いです。

 

ただし、平滑化についてOpenCVでは4種類の処理が用意されています。

それぞれ特徴があり、処理結果も当然違ってきます。
この記事では、これらの4種類の平滑化処理について解説していきます。

 

それでは、解説していきましょう。

 

OpenCV の平滑化とは?

OpenCV の平滑化とは?

OpenCVの平滑化とは、画像をぼかすことです。

英語で「smoothing」というように、ぼかすことで滑らかな画像にします。

opencvの平滑化処理後画像

上の画像のように、ぼかすことで特徴量やエッジを調整するというのが平滑化処理の目的です。

 

OpenCVではこの平滑化処理のために、4種類の処理が用意されています。

  • blur
  • Gaussian
  • median
  • bilateral

 

それぞれの特徴を解説しましょう。

 

OpenCVの一般的な平滑化(cv2.blur)

OpenCVの最も一般的な平滑化処理は blur フィルタによる平滑化です。

import cv2


img = cv2.imread("./sample.png")

img_blur = cv2.blur(src=img, ksize=(5, 5))
imgs = cv2.hconcat([img, img_blur])

cv2.imwrite('./sample_after.png', imgs)

opencvのblurフィルタによる平滑化

左に比べて、右の方が画像がぼけているのが分かります。

 

cv2.blur 関数2つの引数を取ります。

 

第1引数: src は cv2.imread 関数で読み込んだ画像データです。

参考記事:「OpenCVで画像を読み込む方法【Python】

 

第2引数: ksize はカーネルサイズです。

カーネルとは画像の1点に対して、周囲の領域をどれだけ含むかを表します。
この領域の単位でぼかし処理がかけられます。

 

試しに、この第2引数を少しずつ変えた画像を用意してみます。

img_1 = cv2.blur(img, (1, 1))
img_2 = cv2.blur(img, (5, 5))
img_3 = cv2.blur(img, (10, 10))

imgs = cv2.hconcat([img_1, img_2, img_3])

opencvの平滑化ksize変更画像

右になるほどぼかし処理が強くかかっていることが分かります。

 

OpenCVのGaussianフィルタによる平滑化

OpenCV で可能な他の平滑化処理も解説します。

 

Gaussianフィルタによる平滑化では、
カーネルの中心点からの距離に応じたぼかし処理が可能となります。

 

一般的な平滑化とGaussianフィルタによる平滑化の違いは以下の通りです。

  • 一般的な平滑化:カーネル内の画素を一定値で塗りつぶす
  • Gaussianフィルタ:中心に近いほど値が一番大きく、離れるにつれて値は小さくなる

 

import cv2


img = cv2.imread("./sample.png")

img_gauss = cv2.GaussianBlur(img, (3, 3), sigmaX=3)
imgs = cv2.hconcat([img, img_gauss])

cv2.imwrite('./sample_after.png', imgs)

opencvのGaussianフィルタによる平滑化画像

このようにカーネルの中心(≠画像の中心)のぼかしを弱めることで、
より特徴を残したぼかしが可能になります。

 

cv2.GaussianBlur 関数4つの引数を取ります。

 

第1引数、第2引数cv2.blur と同じです。

 

第3引数: sigmaXGaussianにおける横方向の標準偏差です。

この値が小さいとピークが高く、広がりは狭くなります。
逆に、値が大きいとピークが低く、広がりは広くなります。

つまり、値が小さいほど、よりカーネルの中心に強くぼかしがかかり、
逆に、値が大きいほど、より均一にカーネル全体にぼかしがかかるようになります。

 

第4引数: sigmaYGaussianにおける縦方向の標準偏差です。

ただし、第4引数 sigmaY省略可能です。
第4引数 sigmaY を省略した場合、Gaussianにおける縦方向の標準偏差には、第3引数 sigmaX で指定した値が自動的にセットされます。

 

OpenCVのmedianフィルタによる平滑化

medianフィルタによる平滑化では、
カーネル内に含まれる画素から「中央値」を取り出し、その値でカーネル全体を平滑化します。

 

一般的な平滑化とmedianフィルタによる平滑化の違いは以下の通りです。

  • 一般的な平滑化:平均値」で平滑化する
  • medianフィルタ:中央値」( = 画像中に存在する画素値 ) で平滑化する

 

この仕様からmedianフィルタによる平滑化は、
salt-and-pepper(点々が散りばめられた)ノイズ入りの画像に対して効果を発揮します。

import cv2


img = cv2.imread("./sample_noise.png")

img_median = cv2.medianBlur(src=img, ksize=3)
imgs = cv2.hconcat([img, img_median])

cv2.imwrite('./sample_after.png', imgs)

opencvのmedianフィルタによる平滑化画像

点々ノイズだけがきれいに除去できています。

 

cv2.medianBlur 関数2つの引数を取ります。

 

第1引数: src は cv2.blur と同じです。

 

第2引数: ksizeカーネルサイズです。
引数として意味合いは cv2.blur と同じですが、指定の仕方が少し異なります。

cv2.blur の場合は、カーネル領域を(縦, 横)のタプルで指定しますが、
cv2.medianBlur の場合は、カーネル領域の縦のみ指定します。
横は自動的に縦と同じものがセットされます。

すなわち、第2引数 ksize3 を指定した場合は、3 × 3 のカーネルを指定したことになります。

また、第2引数 ksize で指定できるのは奇数のみです。
カーネルサイズを偶数で指定すると error が発生します。

img_median = cv2.medianBlur(img, 3)

# cv2.error: OpenCV(4.4.0) /private/var/folders/nz/vv4_9tw56nv9k3tkvyszvwg80000gn/T/pip-req-build-gi6lxw0x/opencv/modules/imgproc/src/median_blur.dispatch.cpp:285: error: (-215:Assertion failed) (ksize % 2 == 1) && (_src0.dims() <= 2 ) in function 'medianBlur'

 

 

OpenCVのbilateralフィルタによる平滑化

bilateralフィルタによる平滑化では、エッジを残したまま平滑化することができます。
「bilateral」とは「両方を備えた」という意味です。

 

エッジ検出などの前処理として強力な効果を発揮します。

import cv2


img = cv2.imread("./img/sample.png")

img_bltrl = cv2.bilateralFilter(src=img, d=9, sigmaColor=75, sigmaSpace=75)
imgs = cv2.hconcat([img, img_bltrl])

cv2.imwrite('./sample_after.png', imgs)

opencvのbilateralフィルタによる平滑化画像

 

cv2. bilateralFilter 関数4つの引数を取ります。

第1引数: srccv2.blur と同じです。

 

第2引数: d対象となる画素をぼかすために使われる領域です。

この値が大きいほどぼかしが強くなります。

 

第3引数: sigmaColor色空間の標準偏差です。

この値が大きいほど、色がより異なるピクセル同士を混合して平滑化を実施します。

 

第4引数: sigmaSpace距離空間の標準偏差です。

これが大きいほど、より遠くのピクセル同士を混合して平滑化を実施します。

ただし、この引数は 第2引数 d が0以下の場合のみ計算に使用されます。

参考:公式ドキュメントより引用

When d>0, it specifies the neighborhood size regardless of sigmaSpace. Otherwise, d is proportional to sigmaSpace.

OpenCV: Image Filtering

 

なお、bilateralフィルタによる平滑化は強力ですが、処理速度が遅いという特徴があります。

 

画像処理プログラミングを独学で勉強するなら

画像処理プログラミングを独学で勉強するなら

画像から円を検出する方法について解説しました。

 

OpenCVは画像処理には欠かすことのできないライブラリです。

 

もし、OpenCVについて独学でスキルをつけるなら、以下の書籍がオススメです。

 

この書籍はOpenCVの基礎から応用までを
丁寧にかつ詳細に解説しています。

 

OpenCVのほぼ全てを網羅しているとも言えるほどの徹底ぶりなので、
関数のリファレンスとしても使用することができます。
本記事で解説した様々なフィルタによる平滑化処理についても掲載されています。

 

また、Pythonについて基礎から学ぶのであれば、オンラインスクールがオススメです。


オンラインスクールで学習すると、講義も分かりやすく、
サポート体制もしっかりしているので、これからPythonを学ぶ人にもオススメです。


オンラインで無料レッスンを体験することもできるので、
自分にあっているかどうかを確かめることができます。


オススメは以下の3つです。
どのスクールも無料体験が用意されているので、
契約前に自分に最適なスクールを探すことができるでしょう。

✔️オススメのプログラミングスクール ベスト3

これらのプログラミングスクールは全て無料の体験コースがあります。

 

「雰囲気だけでも知りたい」
「プログラミング学習の全体像を知りたい」
「スクールに入るかどうか迷っている」
という方はとりあえず無料カウンセリングを受けてみることをオススメします。

 

無料カウンセリングだけなら費用はかかりませんし、
スクールに通うにしろ、独学で学ぶにしろ、
カウンセリングで得ることができる情報には価値があります

 

プログラミングスクールについては「プログラミングスクールで失敗しないためには【オススメベスト3も紹介】」の記事でも紹介しています。


気になった方はぜひチェックしてみて下さい〜!

コメント

タイトルとURLをコピーしました