英文:
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.
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.
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.
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论