首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Python/OpenCV中计算轮廓是否已远离边缘

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

Stack Overflow用户
提问于 2019-04-03 11:04:22
回答 2查看 556关注 0票数 0

我正在使用几种不同的技术创建一个跟踪系统,MOSSE就是其中之一,我已经得到了基于背景减去的轮廓的边界框-我正在试图找出最好的方法来获取我的轮廓,这些轮廓将显示在屏幕上,以了解它们是否已经远离图像边界(甚至距离边界边缘一个像素),这样我就可以使用它作为边界框来开始MOSSE跟踪。

我目前正在遍历轮廓线,需要根据上面的论点检查每个轮廓线。

我已经考虑过使用pointPolygonTest并为整个框架区域创建一个轮廓,检查轮廓是否在这个区域内(没有接触边界的点)。但似乎无法计算出如何为整个框架创建轮廓,而且这可能会非常低效。

代码语言:javascript
运行
复制
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

结果应该是,如果轮廓边缘没有接触边界(之间没有像素间隙),我会得到输出通知我,这样我就可以为MOSSE添加边界框-这应该发生在帧中的每个轮廓上。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-03 23:49:14

这是另一个解决方案,按照您的建议使用轮廓。

我使用了OpenCV Wrapper library来简化矩形和包含的东西。转换成普通的OpenCV和Numpy并不是太难,只是有点繁琐。

代码语言:javascript
运行
复制
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 Wrapper的作者。

票数 1
EN

Stack Overflow用户

发布于 2019-04-03 23:29:38

一种可能的解决方案是使用填充来清除白色像素的所有边缘。当你找到你的轮廓后,你将得到保证,他们在框架内。我曾经使用过这段代码来实现这一点。

这可能不是最好的解决方案,但仍然是一个解决方案。

代码语言:javascript
运行
复制
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

我对效率不是很确定,所以你得测试一下。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55486414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档