0黑色,1白色
static inline cv::Mat find_road(cv::Mat& frame)
{
// 获取一个2x2的十字形结构元素
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(2, 2));
// 对二值化后的帧进行开运算,去除噪声
cv::morphologyEx(binarizedFrame, morphologyExFrame, cv::MORPH_OPEN, kernel);
// 创建一个全零的掩膜,大小为行跟踪高度+2,列跟踪宽度+2
cv::Mat mask = cv::Mat::zeros(line_tracking_height + 2, line_tracking_width + 2, CV_8UC1);
// 设置种子点,位于行跟踪宽度的中间,行跟踪高度的倒数第二行
cv::Point seedPoint(line_tracking_width / 2, line_tracking_height - 10);
// 在开运算后的帧中绘制一个半径为10的白色圆
cv::circle(morphologyExFrame, seedPoint, 10, 255, -1);
// 设置填充颜色为128
cv::Scalar newVal(128);
// 设置上下差异为20
cv::Scalar loDiff = cv::Scalar(20);
cv::Scalar upDiff = cv::Scalar(20);
// 对开运算后的帧进行泛洪填充,填充颜色为128,上下差异为20
cv::floodFill(morphologyExFrame, mask, seedPoint, newVal, 0, loDiff, upDiff, 8);
// 创建一个全零的输出图像,大小为行跟踪宽度,行跟踪高度
cv::Mat outputImage = cv::Mat::zeros(line_tracking_width, line_tracking_height, CV_8UC1);
// 将掩膜中的图像复制到输出图像中
mask(cv::Rect(1, 1, line_tracking_width, line_tracking_height)).copyTo(outputImage);
// 返回输出图像
return outputImage;
}
# 1. 结构元素创建
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(2, 2));
- 功能:创建2x2的十字形结构元素
- 为什么用:十字形结构能有效处理线状结构(如道路标线),小尺寸(2x2)适合去除微小噪声
- 效果:为后续形态学操作准备基础核
# 2. 开运算去噪
cv::morphologyEx(binarizedFrame, morphologyExFrame, cv::MORPH_OPEN, kernel);
- 功能:对二值图像执行开运算(先腐蚀后膨胀)
- 为什么用:
- 消除细小噪声点(如路面碎石、图像噪点)
- 保持道路主体结构完整(十字核能更好保留线状特征)
- 效果:获得更干净的道路二值图像
# 3. 掩膜初始化
cv::Mat mask = cv::Mat::zeros(line_tracking_height + 2, line_tracking_width + 2, CV_8UC1);
- 功能:创建比原图大2像素的掩膜
- 为什么+2:OpenCV的floodFill要求掩膜尺寸必须为
(width+2) x (height+2) - 效果:为泛洪填充提供符合规范的存储空间
# 4. 种子点设置
cv::Point seedPoint(line_tracking_width / 2, line_tracking_height - 10);
- 功能:在图像底部中间位置设置种子点
- 为什么用:
- 假设车辆通常位于道路中央(宽度中点)
- 距底部10像素:避开图像边缘,确保在道路区域内
- 效果:为区域生长确定起始位置
# 5. 绘制种子区域
cv::circle(morphologyExFrame, seedPoint, 10, 255, -1);
- 功能:以种子点为中心画半径为10的实心白圆
- 为什么用:
- 确保种子区域足够大(避免落在小孔洞/裂缝中)
- 强制连接可能断裂的道路区域
- 效果:创建可靠的泛洪填充起始区域
# 6. 泛洪填充参数
cv::Scalar newVal(128); // 填充值
cv::Scalar loDiff(20), upDiff(20); // 容差
- 参数意义:
newVal=128:填充灰度值(中等灰色)loDiff/upDiff=20:允许的像素值浮动范围
- 为什么用20:在二值图像中,20的容差能覆盖从深灰(235)到纯白(255)的渐变
# 7. 执行泛洪填充
cv::floodFill(morphologyExFrame, mask, seedPoint, newVal, 0, loDiff, upDiff, 8);
- 功能:从种子点开始区域生长
- 参数解析:
8:使用8连通域(考虑对角线方向)0:无标志位(默认行为)
- 效果:将道路连通区域标记为128(掩膜中对应区域变为1)
# 8. 提取道路掩膜
cv::Mat outputImage = cv::Mat::zeros(line_tracking_width, line_tracking_height, CV_8UC1);
mask(cv::Rect(1, 1, line_tracking_width, line_tracking_height)).copyTo(outputImage);
- 功能:从大掩膜中裁剪有效区域
- Rect(1,1,...):去除floodFill添加的边界
- 效果:获得与原图同尺寸的道路二值掩膜(道路=1,背景=0)

