Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.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 洪水填充功能未产生良好效果_Python_Opencv_Image Processing_Computer Vision_Flood Fill - Fatal编程技术网

Python 洪水填充功能未产生良好效果

Python 洪水填充功能未产生良好效果,python,opencv,image-processing,computer-vision,flood-fill,Python,Opencv,Image Processing,Computer Vision,Flood Fill,我在opencv中应用了floodfill函数来从背景中提取前景,但图像中的某些对象无法被算法识别,因此我想知道如何改进检测,以及需要进行哪些修改 image = cv2.imread(args["image"]) image = cv2.resize(image, (800, 800)) h,w,chn = image.shape ratio = image.shape[0] / 800.0 orig = image.copy() gray = cv2.cvtColor(

我在opencv中应用了floodfill函数来从背景中提取前景,但图像中的某些对象无法被算法识别,因此我想知道如何改进检测,以及需要进行哪些修改

image = cv2.imread(args["image"])
image = cv2.resize(image, (800, 800))
h,w,chn = image.shape
ratio = image.shape[0] / 800.0
orig = image.copy()

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)
# show the original image and the edge detected image
print("STEP 1: Edge Detection")
cv2.imshow("Image", image)
cv2.imshow("Edged", edged)

warped1 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
T = threshold_local(warped1, 11, offset = 10, method = "gaussian")
warped1 = (warped1 > T).astype("uint8") * 255
print("STEP 3: Apply perspective transform")

seed = (10, 10)

foreground, birdEye = floodFillCustom(image, seed)
cv2.circle(birdEye, seed, 50, (0, 255, 0), -1)
cv2.imshow("originalImg", birdEye)

cv2.circle(birdEye, seed, 100, (0, 255, 0), -1)

cv2.imshow("foreground", foreground)
cv2.imshow("birdEye", birdEye)

gray = cv2.cvtColor(foreground, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)
cv2.imwrite("gray.jpg", gray)

threshImg = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY)[1]
h_threshold,w_threshold = threshImg.shape
area = h_threshold*w_threshold

cv2.imshow("threshImg", threshImg)[![enter image description here][1]][1]
自定义函数如下所示-

def floodFillCustom(originalImage, seed):

    originalImage = np.maximum(originalImage, 10)
    foreground = originalImage.copy()

    cv2.floodFill(foreground, None, seed, (0, 0, 0),
                  loDiff=(10, 10, 10), upDiff=(10, 10, 10))

    return [foreground, originalImage]


有点晚了,但这里有一个分割工具的替代解决方案。它涉及将图像转换为颜色空间并提取
K
(关键)分量。此组件可以
阈值化
,以获得工具的良好二进制掩码,过程非常简单:

  • 将图像转换为CMYK颜色空间
  • 提取K(关键)组件
  • 阈值通过Otsu阈值化的图像
  • 应用一些形态(关闭)来清洁遮罩
  • (可选)获取所有工具的边界矩形
  • 让我们看看代码:

    # Imports
    import cv2
    import numpy as np
    
    # Read image
    imagePath = "C://opencvImages//"
    inputImage = cv2.imread(imagePath+"DAxhk.jpg")
    
    # Create deep copy for results:
    inputImageCopy = inputImage.copy()
    
    # Convert to float and divide by 255:
    imgFloat = inputImage.astype(np.float) / 255.
    
    # Calculate channel K:
    kChannel = 1 - np.max(imgFloat, axis=2)
    
    # Convert back to uint 8:
    kChannel = (255*kChannel).astype(np.uint8)
    
    第一步是将
    BGR
    图像转换为
    CMYK
    。OpenCV中没有直接的转换,所以我直接应用了。我们可以从这个公式中得到每个颜色空间分量,但我们只对
    K
    通道感兴趣。转换很容易,但是我们需要小心使用数据类型。我们需要对
    float
    数组进行操作。获取
    K
    通道后,我们将图像转换回
    无符号8位
    数组,这是结果图像:

    让我们使用大津的阈值化方法对该图像设置阈值:

    # Threshold via Otsu:
    _, binaryImage = cv2.threshold(kChannel, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    
    这将生成以下二进制图像:

    看起来很漂亮!此外,我们可以使用
    形态学闭包
    稍微清理一下(加入小间隙)。让我们应用大小为
    5x5
    矩形结构元素
    ,并使用
    2
    迭代:

    # Use a little bit of morphology to clean the mask:
    # Set kernel (structuring element) size:
    kernelSize = 5
    # Set morph operation iterations:
    opIterations = 2
    # Get the structuring element:
    morphKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
    # Perform closing:
    binaryImage = cv2.morphologyEx(binaryImage, cv2.MORPH_CLOSE, morphKernel, None, None, opIterations, cv2.BORDER_REFLECT101)
    
    其结果是:

    很酷。以下内容是可选的。通过查找外部(外部)轮廓,我们可以获得每个工具的
    边界矩形

    # Find the contours on the binary image:
    contours, hierarchy = cv2.findContours(binaryImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    # Look for the outer bounding boxes (no children):
    for _, c in enumerate(contours):
    
        # Get the contours bounding rectangle:
        boundRect = cv2.boundingRect(c)
    
        # Get the dimensions of the bounding rectangle:
        rectX = boundRect[0]
        rectY = boundRect[1]
        rectWidth = boundRect[2]
        rectHeight = boundRect[3]
    
        # Set bounding rectangle:
        color = (0, 0, 255)
        cv2.rectangle( inputImageCopy, (int(rectX), int(rectY)),
                       (int(rectX + rectWidth), int(rectY + rectHeight)), color, 5 )
    
        cv2.imshow("Bounding Rectangles", inputImageCopy)
        cv2.waitKey(0)
    
    将生成最终图像:


    你能添加原始的输入图像吗?是的,我当然添加了!您正在尝试创建工具的掩码吗?可以有一种更直接的方法来分割前景对象,而不使用泛洪填充。你想干什么?回答您的问题:泛光填充算法有一个“容差”值,用于确定是否必须忽略用于创建像素连续“面片”的颜色变化。“公差”使填充目标颜色稍有变化的区域成为可能。在您的情况下,螺丝刀可能高于该特定公差,从而防止像素填充。也许增加阈值会有所帮助。是的,我正在尝试创建工具的掩码!你能帮我一些方法吗!真棒!!这正是我需要的!谢谢大家!@SubhamTiwari如果答案对您有帮助,请接受。对于其他一些图像,检测结果不符合要求,是否需要更改一些参数值以获得下注结果?或者还有其他方法吗?@SubhamTiwari没有这些图片很难说。计算机视觉算法高度依赖于它们的输入,如果新图像与原始图像相差太大,可能需要一种新的方法。例如,背景在附加的图像中非常简单,并且自然地在前景对象之间产生很好的对比度,这简化了检测。如果您正在测试具有复杂(纹理、多色)背景的图像,仅使用原始方法是不够的。如果您有太多在不同条件下获取的不同图像,可能需要使用机器学习方法。您是否考虑过任何机器学习模型,以便开始此类场景?我将链接一个图像,这样你就可以公平地理解我正在处理的不同类型的图像!