1

基于我在如何在 OpenCV 中定义分水岭的标记?,我正在尝试将分水岭应用于灰度数据(不是很明显,但不是全黑),从 netcdf(降水数据)中提取。

这是数据的黑白版本(阈值为 0),以便您可以更轻松地查看,以及我想用来定义不同盆地的标记(基本上只是降水更强烈的另一个阈值)。

我正在运行的代码如下:

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

opencv-2.4.11/modules/imgproc/src/segmentation.cpp中的分水岭出现以下错误:

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

对于我在互联网上看到的,这是因为灰度数据是 2D 图像,而分水岭需要 3D 图像(来自 RGB)。确实,我尝试了带有 jpg 图像的脚本,并且效果很好。这里提到了这个问题,但给出的答案最终被拒绝了。而且我找不到任何更新的链接来回答这个问题。

为了解决这个问题,我从 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)

但是,正如预期的那样,它并没有解决问题(同样的错误信息)。

我还尝试从 matplotlib 中保存绘图以获取 RGB 数据:

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 不同(+ 我无法摆脱标签)。

所以,我被困在这里。理想情况下,我想直接在 2D 灰度图像上应用分水岭和/或尽可能限制操作的数量。

4

2 回答 2

1

正如 yapws87 所提到的,我向分水岭函数呈现的格式确实存在问题。这样做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)
于 2017-11-15T04:21:54.167 回答
0

您可以尝试使用将图像帧灰色更改为 BGR 颜色空间

cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)

在将图像传递给分水岭算法之前

于 2017-11-14T03:42:01.673 回答