2017-11-14 14 views
1

How to define the markers for Watershed in OpenCV?で読んだ解決策に基づいて、netcdf(降水量データ)から抽出したgrayscale data (not very visible but not all black)に流域を適用しようとしています。opencvとpythonを使ってグレースケールイメージに流域を適用するには?

より簡単に見ることができるようにblack and white version of the data(スレッショルドは0)であり、別のベインス(基本的には降水量がより激しい別のスレッショルド)を定義するために使用したいmarkersです。次のように

私が実行しているコードは次のとおりです。

import os,sys,string 
from netCDF4 import Dataset as nc 
import cv2 
import numpy as np 
import matplotlib.pyplot as mpl 
import scipy.ndimage as ndimage 
import scipy.spatial as spatial 
from skimage import filter 
from skimage.morphology import watershed 
from scipy import ndimage 

filename=["Cmorph-1999_01_03.nc"] 

nc_data=nc(filename[0]) 
data=nc_data.variables["CMORPH"][23,0:250,250:750] 
new_data=np.flipud(data) 
ma_data=np.ma.masked_where(new_data<=0,new_data) 
ma_conv=np.ma.masked_where(new_data<=2,new_data) 

## Borders 
tmp_data=ma_data.filled(0) 
tmp_data[np.where(tmp_data!=0)]=255 
bw_data=tmp_data.astype(np.uint8) 
border = cv2.dilate(bw_data, None, iterations=5) 
border = border - cv2.erode(border, None) 

## Markers 
tmp_conv=ma_conv.filled(0) 
tmp_conv[np.where(tmp_conv!=0)]=255 
bw_conv=tmp_conv.astype(np.uint8) 
lbl, ncc = ndimage.label(bw_conv) 
lbl = lbl * (255/ncc) 
lbl[border == 255] = 255 
lbl = lbl.astype(np.int32) 

## Apply watershed 
cv2.watershed(ma_data, lbl) 

lbl[lbl == -1] = 0 
lbl = lbl.astype(np.uint8) 
result = 255 - lbl 

私は/ segmentation.cpp OpenCVの-2.4.11 /モジュール/ imgproc/srcの中流域のために次のエラーがあります。

error: (-210) Only 8-bit, 3-channel input images are supported in function cvWatershed 

インターネットで見たものは、グレースケールデータが2D画像であり、流域に3D画像(RGBから)が必要なためです。確かに、私はjpgイメージでスクリプトを試して、私は完全に働いた。 この問題は、hereに記載されていますが、回答は最終的には拒否されました。そして私はその質問に答える最近のリンクを見つけることができません。この問題を解決しようとする

は、私は、2D NEW_DATAから3D配列作成:

new_data = new_data[..., np.newaxis] 
test=np.append(new_data, new_data, axis=2) 
test=np.append(new_data, test, axis=2) 

をしかし、予想通り、それは(同じエラーメッセージを)問題が解決しませんでした。

私はまた、RGBデータを取得するためにmatplotlibのからプロットを保存しようとしました:

fig = mpl.figure() 
fig.add_subplot(111) 
fig.tight_layout(pad=0) 
mpl.contourf(ma_data,levels=np.arange(0,255.1,0.1)) 
fig.canvas.draw() 
test_data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='') 
test_data = test_data.reshape(fig.canvas.get_width_height()[::-1] + (3,)) 

しかし、作成したTEST_DATAの大きさは、(+ Iラベルを取り除くことはできません)ma_dataは異なっています。

だから、私はここで立ち往生しています。理想的には、2Dグレースケール画像に直接流域を適用したり、操作の数を可能な限り制限したいと考えています。

+0

(https://www.pyimagesearch.com/2015/11/02/watershed-opencv/)について – Link

答えて

1

にあなたのイメージを渡す前に

cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)

を使用してBGRの色空間に自分の画像フラムグレーを変更してみてくださいすることができ、実際にフォーマットに問題がありました私は流域機能を紹介していました。 try_data=ma_data.astype(np.uint8)を実行すると、エラーメッセージが削除されました。ここで

が動作するようになりました最小限の例です。

import os,sys 
from netCDF4 import Dataset as nc 
import cv2 
import numpy as np 
import scipy.ndimage as ndimage 
from skimage.morphology import watershed 
from scipy import ndimage 

basename="/home/dcop696/Data/CMORPH/precip/CMORPH_V1.0/CRT/8km-30min/1999/" 
filename=["Cmorph-1999_01_03.nc"] 
fileslm=["/home/dcop696/Data/LSM/Cmorph_slm_8km.nc"] 

nc_data=nc(basename+filename[0]) 
data=nc_data.variables["CMORPH"][23,0:250,250:750] 
new_data=np.flipud(data) 
ma_data=np.ma.masked_where(new_data<=0,new_data) 
try_data=ma_data.astype(np.uint8) 

## Building threshold 
tmp_data=ma_data.filled(0) 
tmp_data[np.where(tmp_data!=0)]=255 
bw_data=tmp_data.astype(np.uint8) 

## Building markers 
ma_conv=np.ma.masked_where(new_data<=2,new_data) 
tmp_conv=ma_conv.filled(0) 
tmp_conv[np.where(tmp_conv!=0)]=255 
bw_conv=tmp_conv.astype(np.uint8) 
markers = ndimage.label(bw_conv)[0] 

## Watershed 
labels = watershed(-try_data, markers, mask=bw_data) 
0

あなたはyapws87述べたように、流域アルゴリズム

+0

感謝を[見てください]提案していますが、試しに2Dから3D配列を作成するのと同じ効果があります(テスト変数が作成されました)。これは、RGBに戻るための十分な情報がないためかもしれません。 – dcoppin

+0

RGBに変えるためにもっと多くの情報を必要とせず、各RGBチャンネルに値を複製するだけです。私の推測では、あなたが流域機能に提示している形式は適切ではありません。 – yapws87

+0

あなたの推測は正しかった。流域の第一引数は正しい形式ではなかった。エラーは、グレースケール画像のディメンションとは関係ありませんでした。 – dcoppin

関連する問題