LoginSignup
13
10

More than 3 years have passed since last update.

OpenCVのスーパーピクセル

Last updated at Posted at 2020-08-18

OpenCVのスーパーピクセルについて紹介がなかったので書こうかと思いました。
説明は使い方をサンプルで示す方法で記述していきます。
アルゴリズムの説明、関数インターフェイスについては、ググってお調べただけましたら
幸いです。
ただ、コンストラクタの引数については記載しないと、まるっきりとりつきが無い感じが
しましたので記載しました。

スーパーピクセルについて

領域分割とかセグメンテーションアルゴリズムのことで、最初見たとき
その認識は無かったですが、資料を読んで分かった次第です。
OpenCVに実装されているスーパーピクセル機能は3種類あります。

  • LSC (Linear Spectral Clustering)

  • SEEDS(Superpixels Extracted via Energy-Driven Sampling)

  • SLIC(Simple Linear Iterative Clustering)

    さらに、3種類のアルゴリズムSLIC, SLICO, MSLICを引数に設定します。


この3種類にサンプルプログラムを作成し実行させ、セグメンテーションを
実施してみます。

構成

サンプルプログラムの構造

サンプルプログラムの基本的な流れとして、下記のようにします。

  1. 画像読込む
  2. 入力画像の色空間をBGRからHSVに変換する。
  3. スーパーピクセル・インスタンスを生成。cv2.ximgproc.createSuperpixel***()
  4. 計算パラメータの設定。iterate(), enforceLabelConnectivity()
  5. セグメンテーションの境界を取得。getLabelContourMask()
  6. 境界線を読み込んだカラー画像に反映。
  7. 表示

入力画像について

F-15_400x533.jpg
入力画像は、上記のF-15の画像を使います。
写真出典は防衛省Webサイト 自衛隊写真館の画像で、それを400x533に縮小しています。

スーパーピクセルLSC

サンプルプログラム

lsc.py
import cv2
import numpy as np

def main():
    image = cv2.imread('F-15_400x533.jpg')

    # BGR-HSV変換
    converted = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL)

    # パラメータ
    region_size = 20
    ruler = 0.1
    min_element_size = 10
    num_iterations = 4

    # LSCインスタンス生成
    slc = cv2.ximgproc.createSuperpixelLSC(converted, region_size,float(ruler))
    slc.iterate(num_iterations)
    slc.enforceLabelConnectivity(min_element_size)

    # スーパーピクセルセグメンテーションの境界を取得
    contour_mask = slc.getLabelContourMask(False)
    image[0 < contour_mask] = (0, 255, 255)
    cv2.imshow('LSC result', image)
    cv2.waitKey(0)

if __name__ == '__main__':
    main()

cv2.ximgproc.createSuperpixelLSC()関数で、パラメータを設定し、LSCインスタンスを
生成、計算パラメータを設定します。
境界線情報を取得し、それを読み込んだ画像に反映して表示します。

スーパーピクセルLSCのインスタンス生成

retval = cv.ximgproc.createSuperpixelLSC(image[, region_size[, ruler]]])
  image - セグメント化するイメージ
  region_size - スーパーピクセルの平均サイズ
  ruler - スーパーピクセル平滑係数
  retval - 返却値:LSCインスタンス

スーパーピクセルLSC 実行結果

LSC_result.jpg

スーパーピクセルSEEDS

サンプルプログラム

seeds.py
import cv2
import numpy as np

def main():
    image = cv2.imread('F-15_400x533.jpg')

    # パラメータ
    height, width, channels= image.shape[:3]
    num_iterations = 5
    prior = 2
    double_step = True
    num_superpixels = 700
    num_levels = 4
    num_histogram_bins = 5

    # スーパーピクセルSEEDSの生成
    seeds = cv2.ximgproc.createSuperpixelSEEDS(width, height, channels, num_superpixels,
            num_levels, prior, num_histogram_bins, double_step)

    converted = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL)

    # 画像のスーパーピクセルSEEDSを計算
    seeds.iterate(converted, num_iterations)

    # スーパーピクセルセグメンテーションの境界を取得
    contour_mask = seeds.getLabelContourMask(False)
    result = image.copy()
    result[0 < contour_mask] = (0, 255, 255)

    # 画像表示
    cv2.imshow('SEEDS result', result)
    cv2.waitKey(0)

if __name__ == '__main__':
    main()

cv2.ximgproc.createSuperpixelSEEDS()でインスタンスを生成しますが、この段階では
入力画像を設定しません。iterate()メソッドに入力画像を設定します。

