Python 如何获取和存储楼层平面图像中房间的质心坐标?
我有一个由多个房间组成的平面图。使用Python,我希望找到每个房间的中心,并以(x,y)的形式存储坐标,以便进一步使用它们进行数学计算。现有的Python 如何获取和存储楼层平面图像中房间的质心坐标?,python,image,opencv,image-processing,computer-vision,Python,Image,Opencv,Image Processing,Computer Vision,我有一个由多个房间组成的平面图。使用Python,我希望找到每个房间的中心,并以(x,y)的形式存储坐标,以便进一步使用它们进行数学计算。现有的drawContours和FindContours函数有助于确定等高线,但如何将获得的值存储到列表中 该图像表示具有多个房间的示例楼层平面 我尝试使用矩,但该函数无法正常工作。 这是我的密码: k= [] # Going through every contours found in the image. for cnt in contours :
drawContours
和FindContours
函数有助于确定等高线,但如何将获得的值存储到列表中
该图像表示具有多个房间的示例楼层平面
我尝试使用矩
,但该函数无法正常工作。
这是我的密码:
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()
这里有一个简单的方法:
下面是一个可视化: 删除文本 结果 坐标
[(93, 241), (621, 202), (368, 202), (571, 80), (317, 79), (93, 118)]
代码
导入cv2
将numpy作为np导入
#加载图像、灰度、大津阈值
image=cv2.imread('1.png')
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
thresh=cv2.阈值(灰色,0,255,cv2.thresh\u二进制\u INV+cv2.thresh\u OTSU)[1]
#删除文本
cnts=cv2.查找对象(阈值、cv2.RETR\u树、cv2.链近似值、简单值)
如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
对于碳纳米管中的碳:
面积=cv2。轮廓面积(c)
如果面积小于1000:
cv2.拉深轮廓(阈值[c],-1,0,-1)
thresh=255-thresh
结果=cv2.CVT颜色(阈值,cv2.COLOR_GRAY2BGR)
坐标=[]
#找到矩形框并获得质心坐标
cnts=cv2.查找对象(阈值、cv2.RETR\u树、cv2.链近似值、简单值)
如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
对于碳纳米管中的碳:
面积=cv2。轮廓面积(c)
peri=cv2.弧长(c,真)
近似值=cv2.近似聚合度(c,0.05*peri,真)
如果len(近似值)=4且面积<100000:
#cv2.等高线图(结果[c],-1,(36255,12),1)
M=cv2.力矩(c)
cx=int(M['m10']/M['m00']
cy=int(M['m01']/M['m00']
坐标。追加((cx,cy))
cv2.圆(结果(cx,cy),3,(36255,12),-1)
cv2.putText(result,({},{}).format(int(cx),int(cy)),(int(cx)-40,int(cy)-10),cv2.FONT\u HERSHEY\u SIMPLEX,0.5,(36255,12),2)
打印(坐标)
cv2.imshow('thresh',thresh)
cv2.imshow(“图像”,图像)
cv2.imshow(“结果”,结果)
cv2.waitKey()
你说瞬间不起作用。但您不显示代码。请始终提供您的代码,以便其他人可以看到您是否有错误。一旦你有了轮廓,你可以得到边界框,从中你可以很容易地计算出中心。不,对于瞬间,它给出零误差。这就是为什么我没有包括它你仍然没有显示你的质心代码。给定有效轮廓,您应该能够从以下位置获取质心:`M=cv2.矩(cntr)cx=int(M[“m10”]/M[“m00”])cy=int(M[“m01”]/M[“m00”])`
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()