画像分割のためのOpenCVの - Pythonの分水嶺アルゴリズム

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/wsp_1138886114/article/details/100115179

I.はじめに

類似点に位置し、グレー値ピクセルに空間を塞ぐよう分水嶺アルゴリズムは相互に接続されている、今重要な基準として画素間の類似度に近づくであろう画像領域分割方法、分割プロセスであります閉じたプロファイルを構成し、閉じられた流域は、アルゴリズムの重要な特徴です。
そのような閾値は、エッジ検出等のような他の画像セグメンテーション方法は、いかなる統一がなく、互いに互いに独立したピクセル間の空間的関係における画素の閉じた類似の概念とはみなされないであろう。分水界アルゴリズムは、複数の画像の人間の目の印象に沿って、他の分割方法よりも思想です。
ここに画像を挿入説明
任意のグレースケール画像が表面地質として見ることができ、局所的なピークは、輝度が低い谷高輝度です。水が立ち上がっ異なる色(ラベル)内の水の各孤立谷(極小値)に、周囲のピーク(勾配)によると、谷は、異なる色で異なる合併を開始します。これを回避するには、次のことができますすべてのピークが水没されるまでマージする場所での水の障壁を構築します。あなたは、セグメンテーション結果を作成する障害が、この原理は流域ですが、ノイズ、または他の画像上の誤差があるので、この方法では、過度の分割されます。だから、OpenCVのは、あなたがないもの、ポイントをマージすることが何であるかを指定することができ、これはインタラクティブな画像分割であるマスクに基づいて流域のアルゴリズムを実装して、我々はしなければならない異なるラベルを与えることです。我々は、バックグラウンドまたは非標的プラス別の色を知っているため、見込み客をターゲットや色でタグ付けすることを知って、そして最終的に領域が続い流域アルゴリズムを使用して0をマークされているかわかりません。

二、cv2.distanceTransform(SRC、distanceType、maskSize)

距離の基本的な意味変換は、すなわちピクセルのゼロ点の最も一般的な変換アルゴリズムは、連続エッチング処理、エッチング処理によって実現されるから最短距離、ゼロに最も近い非ゼロ画素に画像ピクセルから計算されます。完全に腐食されているすべての前景ピクセルを止めます。このような腐食は、順序に従って、我々は中央前面にそれぞれの前景ピクセル距離聖歌Ⅵピクセルを取得します。各画素の距離値は、異なるグレースケール値に設定されています。これは、二値画像からの変換を完了します

パラメータ:

distanceType -距離の種類:cv2.DIST_L1cv2.DIST_L2cv2.DIST_C

maskSize - 距離変換マスクサイズ:3.5の値またはCV_DIST_MASK_PRECISE(後者のオプションは、最初の関数によって支持されています)。距離CV_DIST_L1又はCV_DIST_Cタイプパラメータが3に強制される場合。

cv2.distanceTransformWithLabels()追加のパラメータ

labels - ラベルのオプション出力2次元アレイ(離散ボロノイ図):それは同じ型CV_32SC1、サイズおよびSrcあります

labelType-配列型タグの構築:
それがある場合にDIST_LABEL_CCOMPは、SRC(最も近い非ゼロ画素に接続された全ての成分)のそれぞれの連結成分は、同じラベルが割り当てられます。
もしそうであればDIST_LABEL_PIXEL、各ピクセルがゼロ(およびそのすべての最寄りの非ゼロピクセル)は、独自のラベルを取得します。

第三に、マーカーに基づく流域セグメンテーション機能

img = np.zeros((400, 400), np.uint8)
cv2.circle(img, (150, 150), 100, 255, -1)
cv2.circle(img, (250, 250), 100, 255, -1)

dist = cv2.distanceTransform(img, cv2.cv.CV_DIST_L2, cv2.cv.CV_DIST_MASK_PRECISE)
dist3 = np.zeros((dist.shape[0], dist.shape[1], 3), dtype = np.uint8)
dist3[:, :, 0] = dist
dist3[:, :, 1] = dist
dist3[:, :, 2] = dist

markers = np.zeros(img.shape, np.int32)
markers[150,150] = 1  # seed for circle one
markers[250, 250] = 2 # seed for circle two
markers[50,50] =  3   # seeds for background

cv2.watershed(dist3, markers)

第四に、サンプル・コード

import numpy as np
import cv2


def watershed(imgpath):
    img = cv2.imread(imgpath)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret0, thresh0 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

    kernel = np.ones((3,3),np.uint8)
    opening = cv2.morphologyEx(thresh0,cv2.MORPH_OPEN,kernel, iterations = 2)

    # 确定背景区域
    sure_bg = cv2.dilate(opening,kernel,iterations=3)

    # 确定前景区域
    dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
    ret1, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

    # 查找未知区域
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg,sure_fg)

    # 标记标签
    ret2, markers1 = cv2.connectedComponents(sure_fg)
    markers = markers1+1
    markers[unknown==255] = 0

    markers3 = cv2.watershed(img,markers)
    img[markers3 == -1] = [0,255,0]
    return thresh0,sure_bg,sure_fg,img

if __name__ == '__main__':
    imgpath = './gggg/fenshuiling.png'
    thresh0, sure_bg, sure_fg, img = watershed(imgpath)

    cv2.imshow('thresh0',thresh0)
    cv2.imshow('sure_bg', sure_bg)
    cv2.imshow('sure_fg', sure_fg)
    cv2.imshow('result_img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

ここに画像を挿入説明

おすすめ

転載: blog.csdn.net/wsp_1138886114/article/details/100115179