Python 洪水填充功能未产生良好效果
我在opencv中应用了floodfill函数来从背景中提取前景,但图像中的某些对象无法被算法识别,因此我想知道如何改进检测,以及需要进行哪些修改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(
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
(关键)分量。此组件可以阈值化
,以获得工具的良好二进制掩码,过程非常简单:
# 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没有这些图片很难说。计算机视觉算法高度依赖于它们的输入,如果新图像与原始图像相差太大,可能需要一种新的方法。例如,背景在附加的图像中非常简单,并且自然地在前景对象之间产生很好的对比度,这简化了检测。如果您正在测试具有复杂(纹理、多色)背景的图像,仅使用原始方法是不够的。如果您有太多在不同条件下获取的不同图像,可能需要使用机器学习方法。您是否考虑过任何机器学习模型,以便开始此类场景?我将链接一个图像,这样你就可以公平地理解我正在处理的不同类型的图像!