gpt4 book ai didi

opencv - 从外部轮廓创建蒙版以移除图像背景

转载 作者:行者123 更新时间:2023-12-02 16:27:50 25 4
gpt4 key购买 nike

我有一个无法控制的背景颜色的对象(样本)的图像。此问题已通过 post 的建议得到解决.如果图像是从垂直角度拍摄的,则该代码可以很好地工作。

但是,我还有另一个问题。一些图像是从无法控制的角度拍摄的。我上面提到的帖子中的现有代码返回了意外的结果。例如,给定原始图像

original

结果是result .

我修改该代码的想法是从外部轮廓制作一个蒙版,然后在原始和蒙版之间按位应用。但我不知道如何从外轮廓制作面具。我可以有你的建议吗?

最佳答案

您可以使用以下解决方案(尽管它不能很好地分离样本):

  • 使用cv2.floodFill用黑色背景替换彩色背景。
  • 使用“关闭”形态学操作来移除在 floodFill 之后留下的一些不需要的伪影。 .
  • 阈值结果,并找到最大的轮廓。
  • 使用 following post 中的代码平滑轮廓
  • 从“平滑”轮廓构建面膜,然后涂抹面膜。

  • 这是代码:

    import numpy as np
    import cv2
    from scipy.interpolate import splprep, splev

    orig_im = cv2.imread("specimen1.jpg")

    im = orig_im.copy()

    h, w = im.shape[0], im.shape[1]

    # Seed points for floodFill (use two points at each corner for improving robustness)
    seedPoints = ((0, 0), (10, 10), (w-1, 0), (w-1, 10), (0, h-1), (10, h-1), (w-1, h-1), (w-10, h-10))

    # Fill background with black color
    for seed in seedPoints:
    cv2.floodFill(im, None, seedPoint=seed, newVal=(0, 0, 0), loDiff=(5, 5, 5), upDiff=(5, 5, 5))

    # Use "close" morphological operation
    im = cv2.morphologyEx(im, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10,10)));

    #Convert to Grayscale, and then to binary image.
    gray = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
    ret, thresh_gray = cv2.threshold(gray, 5, 255, cv2.THRESH_BINARY)

    #Find contours
    _, contours, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    c = max(contours, key=cv2.contourArea) # Get the largest contour

    # Smooth contour
    # https://agniva.me/scipy/2016/10/25/contour-smoothing.html
    x,y = c.T
    x = x.tolist()[0]
    y = y.tolist()[0]
    tck, u = splprep([x,y], u=None, s=1.0, per=1)
    u_new = np.linspace(u.min(), u.max(), 20)
    x_new, y_new = splev(u_new, tck, der=0)
    res_array = [[[int(i[0]), int(i[1])]] for i in zip(x_new,y_new)]
    smoothened = np.asarray(res_array, dtype=np.int32)

    # For testing
    test_im = orig_im.copy()
    cv2.drawContours(test_im, [smoothened], 0, (0, 255, 0), 1)

    # Build a mask
    mask = np.zeros_like(thresh_gray)
    cv2.drawContours(mask, [smoothened], -1, 255, -1)

    # Apply mask
    res = np.zeros_like(orig_im)
    res[(mask > 0)] = orig_im[(mask > 0)]

    # Show images for testing
    cv2.imshow('test_im', test_im)
    cv2.imshow('res', res)
    cv2.imshow('mask', mask)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    评论:
    我不认为该解决方案非常强大。
    您可能需要使用迭代方法(例如逐渐增加 loDiffhiDiff 参数以匹配给定图像的最佳参数)。

    结果:

    第一个样本:

    test_im:
    enter image description here

    面具:
    enter image description here

    资源:
    enter image description here

    第二个样本:

    test_im:
    enter image description here

    面具:
    enter image description here

    资源:
    enter image description here

    第三个样本:

    资源:
    enter image description here

    关于opencv - 从外部轮廓创建蒙版以移除图像背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60319634/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com