基于OpenCV的LiDAR地图图像直线规整化处理技术问询
LiDAR地图规整化处理问题
图像说明
初次处理后的LiDAR地图:

该图像是LiDAR传感器生成的地图经初次处理后的结果,存在大量凹凸不平区域,边缘并非标准直线。目标规整样式:

希望将处理结果调整为该图像所示的规整样式。LiDAR原始地图:

这是LiDAR扫描得到的原始地图图像。
问题描述
尝试使用Hough Line(霍夫直线)算法处理,但效果不理想,希望找到一种可适配多种场景的通用处理方法。
现有处理代码
import numpy as np import math import cv2 def get_dist(pt1, pt2): return math.hypot(pt1[0]-pt2[0], pt1[1]-pt2[1]) def reorderPts(pts): idx = np.lexsort((pts[:, 1], pts[:, 0])) pts = pts[idx] if pts[0, 1] > pts[1, 1]: pts[[0, 1]] = pts[[1, 0]] if pts[2, 1] < pts[3, 1]: pts[[2, 3]] = pts[[3, 2]] return pts def solve(src): H, W = src.shape[:2] dst = src.copy() gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) _, bin = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) bin = cv2.erode(bin, np.ones((5, 5))) cv2.floodFill(bin, np.zeros((H+2, W+2), np.uint8), (0, 0), 0) bin = cv2.medianBlur(bin, 7) nonRectArea = bin.copy() cv2.floodFill(nonRectArea, np.zeros((H+2, W+2), np.uint8), (W//2, H//2), 0) bin[np.where(nonRectArea == 255)] = 0 contours, _ = cv2.findContours(bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) rect = cv2.minAreaRect(contours[0]) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(dst, [box], 0, (0, 255, 0), 1) srcQuad = reorderPts(box.reshape(4, 2).astype(np.float32)) dw = int(get_dist(srcQuad[0], srcQuad[3])*2) dh = int(get_dist(srcQuad[0], srcQuad[1])*2) dstQuad = np.array([[0, 0], [0, dh], [dw, dh], [dw, 0]], np.float32) pers = cv2.getPerspectiveTransform(srcQuad, dstQuad) dst = cv2.warpPerspective(src, pers, (dw, dh)) gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((25, 25))) lines = cv2.HoughLinesP(thresh, 0.8, np.pi/180, 80, minLineLength=30, maxLineGap=100) w, h = dst.shape[:2] mask = np.zeros((w, h), dtype=np.uint8) for line in lines: x1, y1, x2, y2 = line[0] cv2.line(dst, (x1,y1), (x2, y2), (0,255,0), 3) cv2.line(mask, (x1,y1), (x2, y2), 255, 3) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((7, 7), dtype=np.uint8)) thresh = cv2.bitwise_and(thresh,thresh,mask=~mask) thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, np.ones((9, 9), dtype=np.uint8)) cv2.imshow("src", src) cv2.imshow("dst", dst) cv2.imshow("thresh", thresh) cv2.waitKey() src = cv2.imread('map.png') solve(src)
代码运行结果
- 结果图1:

- 结果图2:

解决方案建议
针对LiDAR地图的规整化需求,推荐以下几种通用处理思路:
轮廓多边形逼近
用cv2.approxPolyDP对提取的轮廓做多边形逼近,设置合适的精度(epsilon值取轮廓周长的0.01~0.05倍),直接将不规则轮廓拟合为四边形。之后通过透视变换把拟合区域映射成标准矩形。
示例片段:contours, _ = cv2.findContours(bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[0] epsilon = 0.02 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) if len(approx) == 4: # 后续透视变换处理逻辑形态学优化+直线拟合
在现有形态学处理基础上,先用大尺寸闭运算填充凹凸区域,提取边缘后用RANSAC直线拟合工具获取规整边缘直线,最后根据拟合直线生成标准地图。栅格地图区域规整
将LiDAR地图转为栅格地图,通过连通区域分析识别可通行区域,再对该区域做最小矩形包围,或用膨胀-腐蚀操作把不规则边缘平滑为直线,最终生成规整栅格地图。
这些方法先去除噪声和凹凸干扰,再通过几何拟合或形态学操作实现规整化,比单纯霍夫直线检测鲁棒性更强,适配更多LiDAR场景。
内容的提问来源于stack exchange,提问作者MobileRobotics
相关产品推荐
相关产品推荐

