Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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 使用OpenCV改善显光条件下的洪水填充效果_Python_Opencv - Fatal编程技术网

Python 使用OpenCV改善显光条件下的洪水填充效果

Python 使用OpenCV改善显光条件下的洪水填充效果,python,opencv,Python,Opencv,我正在尝试用工具对图像进行轮廓检测,因为工具的金属性质会反射光线并产生眩光。为了限制这种影响,我使用了泛洪填充,但这对参数非常敏感 例如,这里是我的原始图像: 这是被洪水淹没的那个 这看起来很棒,不是我尝试的第二张图片: 正如您在泛光图像上看到的,一些工具没有正确处理,因此轮廓检测将无法给出良好的结果 以下是更新版本: import numpy as np import cv2 def getFilteredLabelIndex(stats, widthLowLimit=50, he

我正在尝试用工具对图像进行轮廓检测,因为工具的金属性质会反射光线并产生眩光。为了限制这种影响,我使用了泛洪填充,但这对参数非常敏感

例如,这里是我的原始图像:

这是被洪水淹没的那个

这看起来很棒,不是我尝试的第二张图片:

正如您在泛光图像上看到的,一些工具没有正确处理,因此轮廓检测将无法给出良好的结果

以下是更新版本:

import numpy as np
import cv2


def getFilteredLabelIndex(stats, widthLowLimit=50, heightLowLimit=50, areaLowLimit=7000):
    ret = []
    for i in range(1, stats.shape[0]):
        # extract the connected component statistics for the current label
        w = stats[i, cv2.CC_STAT_WIDTH]
        h = stats[i, cv2.CC_STAT_HEIGHT]
        area = stats[i, cv2.CC_STAT_AREA]

        keepWidth = w > widthLowLimit
        keepHeight = h > heightLowLimit
        keepArea = area > areaLowLimit

        if all((keepWidth, keepHeight, keepArea)):
            ret.append(i)

    return ret

# load our input image, convert it to grayscale, and blur it slightly
impath = "q8djf.png"
originalImage = cv2.imread(impath)

birdEye = originalImage 

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

# Use floodFill for filling the background with black color
cv2.floodFill(foreground, None, seed, (0, 0, 0),
              loDiff=(5, 5, 5), upDiff=(5, 5, 5))
              
cv2.imshow("foreground", foreground)

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

threshImg = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY)[1]
cv2.imshow("threshImg", threshImg)

(numLabels, labels, stats, centroids) = cv2.connectedComponentsWithStats(
    threshImg, 4, cv2.CV_32S)

filteredIdx = getFilteredLabelIndex(stats)

for i in filteredIdx:
    componentMask = (labels == i).astype("uint8") * 255

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    componentMask = cv2.dilate(componentMask, kernel, iterations=3)

    ctrs, _ = cv2.findContours(
        componentMask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    ctrs = sorted(ctrs, key=cv2.contourArea, reverse=True)
    cntrs = max(ctrs, key=cv2.contourArea)

    cv2.drawContours(birdEye, [cntrs], -1, (255, 0, 255), 3)
    cv2.imshow("contour", birdEye)

cv2.imshow("original contour", birdEye)
cv2.waitKey(0)
cv2.destroyAllWindows()

欢迎任何建议。

锐化输入图像可能会有所帮助

锐化操作会放大对象和背景之间的差异

我不确定它对其他图像的鲁棒性如何,但它可以提高当前解决方案的鲁棒性

我使用了以下帖子中的锐化解决方案:,但参数不同,锐化效果更强

以下代码演示了该解决方案:

#https://stackoverflow.com/questions/4993082/how-can-i-sharpen-an-image-in-opencv
#锐化图像
模糊=cv2.高斯模糊(birdEye,(0,0,3)
锐利的前景=cv2.addWeighted(birdEye,2,blur,-1,0);
锐利前景=np.最大值(锐利前景,10)
#使用泛光填充以黑色填充背景
#使用loDiff和upDiff(10,10,10)而不是(5,5,5)来夸大问题
cv2.泛光填充(前景清晰,无,种子,(0,0,0),
loDiff=(10,10,10),upDiff=(10,10,10))

带锐化(
sharp_前台
):

不进行锐化:

注:
该示例使用
loDiff=(10,10,10)
upDiff=(10,10,10)
进行演示。

尝试保持较低的值。

控制照明条件或使用更先进的技术,如深度学习实例分割或对象检测。中级高级技术可以是超像素分割形状匹配、关键点匹配,但通常所有这些技术都有一些边缘化以及它们的优点。如果你的背景总是像那些rwo图像一样好,你可以尝试梯度或边缘提取,并对结果进行聚类以估计对象。然后你可以使用凸包来估计轮廓。嗨,米卡,谢谢你的提示。我不确定深入学习能有多大帮助,因为没有办法知道工具的形状。这不像识别一张脸或一辆汽车,你可以训练一个网络。在我的情况下,工具可以是任何性质的(如果我错了,请纠正我)。至于你的第二点,是的,背景总是一样好,它是一张普通的A4纸。事实上,我正在使用cv2.ConnectedComponents SwithStats图像来识别不同的对象,但同样,这将根据光线条件切割出部分对象。深度学习可以很好地概括,并且是在不受控制的现实生活中工作良好的少数技术之一。您当前的方法非常简单,因此您必须控制环境,或者找到一种方法来自动规范化图像或参数(根据图像),或者进行大量假设。请发布您的代码,谢谢。