簡體   English   中英

如何獲取和存儲平面圖圖像的房間的質心坐標?

[英]How to obtain and store centroid coordinates of rooms of a floor plan image?

我有一個由多個房間組成的平面圖圖像。 使用 Python,我想找到每個房間的中心並以 (x,y) 的形式存儲坐標,以便我可以進一步使用它們進行數學計算。 現有的drawContoursFindContours函數有助於確定輪廓,但如何將獲得的值存儲到列表中。

該圖像表示具有多個房間的示例平面圖。

該圖像表示具有多個房間的示例平面圖。

我嘗試使用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()

這是一個簡單的方法:

  1. 獲取二值圖像。 加載圖像、灰度和大津閾值

  2. 刪除文本。 我們找到輪廓然后使用輪廓區域過濾以去除小於某個閾值的輪廓。 我們通過用cv2.drawContours填充它們來有效地去除這些輪廓。

  3. 找到矩形框並獲得質心坐標。 我們再次找到輪廓,然后使用輪廓面積和輪廓近似進行過濾。 然后我們找到每個輪廓的矩,這給了我們質心


這是一個可視化:

刪除文本

在此處輸入圖片說明

結果

在此處輸入圖片說明

坐標

[(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM