Basierend auf einer Lösung, die ich unter How to define the markers for Watershed in OpenCV? gelesen habe, versuche ich anzuwenden Wasserscheide grayscale data (not very visible but not all black), extrahiert aus netcdf (Niederschlagsdaten).Wie Watershed auf Graustufenbild mit Opencv und Python anwenden?
Hier ist ein black and white version of the data (Schwelle bei 0), so dass Sie einfacher sehen können, und die markers Ich möchte verwenden, um die verschiedenen Becken zu definieren (im Grunde nur eine Schwelle, wo Niederschlag stärker ist).
Der Code, den ich läuft wie folgt:
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
Ich habe folgende Fehler für den Wendepunkt in der opencv-2.4.11/modules/imgproc/src/segmentation.cpp:
error: (-210) Only 8-bit, 3-channel input images are supported in function cvWatershed
Für was ich im Internet gesehen habe, ist dies aufgrund der Tatsache, dass die Graustufen Daten ein 2D-Bild und Wasserscheide ein 3D-Bild (von RGB) benötigt. In der Tat habe ich das Skript mit einem JPG-Bild ausprobiert und ich habe perfekt gearbeitet. Dieses Problem wird here erwähnt, aber die gegebene Antwort wurde schließlich zurückgewiesen. Und ich kann keinen kürzlichen Link finden, der die Frage beantwortet.
Um zu versuchen, dieses Problem zu lösen, habe ich ein 3D-Array aus dem 2D-new_data:
new_data = new_data[..., np.newaxis]
test=np.append(new_data, new_data, axis=2)
test=np.append(new_data, test, axis=2)
Aber, wie erwartet, es hat das Problem (gleiche Fehlermeldung) nicht lösen.
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,))
Aber die Größe des test_data erstellt unterscheidet sich von ma_data (+ ich nicht loswerden der Etiketten bekommen können): RGB-Daten zu erhalten
Ich habe auch versucht, die Handlung von matplotlib zu speichern.
Also, ich bin hier fest. Im Idealfall möchte ich das Wassereinzugsgebiet direkt auf das 2D-Graustufenbild anwenden und/oder die Anzahl der Vorgänge so weit wie möglich begrenzen.
[Werfen Sie einen Blick] (https://www.pyimagesearch.com/2015/11/02/watershed-opencv/) – Link