使用 OpenCV 从图像中查找房间的坐标
Find coordinates of a room from an image using OpenCV
我正在尝试为 map/navigation 应用获取每个房间的坐标。下面的代码找到每个角落,再往下的代码找到房间的中心。我不知道如何将两者结合起来,以便分别获得每个房间角落的坐标数组。
平面图图片:
#finds every corner
img = cv2.imread('out.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv2.cornerHarris(gray,5,3,0.04)
ret, dst = cv2.threshold(dst,0.1*dst.max(),255,0)
dst = np.uint8(dst)
ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv2.cornerSubPix(gray,np.float32(centroids),(50,50),(-1,-1),criteria)
img[dst>0.1*dst.max()]=[0,0,255]
#find centre of each room
IMAGE_NAME = 'out.png'
#Remove Small Items
im_gray = cv2.imread(IMAGE_NAME, cv2.IMREAD_GRAYSCALE)
(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
#find all your connected components
nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(im_bw, connectivity=8)
#connectedComponentswithStats yields every seperated component with information on each of them, such as size
#the following part is just taking out the background which is also considered a component, but most of the time we don't want that.
sizes = stats[1:, -1]; nb_components = nb_components - 1
这是一个基于 findContours 使用 opencv_contrib_python-4.5.5
的示例:
import cv2 as cv
img = cv.imread("UYret.png")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
print(contours)
cv.drawContours(img, contours, -1, (0, 255, 0), 3)
cv.imwrite("out.png", img)
所选的近似方法将减少 contour-points 到房间的角落。所以 contours
returns 数组列表,每个数组都包含其中一个房间角落的坐标:
(
...
array([[[9271, 7560]],
[[9271, 7795]],
[[9782, 7795]],
[[9782, 7560]]], dtype=int32),
...
)
在 out.png
中,您可以看到已找到的房间为绿色。外面“房间”的形状也会被检测到。您可以使用 hierarchy
中返回的结构轻松过滤掉这些周围的房间(可能您只对树叶感兴趣),或者假设真实房间的大小有限。
我正在尝试为 map/navigation 应用获取每个房间的坐标。下面的代码找到每个角落,再往下的代码找到房间的中心。我不知道如何将两者结合起来,以便分别获得每个房间角落的坐标数组。
平面图图片:
#finds every corner
img = cv2.imread('out.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv2.cornerHarris(gray,5,3,0.04)
ret, dst = cv2.threshold(dst,0.1*dst.max(),255,0)
dst = np.uint8(dst)
ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv2.cornerSubPix(gray,np.float32(centroids),(50,50),(-1,-1),criteria)
img[dst>0.1*dst.max()]=[0,0,255]
#find centre of each room
IMAGE_NAME = 'out.png'
#Remove Small Items
im_gray = cv2.imread(IMAGE_NAME, cv2.IMREAD_GRAYSCALE)
(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
#find all your connected components
nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(im_bw, connectivity=8)
#connectedComponentswithStats yields every seperated component with information on each of them, such as size
#the following part is just taking out the background which is also considered a component, but most of the time we don't want that.
sizes = stats[1:, -1]; nb_components = nb_components - 1
这是一个基于 findContours 使用 opencv_contrib_python-4.5.5
的示例:
import cv2 as cv
img = cv.imread("UYret.png")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
print(contours)
cv.drawContours(img, contours, -1, (0, 255, 0), 3)
cv.imwrite("out.png", img)
所选的近似方法将减少 contour-points 到房间的角落。所以 contours
returns 数组列表,每个数组都包含其中一个房间角落的坐标:
(
...
array([[[9271, 7560]],
[[9271, 7795]],
[[9782, 7795]],
[[9782, 7560]]], dtype=int32),
...
)
在 out.png
中,您可以看到已找到的房间为绿色。外面“房间”的形状也会被检测到。您可以使用 hierarchy
中返回的结构轻松过滤掉这些周围的房间(可能您只对树叶感兴趣),或者假设真实房间的大小有限。