简体   繁体   English

如何获取和存储平面图图像的房间的质心坐标?

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

I have a floor plan image which consists of multiple rooms.我有一个由多个房间组成的平面图图像。 Using Python, I want to find the centers of each room and store the coordinates in the form of (x,y) so that I can use them further for mathematical calculations.使用 Python,我想找到每个房间的中心并以 (x,y) 的形式存储坐标,以便我可以进一步使用它们进行数学计算。 The existing drawContours and FindContours functions help in determining the contours, but how can I store the values obtained into a list.现有的drawContoursFindContours函数有助于确定轮廓,但如何将获得的值存储到列表中。

The image represents a sample floor plan with multiple rooms.该图像表示具有多个房间的示例平面图。

该图像表示具有多个房间的示例平面图。

I tried using moments but the function doesn't work properly.我尝试使用moments但该功能无法正常工作。 As you may see this image is obtained from drawContours function.如您所见,此图像是从drawContours函数获得的。 But then how do I store the x and y coordinates.但是我如何存储 x 和 y 坐标。

Here's my code :这是我的代码:

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()

Here's a simple approach:这是一个简单的方法:

  1. Obtain binary image.获取二值图像。 Load image, grayscale, and Otsu's threshold .加载图像、灰度和大津阈值

  2. Remove text.删除文本。 We find contours then filter using contour area to remove contours smaller than some threshold value.我们找到轮廓然后使用轮廓区域过滤以去除小于某个阈值的轮廓。 We effectively remove these contours by filling them in with cv2.drawContours .我们通过用cv2.drawContours填充它们来有效地去除这些轮廓。

  3. Find rectangular boxes and obtain centroid coordinates.找到矩形框并获得质心坐标。 We find contours again then filter using contour area and contour approximation .我们再次找到轮廓,然后使用轮廓面积和轮廓近似进行过滤。 We then find moments for each contour which gives us the centroid .然后我们找到每个轮廓的矩,这给了我们质心


Here's a visualization:这是一个可视化:

Remove text删除文本

在此处输入图片说明

Result结果

在此处输入图片说明

Coordinates坐标

[(93, 241), (621, 202), (368, 202), (571, 80), (317, 79), (93, 118)]

Code代码

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