2017-11-14 31 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 

I이 OpenCV의-2.4.11/모듈/imgproc/SRC/segmentation.cpp의 유역에 대한 다음과 같은 오류 :

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

인터넷에서 본 것은 회색 음영 데이터가 2D 이미지이고 유역에 3D 이미지 (RGB)가 필요하기 때문입니다. 사실, jpg 이미지로 스크립트를 시도하고 완벽하게 작업했습니다. 이 문제는 언급 된 here이지만 주어진 답은 마침내 거부되었습니다. 그리고 나는 그 질문에 답하는 더 이상 최근 링크를 찾을 수 없다.

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

그러나, 예상대로,이 문제 (같은 오류 메시지)가 해결되지 않은 :

는이 문제를 해결하려고하기 위해, 나는 2 차원 new_data에서 3D 배열을 만들었습니다.

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의 크기는 ma_data (+ 내가 레이블을 제거 할 수없는) 다른 :

는 또한 RGB 데이터를 얻을하기 matplotlib에서 플롯을 저장했습니다.

그래서 여기 붙어 있습니다. 이상적으로는 2D 회색 음영 이미지에 직접 유역을 적용하거나 가능한 많은 작업 수를 제한하려고합니다.

+0

[보세요] (https://www.pyimagesearch.com/2015/11/02/watershed-opencv/) – Link

답변

1

에 이미지를 전달하기 전에

cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)

를 사용하여 BGR 색 공간에 이미지 FRAM 회색을 변경 시도 할 수 있습니다, 실제로 형식에 문제가 있었다 나는 유역 기능에 대해 발표하고있었습니다. 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