Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于OpenCV的距离图像分水岭变换_Python_Opencv_Distance_Image Segmentation_Watershed - Fatal编程技术网

Python 基于OpenCV的距离图像分水岭变换

Python 基于OpenCV的距离图像分水岭变换,python,opencv,distance,image-segmentation,watershed,Python,Opencv,Distance,Image Segmentation,Watershed,在Matlab中,我们可以对距离变换执行分水岭变换,以分离两个接触对象: 上面的第一个图像是我们希望分离的带有触摸对象的图像。第二个图像是它的距离变换 因此,如果黑白图像被称为img,在Matlab中,我们可以: D = -bwdist(~img); L = watershed(D); 现在要对openCV执行相同的操作: OpenCV具有基于标记的分水岭分割功能。似乎要使用openCV执行分离两个触摸对象的相同任务,需要为两个对象和背景提供标记 img = np.zeros((400,

在Matlab中,我们可以对距离变换执行分水岭变换,以分离两个接触对象:

上面的第一个图像是我们希望分离的带有触摸对象的图像。第二个图像是它的距离变换

因此,如果黑白图像被称为
img
,在Matlab中,我们可以:

D = -bwdist(~img); 
L = watershed(D);
现在要对openCV执行相同的操作: OpenCV具有基于标记的分水岭分割功能。似乎要使用openCV执行分离两个触摸对象的相同任务,需要为两个对象和背景提供标记

img = np.zeros((400, 400), np.uint8)
cv2.circle(img, (150, 150), 100, 255, -1)
cv2.circle(img, (250, 250), 100, 255, -1)

dist = cv2.distanceTransform(img, cv2.cv.CV_DIST_L2, cv2.cv.CV_DIST_MASK_PRECISE)
dist3 = np.zeros((dist.shape[0], dist.shape[1], 3), dtype = np.uint8)
dist3[:, :, 0] = dist
dist3[:, :, 1] = dist
dist3[:, :, 2] = dist

markers = np.zeros(img.shape, np.int32)
markers[150,150] = 1 # seed for circle one
markers[250, 250] = 2 # seed for circle two
markers[50,50] =  3 # seeds for background

cv2.watershed(dist3, markers)
在下图中,您可以看到执行分水岭后的
标记
图像。原始黑白
img
以红色叠加在其上。 问题在于生成的
标记
图像中的对象边界与原始图像不同。如何确保对象边界保持不变


您将了解分水岭功能中的实际情况。 它开始用它的种子泛滥,并把它们的邻居的坐标和梯度放在一个优先队列中

如你所知,当你在img上应用距离变换时,圆的梯度变为0或1,但背景总是0

所以,现在你有3个种子,洪水开始工作:背景(种子3),邻居(种子1),邻居(种子2),他们可以轮流工作,直到种子1或种子2满足他们的梯度1;然后就可以继续工作了

当种子3遇到圆的边界时,它的梯度变为1,现在它们可以依次工作

因此,如果要确保对象边界保持不变,最好在种子3与圆边界相交时增加渐变

就像:

dist = cv2.distanceTransform(img, cv2.cv.CV_DIST_L2, cv2.cv.CV_DIST_MASK_PRECISE)
dist[dist > 0] += 2.0
这是你的电话号码

…其中存在一些问题(当队列中的所有渐变都为1时,哪个将首先弹出,哪个将第二次弹出)