[学習メモ]OpenCVを用いた平滑化,二値化, 輪郭の抽出
画像の平滑化
いくつかの平滑化の仕方を紹介。
平均
カーネルの範囲内にある全画素の画素値の平均をとる。
- img:入力画像
- ax:カーネルの横幅
- ay:カーネルの縦幅
blur=cv2.blur(img,(ax,ay))
ガウシアンフィルタ
ホワイトノイズに適している。
単に平均をとるのではなくガウシアンフィルタは注目画素との距離に応じて重みを変えることができる。
- img:入力画像
- ax:カーネルの横幅(奇数)
- ay:カーネルの縦幅(奇数)
- sigma_x:横方向の標準偏差。0にした場合、カーネルサイズから自動的に計算される。
gau=cv2.GaussianBlur(img,(ax,ay),sigma_x)
中央値フィルタ
ごま塩ノイズに適している。
カーネル内の全画素の中央値を計算する。
- img:入力画像
- k:カーネルのサイズ(奇数)
median=cv2.medianBlur(img,k)
バイラテラルフィルタ
エッジを残したまま画像をぼかすことができる。
処理速度が遅くなるという欠点がある。
詳しくはpython+OpenCVでエッジを保存した平滑化(BilateralFilter, NLMeansFilter)
画像を平滑化する その1 - OpenCV for Android
- img:入力画像
- d:注目画素をぼかすために使われる領域。大きくなるとぼかしが強くなる。
- sigmaColor:色空間の標準偏差。これが大きいと、近くにある色的により遠くのピクセルが混ぜ合わせられる。
- sigmaSpace:距離空間の標準偏差。これが大きいと、より遠くのピクセル同士が影響しあいます。 dがゼロ以下の場合のみ計算に利用される。
bilate=cv2.bilateralFilter(img,d,sigmaColor,sigmaSpace)
画像の二値化
- img:入力画像(グレイスケール)
- thresh:しきい値
- maxval:しきい値以上の値を持つ値に対して割り当てる値を指定
- type:THRESH_BINARY_INVの場合しきい値よりも大きな値であれば0、それ以外はmaxvalの値にする。
typeの他の種類はOpenCV - 画像の2値化について参照
threshold.py
ret, th=cv2.threshold(img,thresh,maxval,type)
- ret:threshと同じ値
- th:二値化した画像
輪郭の抽出
輪郭の取得
- image:入力画像(二値画像のほうが精度がいい)
- mode:抽出モード
- method:近似手法
ret, th=cv2.threshold(img,thresh,maxval,type)
輪郭の取得
- image:入力画像(二値画像のほうが精度がいい)
- mode:抽出モード
- method:近似手法
第2引数は以下の引数で指定できる。
定数 | 意味 |
---|---|
cv2.RETR_LIST | 単純に輪郭を検出 |
cv2.RETR_EXTRNAL | 最も外側の輪郭を検出 |
cv2.RETR_CCOMP | 階層を考慮し2レベルの輪郭を検出 |
cv2.RETR_TREE | 全ての輪郭を検出し階層構造を保持 |
第3引数は以下の引数で指定できる。
定数 | 意味 |
---|---|
cv2.CHAIN_APPROX_NONE | 輪郭上のすべての点を保持する |
cv2.CHAIN_APPROX_SIMPLE | 冗長な点情報を削除して返す |
imges, contours, hierarchy=cv2.findContours(image,mode,method)
- images:輪郭画像
- contours:輪郭
- hierarchy:輪郭の階層情報
輪郭の描写
- img:入力画像
- contours:listとして保存されている輪郭
- ind:描画したい輪郭のインデックス(第2引数で与えた輪郭のlistから一つの輪郭だけを描画する時に描画したい輪郭の指定に使う.全輪郭を描画する時はー1を指定する)
- (r,g,b):輪郭を描画する色
- num:輪郭を描画する線の太さ
img = cv2.drawContours(img, contours, ind, (r,g,b),num)
まとめ
まとめるとこんな感じになる。
# -*- coding: utf-8 -*-
import cv2
import matplotlib.pyplot as plt
# 画像を読み込んでリサイズ --- (*1)
img = cv2.imread("flower.jpg")
img = cv2.resize(img, (300, 169))
# 色空間を二値化 --- (*2)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
im2 = cv2.threshold(gray, 140, 240, cv2.THRESH_BINARY_INV)[1]
# 輪郭を抽出 --- (*4)
imges, contours, hierarchy = cv2.findContours(im2,
cv2.RETR_LIST, #単純に輪郭を検出
cv2.CHAIN_APPROX_SIMPLE) #冗長な点情報を削除して返す
#全ての輪郭を赤で表示
img_co = cv2.drawContours(img, contours, -1, (225,0,0), 3)
plt.imshow(img_co)
Author And Source
この問題について([学習メモ]OpenCVを用いた平滑化,二値化, 輪郭の抽出), 我々は、より多くの情報をここで見つけました https://qiita.com/ankomotch/items/74884b0ca24b739159c0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .