环境
- OpenCV 4.5.0
- C++
步骤
- 图像输入
- 灰度处理
- 滤波处理
- 边缘提取
- 感兴趣区域
- 霍夫变换
- 直线拟合
代码分析
1. 图像输入
Mat image;
image = imread("img/whiteCarLaneSwitch.jpg");
Mat cv::imread ( const String & filename,
int flags = IMREAD_COLOR
)
参数1:filename—需要载入图片的路径名。主要有绝对路径法、相对路径法、命令行参数法等,具体可参考使用imread()函数读取图片的六种正确姿势。
参数2:flags—加载图像的颜色类型(cv::ImreadModes)。默认是3通道BGR彩色图像。
2. 灰度处理
Mat gray_image;
cv::cvtColor(image, gray_image, COLOR_BGR2GRAY);
void cv::cvtColor(cv::InputArray src,
cv::OutputArray dst,
int code,
int dstCn = 0)
参数1:src—输入图像即要进行颜色空间变换的原图像。
参数2:dst—输出图像即进行颜色空间变换后存储图像。
参数3:code—转换的代码或标识,即在此确定将什么制式的图片转换成什么制式的图片。cv::ColorConversionCodes
参数4:dstCn—目标图像通道数,如果取值为0,则由src和code决定。
3. 滤波处理
Mat blur_image;
//bilateralFilter(gray_image, blur_image, 13, 15, 15);
cv::GaussianBlur(gray_image, blur_image, cv::Size(3, 3), 0, 0);
GaussianBlur函数
void cv::GaussianBlur(cv::InputArray src,
cv::OutputArray dst,
cv::Size ksize,
double sigmaX,
double sigmaY = (0.0),
int borderType = 4)
参数1:src—输入图像;图像可以具有任意数量的通道,这些通道是独立处理的。
参数2:dst—输出图像;与src具有相同大小和类型。
参数3:ksize—高斯核大小;ksize.width和ksize.height可以不同,但它们都必须为正奇数。 或者,它们可以为零,然后根据sigma计算得出。
参数4:sigmaX—高斯核在x方向的标准差。
参数5:sigmaY—高斯核在y方向的标准差。sigmaY=0时,其值自动由sigmaX确定(sigmaY=sigmaX);sigmaY=sigmaX=0时,它们的值将由ksize.width和ksize.height自动确定。
参数6:borderType—像素外插策略。
4. 边缘提取
Mat canny_image;
cv::Canny(blur_image, canny_image, 50, 150, 3);
Canny函数
void cv::Canny(cv::InputArray image,
cv::OutputArray edges,
double threshold1,
double threshold2,
int apertureSize = 3,
bool L2gradient = false)
参数1:image—输入图像;8位。
参数2:edges—输出边缘;单通道8位图像,其大小与image相同。
参数3:threshold1—阈值1
参数4:threshold2—阈值2
参数5:apertureSize—Sobel算子大小。
参数6:L2gradient—是否采用更精确的方式计算图像梯度。
关于阈值:
- 两个参数不区分较大阈值和较小阈值,函数会自动比较区分两个阈值的大小,不过一般情况下,较大阈值与较小阈值的比值在2:1到3:1之间。
- 如果该像素的梯度值小于较小阈值,则该像素为非边缘像素;
- 如果该像素的梯度值大于较大阈值,则该像素为边缘像素;
- 如果该像素的梯度值介于较小阈值与较大阈值之间,需要进一步检测该像素的3×3邻域内的8个点,如果这8个点内有一个或以上的点梯度超过了较大阈值,则该像素为边缘像素,否则不是边缘像素。
5. 感兴趣区域
//感兴趣区域 ROI
Mat region_of_interest