[英]How to obtain and store centroid coordinates of rooms of a floor plan image?
我有一個由多個房間組成的平面圖圖像。 使用 Python,我想找到每個房間的中心並以 (x,y) 的形式存儲坐標,以便我可以進一步使用它們進行數學計算。 現有的drawContours
和FindContours
函數有助於確定輪廓,但如何將獲得的值存儲到列表中。
該圖像表示具有多個房間的示例平面圖。
我嘗試使用moments
但該功能無法正常工作。 如您所見,此圖像是從drawContours
函數獲得的。 但是我如何存儲 x 和 y 坐標。
這是我的代碼:
k= []
# Going through every contours found in the image.
for cnt in contours :
approx = cv2.approxPolyDP(cnt, 0.009 * cv2.arcLength(cnt, True), True)
# draws boundary of contours.
cv2.drawContours(img, [approx], -1, (0, 0,255), 3)
# Used to flatted the array containing
# the co-ordinates of the vertices.
n = approx.ravel()
i = 0
x=[]
y=[]
for j in n :
if(i % 2 == 0):
x = n[i]
y = n[i + 1]
# String containing the co-ordinates.
string = str(x) + " ," + str(y)
if(i == 0):
# text on topmost co-ordinate.
cv2.putText(img, string, (x, y),
font, 0.5, (255, 0, 0))
k.append(str((x, y)))
else:
# text on remaining co-ordinates.
cv2.putText(img, string, (x, y),
font, 0.5, (0, 255, 0))
k.append(str((x, y)))
i = i + 1
# Showing the final image.
cv2_imshow( img )
# Exiting the window if 'q' is pressed on the keyboard.
if cv2.waitKey(0) & 0xFF == ord('q'):
cv2.destroyAllWindows()
這是一個簡單的方法:
獲取二值圖像。 加載圖像、灰度和大津閾值。
刪除文本。 我們找到輪廓然后使用輪廓區域過濾以去除小於某個閾值的輪廓。 我們通過用cv2.drawContours
填充它們來有效地去除這些輪廓。
找到矩形框並獲得質心坐標。 我們再次找到輪廓,然后使用輪廓面積和輪廓近似進行過濾。 然后我們找到每個輪廓的矩,這給了我們質心。
這是一個可視化:
刪除文本
結果
坐標
[(93, 241), (621, 202), (368, 202), (571, 80), (317, 79), (93, 118)]
代碼
import cv2
import numpy as np
# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Remove text
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 1000:
cv2.drawContours(thresh, [c], -1, 0, -1)
thresh = 255 - thresh
result = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
coordinates = []
# Find rectangular boxes and obtain centroid coordinates
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.05 * peri, True)
if len(approx) == 4 and area < 100000:
# cv2.drawContours(result, [c], -1, (36,255,12), 1)
M = cv2.moments(c)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
coordinates.append((cx, cy))
cv2.circle(result, (cx, cy), 3, (36,255,12), -1)
cv2.putText(result, '({}, {})'.format(int(cx), int(cy)), (int(cx) -40, int(cy) -10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (36,255,12), 2)
print(coordinates)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.imshow('result', result)
cv2.waitKey()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.