如何在Python中找到一个楼层平面图的外部轮廓

huangapple go评论76阅读模式
英文:

How to find the outer contour of a floorplan in python

问题

通过应用一些模糊处理并使用OpenCV中的基本轮廓函数,您可以提取轮廓,如下所示:

floorplan = cv2.imread("Edited_floorplan_v2.jpeg")
gray = cv2.cvtColor(floorplan, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0)
edges = cv2.Canny(blur, 50, 150)
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

然后,您可以尝试以下代码来找到最大的外部轮廓:

largest_contour_area = 0
for contour in contours:
    if (cv2.contourArea(contour)) > largest_contour_area:
        largest_contour_area = cv2.contourArea(contour)
        largest_contour = contour

然而,结果可能不如预期。如果您想要保留最大的外部轮廓,可以尝试以下方法:

largest_contours = sorted(contours, key=cv2.contourArea, reverse=True)[:1]

这将按轮廓面积对轮廓进行排序,并选择最大的一个。然后,largest_contours 中将包含最大的外部轮廓。这样,您就可以只保留最大的外部轮廓。

英文:

I have a floorplan in the format of jpeg and I would like to find the outer contour of the floorplan (as indicated in the blue line below). So that given any pixel, I can identify whether that point is inside or outside the building.

如何在Python中找到一个楼层平面图的外部轮廓

By applying some blurring and using the basic contour function from cv2,

floorplan = cv2.imread("Edited_floorplan_v2.jpeg")
gray = cv2.cvtColor(floorplan, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0)
edges = cv2.Canny(blur, 50, 150)
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

I can extract the contours like shown below.

如何在Python中找到一个楼层平面图的外部轮廓

Then I tried the following code

largest_contour_area = 0
for contour in contours:
    if (cv2.contourArea(contour)) > largest_contour_area:
        largest_contour_area = cv2.contourArea(contour)
        largest_contour = contour

However the result was not satisfactory.

如何在Python中找到一个楼层平面图的外部轮廓

Is there something I can do so that I can only keep the largest outer contours? Thanks.

答案1

得分: 0

教训:不要急于发布问题,多做一些研究。

经过一些研究(还要感谢 @fana 的指点),floodFill 非常有效地解决了这个问题。如果外部轮廓已经封闭,那么你只需要手动选择一些开放空间中的点,然后进行 floodFill 操作。

seed_point1 = (120, 120)
seed_point2 = (90, 500)
seed_point3 = (800, 50)
seed_point4 = (2200, 100)

cv2.floodFill(blur, None, seed_point1, 0, loDiff=10, upDiff=10)
cv2.floodFill(blur, None, seed_point2, 0, loDiff=10, upDiff=10)
cv2.floodFill(blur, None, seed_point3, 0, loDiff=10, upDiff=10)
cv2.floodFill(blur, None, seed_point4, 0, loDiff=10, upDiff=10)

这就是结果。

英文:

Lesson learned: don't rush to post questions and do more research.

After a bit of research (also thanks @fana for pointing out), floodFill solves this problem like a charm. If your outer contour is enclosed, then all you need to do is to manually pick a few points in those open spaces and floodFill it.

seed_point1 = (120, 120)
seed_point2 = (90, 500)
seed_point3 = (800, 50)
seed_point4 = (2200, 100)

cv2.floodFill(blur, None, seed_point1, 0, loDiff=10, upDiff=10)
cv2.floodFill(blur, None, seed_point2, 0, loDiff=10, upDiff=10)
cv2.floodFill(blur, None, seed_point3, 0, loDiff=10, upDiff=10)
cv2.floodFill(blur, None, seed_point4, 0, loDiff=10, upDiff=10)

This is the result.
如何在Python中找到一个楼层平面图的外部轮廓

huangapple
  • 本文由 发表于 2023年2月27日 13:12:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576954.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定