将背景颜色扩展到连接的组件(Flood fill) - 图像处理

Expanding background color to connected components(Flood fill) - Image Processing

有点想弄清楚如何向内扩展背景颜色。 我有这张图像是在去除噪声背景后通过蒙版生成的。

我正在努力做到这一点:

到目前为止我已经试过了,但没有成功:

import cv2
from PIL import Image
import numpy as np

Image.open("example_of_misaligned_frame.png") # open poor frame

img_copy = np.asanyarray(img).copy()

contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX) # find contours 

# create bounding box around blob and figure out the row.cols to iterate over
x,y,w,h = cv2.boundingRect(max(contours, key = cv2.contourArea)) 

# flood fill the entire region with back, hoping that off-white region gets filled due to connected components.
for row in range(y, y+h):
    for col in range(x, x+w):
        cv2.floodFill(img_copy, None, seedPoint=(col,row), newVal=0)

这会导致全黑图像:(

非常感谢任何为我指明正确方向的帮助。

你可以用floodFill两次解决:

  • 第一次 - 用灰白色填充黑色像素。
  • 第二次 - 用黑色填充灰白色像素。

查找灰白色的 RGB 值仍然存在问题。
我找到了一个临时解决方案来查找灰白色(我不知道什么颜色被认为是背景的确切规则)。

这是一个工作代码示例:

import cv2
import numpy as np

#Image.open("example_of_misaligned_frame.png") # open poor frame
img = cv2.imread("example_of_misaligned_frame.png")

#img_copy = np.asanyarray(img).copy()
img_copy = img.copy()

#Improvised way to find the Off White color (it's working because the Off White has the maximum color components values).
tmp = cv2.dilate(img, np.ones((50,50), np.uint8), iterations=10)

# Color of Off-White pixel
offwhite = tmp[0, 0, :]

# Convert to tuple
offwhite = tuple((int(offwhite[0]), int(offwhite[1]), int(offwhite[2])))

# Fill black pixels with off-white color
cv2.floodFill(img_copy, None, seedPoint=(0,0), newVal=offwhite)

# Fill off-white pixels with black color
cv2.floodFill(img_copy, None, seedPoint=(0,0), newVal=0, loDiff=(2, 2, 2, 2), upDiff=(2, 2, 2, 2))

cv2.imshow("img_copy", img_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.dilate的结果:

第一个cv2.floodFill的结果:

第二个cv2.floodFill的结果:

在 Python/OpenCV 中,您可以简单地从填充过程图像中提取二进制掩码并腐蚀该掩码。然后将其重新应用于输入或您的洪水填充结果。

输入:

import cv2

# read image
img = cv2.imread("masked_image.png")

# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# make anything not black into white
gray[gray!=0] = 255

# erode mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (51,51))
mask = cv2.morphologyEx(gray, cv2.MORPH_ERODE, kernel)

# make mask into 3 channels
mask = cv2.merge([mask,mask,mask])

# apply new mask to img
result = img.copy()
result = cv2.bitwise_and(img, mask)

# write result to disk
cv2.imwrite("masked_image_original_mask.png", gray)
cv2.imwrite("masked_image_eroded_mask.png", mask)
cv2.imwrite("masked_image_eroded_image.png", result)

# display it
cv2.imshow("IMAGE", img)
cv2.imshow("MASK", mask)
cv2.imshow("RESULT", result)
cv2.waitKey(0)


面具:

侵蚀面具:

结果:

根据需要调整圆形(椭圆形)形态内核的大小以增加或减少侵蚀。