在Python/OpenCV中,如何计算轮廓是否已经远离边缘

2024-10-03 21:26:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我用了两种不同的技术创建了一个跟踪系统,MOSSE就是其中之一,我有一个基于背景减法轮廓的边界框——我正在尝试找出最好的方法来获得屏幕上的轮廓,以知道它们是否已经远离了图像边界(甚至离图像边界有一个像素)边界边缘),所以我可以使用它作为边界框来开始苔藓跟踪。你知道吗

Imgur

我现在正在循环遍历轮廓,需要对照上面的参数检查每个轮廓。你知道吗

我考虑过使用pointPolygonTest并为帧的整个区域创建一个轮廓,检查轮廓是否在这个区域内(没有点接触到边界)。但似乎无法为整个帧创建轮廓,而且这可能会非常低效。你知道吗

while(1):
    ret, frame = cap.read()

    contour, heir = cv2.findContours(fgmask, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)


    for cnt in contour:
        # and so on ...
        # This is where I will check the contour if it is touching frame boundary/edge

结果应该是,如果一个轮廓边缘没有接触到边界(没有像素(s)之间的差距),我会得到输出通知我,这样我就可以添加边界框苔藓-这应该发生在帧中的每个轮廓。你知道吗

如果我没有提供足够的细节,或您需要澄清,请随时发表意见,任何帮助是感激的。你知道吗


Tags: 图像区域is系统像素cv2frame技术
2条回答

一个可能的解决方案是使用泛光填充来清除白色像素的所有边缘。当你找到你的轮廓后,你会保证他们是在框架内。我曾经用过这个代码来完成这个任务。你知道吗

这可能不是最好的解决办法,但仍然是一个解决办法。你知道吗

import numpy as np
import cv2 as cv

# Image will then be binary, either 0 or 255. 
def floodfill_edges(image):
    where = np.where(image[:, 0] == 255)
    while where[0].size > 0:
        x, y = 0, where[0][0]
        cv.floodFill(image, None, (x, y), 0)
        where = np.where(image[:, 0] == 255)

    where = np.where(image[:, -1] == 255)
    while where[0].size > 0:
        x, y = image.shape[1] - 1, where[0][0]
        cv.floodFill(image, None, (x, y), 0)
        where = np.where(image[:, -1] == 255)

    where = np.where(image[0, :] == 255)
    while where[0].size > 0:
        x, y = where[0][0], 0
        cv.floodFill(image, None, (x, y), 0)
        where = np.where(image[0, :] == 255)

    where = np.where(image[-1, :] == 255)
    while where[0].size > 0:
        x, y = where[0][0], image.shape[0] - 1
        cv.floodFill(image, None, (x, y), 0)
        where = np.where(image[-1, :] == 255)

    return image

我不确定效率,所以你得测试一下。你知道吗

这里是另一个解决方案,使用您建议的等高线。你知道吗

我使用了OpenCV Wrapper library来简化矩形并包含一些内容。转换成普通的OpenCV和Numpy并不难,只是有点乏味。你知道吗

import cv2 as cv
import numpy as np
import opencv_wrapper as cvw

image = cv.imread("path/to/image")
gray = cvw.bgr2gray(image)
thresh = cvw.threshold_otsu(gray)

# Returns Contour object
contours = cvw.find_external_contours(thresh)

# Create a rectangle representing the boundary 1 pixel in.
boundary = cvw.Rect(1, 1, image.shape[1] - 2, image.shape[0] - 2)

for contour in contours:
    # Returns a Rect object
    rect = contour.bounding_rect
    if (
        rect.tl not in boundary
        or rect.tr not in boundary
        or rect.bl not in boundary
        or rect.br not in boundary
    ):
        continue

    # Create tracker
    cvw.rectangle(image, rect, cvw.Color.RED, 1)

cv.imshow("Image", np.hstack([image, cvw.gray2bgr(thresh)]))
cvw.wait_key(0)

披露:我是OpenCV包装器的作者。你知道吗

相关问题 更多 >