Как получить и сохранить координаты центроида комнат на плане этажа? - PullRequest
1 голос
/ 24 марта 2020

У меня есть изображение плана этажа, которое состоит из нескольких комнат. Используя Python, я хочу найти центры каждой комнаты и сохранить координаты в форме (x, y), чтобы в дальнейшем использовать их для математических расчетов. Существующие функции drawContours и FindContours помогают определить контуры, но как я могу сохранить полученные значения в списке.

Изображение представляет собой пример плана этажа с несколькими комнатами.

The image represents a sample floor plan with multiple rooms.

Я пытался использовать 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 Ответ

1 голос
/ 25 марта 2020

Вот простой подход:

  1. Получение двоичного изображения. Загрузка изображения, оттенков серого и Порог Оцу .

  2. Удалить текст. Мы находим контуры , а затем фильтруем, используя область контура , чтобы удалить контуры, меньшие некоторого порогового значения. Мы эффективно удаляем эти контуры, заполняя их cv2.drawContours.

  3. Находим прямоугольные angular блоки и получаем координаты центроида. Мы снова найдите контуры, затем отфильтруйте, используя площадь контура и приближение контура . Затем мы находим моменты для каждого контура, которые дают нам центроид .


Вот визуализация:

Удалить текст

enter image description here

Результат

enter image description here

Координаты

[(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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...