Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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
如何在OpenCV中定义流域的标记?_Opencv_Image Processing_Computer Vision_Image Segmentation_Watershed - Fatal编程技术网

如何在OpenCV中定义流域的标记?

如何在OpenCV中定义流域的标记?,opencv,image-processing,computer-vision,image-segmentation,watershed,Opencv,Image Processing,Computer Vision,Image Segmentation,Watershed,我在用OpenCV为Android写文章。我正在使用标记控制的分水岭分割一幅与下面类似的图像,而不需要用户手动标记图像。我打算用区域最大值作为标记 minMaxLoc()会给我这个值,但是我怎么能把它限制在我感兴趣的blob上呢?我是否可以利用findContours()或cvBlob blob的结果来限制ROI并对每个blob应用最大值 我想在这里解释一个关于如何使用流域的简单代码。我正在使用OpenCV Python,但我希望您不会有任何理解困难 此代码中,我将使用分水岭作为前台背景提取的工

我在用OpenCV为Android写文章。我正在使用标记控制的分水岭分割一幅与下面类似的图像,而不需要用户手动标记图像。我打算用区域最大值作为标记

minMaxLoc()
会给我这个值,但是我怎么能把它限制在我感兴趣的blob上呢?我是否可以利用
findContours()
或cvBlob blob的结果来限制ROI并对每个blob应用最大值


我想在这里解释一个关于如何使用流域的简单代码。我正在使用OpenCV Python,但我希望您不会有任何理解困难

此代码中,我将使用分水岭作为<强>前台背景提取的工具。<强>(本示例是OpenCV食谱中的C++代码的Python对应)。这是一个理解分水岭的简单案例。除此之外,还可以使用“分水岭”来计算此图像中对象的数量。这将是该代码的一个稍微高级的版本

1首先,我们加载图像,将其转换为灰度,并使用合适的值设置阈值。我采用了大津的二值化方法,因此它会找到最佳阈值

import cv2
import numpy as np

img = cv2.imread('sofwatershed.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
以下是我得到的结果:

(即使这样的结果也不错,因为前景图像和背景图像之间的对比度很大)

2-现在我们必须创建标记标记是与原始图像大小相同的图像,即32SC1(32位有符号单通道)。

现在,在原始图像中会有一些区域,您可以简单地确定,这些区域属于前景。在标记图像中用255标记该区域。现在,您确定为背景的区域标记为128。您不确定的区域标记为0。这就是我们下一步要做的

A-前景区域:-我们已经得到了一个阈值图像,其中药丸是白色的。我们稍微腐蚀了它们,这样我们就可以确定剩下的区域属于前景

fg = cv2.erode(thresh,None,iterations = 2)
fg

marker = cv2.add(fg,bg)

B-背景区域:-这里我们放大阈值图像,以便缩小背景区域。但我们确信剩下的黑色区域是100%的背景。我们把它设为128

bgt = cv2.dilate(thresh,None,iterations = 3)
ret,bg = cv2.threshold(bgt,1,128,1)
现在我们得到如下bg

C-现在我们同时添加fg和bg

marker = cv2.add(fg,bg)
以下是我们得到的信息:

现在我们可以从上面的图像清楚地了解到,白色区域是100%的前景,灰色区域是100%的背景,黑色区域我们不确定

然后我们将其转换为32SC1:

marker32 = np.int32(marker)
3-最后,我们应用分水岭并将结果转换回uint8图像:

cv2.watershed(img,marker32)
m = cv2.convertScaleAbs(marker32)
m:

ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
res = cv2.bitwise_and(img,img,mask = thresh)

4-我们正确设置阈值,以获得掩码,并对输入图像执行
逐位\u和

ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
res = cv2.bitwise_and(img,img,mask = thresh)
res:

ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
res = cv2.bitwise_and(img,img,mask = thresh)

希望对你有帮助


ARK

我想在这里解释一个关于如何使用流域的简单代码。我正在使用OpenCV Python,但我希望您不会有任何理解困难

此代码中,我将使用分水岭作为<强>前台背景提取的工具。<强>(本示例是OpenCV食谱中的C++代码的Python对应)。这是一个理解分水岭的简单案例。除此之外,还可以使用“分水岭”来计算此图像中对象的数量。这将是该代码的一个稍微高级的版本

1首先,我们加载图像,将其转换为灰度,并使用合适的值设置阈值。我采用了大津的二值化方法,因此它会找到最佳阈值

import cv2
import numpy as np

img = cv2.imread('sofwatershed.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
以下是我得到的结果:

(即使这样的结果也不错,因为前景图像和背景图像之间的对比度很大)

2-现在我们必须创建标记标记是与原始图像大小相同的图像,即32SC1(32位有符号单通道)。

现在,在原始图像中会有一些区域,您可以简单地确定,这些区域属于前景。在标记图像中用255标记该区域。现在,您确定为背景的区域标记为128。您不确定的区域标记为0。这就是我们下一步要做的

A-前景区域:-我们已经得到了一个阈值图像,其中药丸是白色的。我们稍微腐蚀了它们,这样我们就可以确定剩下的区域属于前景

fg = cv2.erode(thresh,None,iterations = 2)
fg

marker = cv2.add(fg,bg)

B-背景区域:-这里我们放大阈值图像,以便缩小背景区域。但我们确信剩下的黑色区域是100%的背景。我们把它设为128

bgt = cv2.dilate(thresh,None,iterations = 3)
ret,bg = cv2.threshold(bgt,1,128,1)
现在我们得到如下bg

C-现在我们同时添加fg和bg

marker = cv2.add(fg,bg)
以下是我们得到的信息:

现在我们可以从上面的图像清楚地了解到,白色区域是100%的前景,灰色区域是100%的背景,黑色区域我们不确定

然后我们将其转换为32SC1:

marker32 = np.int32(marker)
3-最后,我们应用分水岭并将结果转换回uint8图像:

cv2.watershed(img,marker32)
m = cv2.convertScaleAbs(marker32)
m:

ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
res = cv2.bitwise_and(img,img,mask = thresh)

4-我们正确设置阈值,以获得掩码,并对输入图像执行
逐位\u和

ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
res = cv2.bitwise_and(img,img,mask = thresh)
res:

ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
res = cv2.bitwise_and(img,img,mask = thresh)

希望对你有帮助


ARK

首先:函数
minMaxLoc
只查找给定输入的全局最小值和全局最大值,因此它在确定区域最小值和/或区域最大值时几乎没有用处。但您的想法是正确的,基于区域最小值/最大值提取标记以执行基于标记的分水岭变换是完全正确的。让我试着澄清什么是分水岭变换,以及您应该如何