スーパーピクセルSEEDSのインスタンス生成

retval = cv.ximgproc.createSuperpixelSEEDS(image_width, image_height, image_channels,
              num_superpixels, num_levels[, prior[, histogram_bins[, double_step]]] )
  image_width - 画像幅
  image_height - 画像高さ
  image_channels - 画像チャンネル
  num_superpixels - 必要なスーパーピクセルセグメンテーション数
  num_levels - ブロックレベルの数
  prior - 平滑オプション(0~5) 3x3平滑化を有効にします。
  histogram_bins - ヒストグラムビンの数
  double_step - Trueの場合、精度向上の為、各ブロックレベルをダブルで実施
  retval - 返却値:スーパーピクセルSEEDSのインスタンス

スーパーピクセルSEEDS 実行結果

SEEDS_result.jpg

スーパーピクセルSLIC

サンプルプログラム

slic.py
import cv2
import numpy as np

def main():
    image = cv2.imread('F-15_400x533.jpg')

    # パラメータ
    algorithms = [
        ('SLIC', cv2.ximgproc.SLIC), 
        ('SLICO', cv2.ximgproc.SLICO), 
        ('MSLIC', cv2.ximgproc.MSLIC) ]
    region_size = 20
    ruler = 30
    min_element_size = 10
    num_iterations = 4

    # BGR-HSV変換
    converted = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL)
    for alg in algorithms:
        slic = cv2.ximgproc.createSuperpixelSLIC(converted, alg[1], region_size,float(ruler))
        slic.iterate(num_iterations)
        slic.enforceLabelConnectivity(min_element_size)
        result = image.copy()

        # スーパーピクセルセグメンテーションの境界を取得
        contour_mask = slic.getLabelContourMask(False)
        result[0 < contour_mask] = (0, 255, 255)
        cv2.imshow('SLIC ('+ alg[0] + ') result', result)
        cv2.imwrite('images/SLIC_'+alg[0]+'_result.jpg', result)
        cv2.waitKey(0)

if __name__ == '__main__':
    main()

基本的身はスーパーピクセルLSCと同じです。
3種類のアルゴリズムを実行しているため、ループさせています。

スーパーピクセルSLICのインスタンス生成

retval = cv.ximgproc.createSuperpixelSLIC(image[,algorithm[,region_size[,ruler]]])
  image - セグメント化するイメージ
  algorithm - アルゴリズム(SLIC, SLICO, MSLIC)
  region_size - スーパーピクセルの平均サイズ
  ruler - スーパーピクセル平滑係数
  retval - 返却値:ーパーピクセルSLICインスタンス

スーパーピクセルSLIC SLICアルゴリズム 実行結果

SLIC_SLIC_result.jpg

スーパーピクセルSLIC SLICOアルゴリズム 実行結果

SLIC_SLICO_result.jpg

スーパーピクセルSLIC MSLICアルゴリズム 実行結果

SLIC_MSLIC_result.jpg

終わりに

実行結果についてはコメントを書きませんでした。画像を見てご判断下さい。
用途、対象画像等々条件でアルゴリズムを選択することになるかともいます。
最初、規定値で行おうとも考えましたが、分割が細かくなってしまい、良く見えなかったので
見た目の分割サイズが同じようになるように、パラメータを調整してあります。
パラメータは、同じ名前であっても、アルゴリズムが異なるため動きが違ってきます。
さて、セグメンテーションについてはK-Meansなど他にも、いろいろあるかと思いますが、
そのうちの一つとして紹介しました。
ご覧いただきありがとうございました。

実行環境

Windows10 Anaconda
Python 3.8.5
OpenCV 4.0.1

参考

Emotion Explorer - OpenCVのスーパーピクセル(3) - SuperpixelLSCクラスを試す。
Emotion Explorer - OpenCVのスーパーピクセル(2) - SuperpixelSLICクラスを試す。
Emotion Explorer - OpenCVのスーパーピクセル(1) - SuperpixelSEEDSクラスを試す。
Emotion Explorer - Watershedアルゴリズムの領域分割
docs.opencv.org - Superpixels Extended Image Processing
docs.opencv.org - cv::ximgproc::SuperpixelSEEDS Class Reference
docs.opencv.org - cv::ximgproc::SuperpixelSLIC Class Reference
docs.opencv.org - cv::ximgproc::SuperpixelLSC Class Reference

写真引用

防衛省Webサイト 自衛隊写真館を400x533に縮小して画像処理サンプルとして使用

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10