【发布时间】:2018-03-07 05:55:22
【问题描述】:
根据我在How to define the markers for Watershed in OpenCV? 阅读的解决方案,我正在尝试将分水岭应用于grayscale data (not very visible but not all black),从netcdf(降水数据)中提取。
这是一个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
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 图像的脚本,并且效果很好。 这个问题被提到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)
但是,正如预期的那样,它并没有解决问题(同样的错误消息)。
我还尝试从 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 灰度图像上应用分水岭和/或尽可能限制操作次数。
【问题讨论】:
标签: python opencv image-segmentation grayscale watershed