Qt之OpenCv 灰度处理、均值滤波、边缘检测学习
本章来学习一下opencv常见的操作,首先看下我们的Qt制作好的界面:
源码在后面。
灰度化:
均值滤波:
边缘检测:
那么对应以下的主要函数源码以及学习:
首先是加载图像的:
-
QString imagePath = QFileDialog::getOpenFileName(this,tr("打开文件"),"C:/Users/ALIENTEK/Desktop","(所有图像(*.jpg *.png *.bmp))");
:- 使用
QFileDialog
类的静态函数getOpenFileName
弹出一个文件选择对话框。 this
作为第一个参数,通常表示当前窗口对象,用于指定对话框的父窗口。tr("打开文件")
是对话框的标题,用于显示给用户。"C:/Users/ALIENTEK/Desktop"
是对话框打开时的初始目录。"所有图像(*.jpg *.png *.bmp))"
是文件过滤器,用于限制用户只能选择特定类型的图像文件。- 该函数返回用户选择的文件路径,存储在
imagePath
变量中。
- 使用
-
if(imagePath.isEmpty()){ return; }
:- 检查
imagePath
是否为空,如果用户没有选择文件或者取消了文件选择对话框,imagePath
将为空字符串。在这种情况下,函数直接返回,不进行后续操作。
- 检查
-
srcImage = imread(imagePath.toStdString());
:- 使用 OpenCV 的
imread
函数读取用户选择的图像文件,并将图像数据存储在srcImage
(类型为cv::Mat
)中。 imagePath.toStdString()
将 Qt 的 QString 类型的文件路径转换为标准 C++ 字符串,以便 OpenCV 函数能够使用。
- 使用 OpenCV 的
-
cvtColor(srcImage,srcImage,CV_BGR2RGB);
:- 使用 OpenCV 的
cvtColor
函数将加载的图像从 BGR 颜色空间转换为 RGB 颜色空间。这是因为 Qt 的QImage
通常使用 RGB 格式,而 OpenCV 默认使用 BGR 格式。
- 使用 OpenCV 的
-
QImage disaplayImg = QImage(srcImage.data,srcImage.cols,srcImage.rows,srcImage.cols * srcImage.channels(),QImage::Format_RGB888);
:- 创建一个
QImage
对象disaplayImg
,从 OpenCV 的Mat
对象srcImage
中获取图像数据。 srcImage.data
是图像的像素数据指针。srcImage.cols
和srcImage.rows
分别是图像的宽度和高度。srcImage.cols * srcImage.channels()
是每行的字节数,其中channels()
表示图像的通道数。QImage::Format_RGB888
指定图像的格式为 RGB 8-8-8,即每个像素由三个 8 位的颜色通道组成。
- 创建一个
-
QImage disimage = imageCenter(disaplayImg,ui->opencv_show1);
:- 调用一个名为
imageCenter
的函数,传入刚刚创建的QImage
对象disaplayImg
和一个界面组件指针ui->opencv_show1
。这个函数可能是用于对图像进行某种处理或调整图像在界面上的显示位置。
- 调用一个名为
-
ui->opencv_show1->setPixmap(QPixmap::fromImage(disimage));
:- 将处理后的
QImage
对象disimage
转换为QPixmap
对象,然后设置到一个界面组件(可能是一个标签或图像显示区域)ui->opencv_show1
上,以显示图像。
- 将处理后的
灰度处理:
-
Mat grayImage;
:- 定义一个 OpenCV 的
Mat
对象grayImage
,用于存储灰度图像。
- 定义一个 OpenCV 的
-
cvtColor(srcImage,grayImage,COLOR_BGR2GRAY);
:- 使用 OpenCV 的
cvtColor
函数将原始的彩色图像srcImage
转换为灰度图像,并存储在grayImage
中。这里的COLOR_BGR2GRAY
表示从 BGR(蓝绿红)颜色空间转换为灰度空间。
- 使用 OpenCV 的
-
cvtColor(grayImage,grayImage,COLOR_GRAY2RGB);
:- 再次使用
cvtColor
函数将灰度图像grayImage
转换回 RGB 颜色空间。这一步可能是为了使灰度图像能够以彩色格式显示在使用 RGB 格式的界面组件上。虽然图像实际上是灰度的,但以 RGB 格式显示可以让灰度值在三个通道上重复,从而在某些显示场景下更方便地展示灰度图像。
- 再次使用
-
QImage disaplayImg = QImage(grayImage.data,grayImage.cols,grayImage.rows,grayImage.cols * grayImage.channels(),QImage::Format_RGB888);
:- 创建一个
QImage
对象disaplayImg
,从转换后的grayImage
中获取图像数据。参数的含义与前面类似,这里的QImage::Format_RGB888
表示图像格式为 RGB 8-8-8,即使图像实际上是灰度的,也以这种格式表示。
- 创建一个
-
QImage disimage = imageCenter(disaplayImg,ui->opencv_show2);
:- 调用一个名为
imageCenter
的函数,传入刚刚创建的QImage
对象disaplayImg
和一个界面组件指针ui->opencv_show2
。这个函数可能是用于对图像进行某种处理或调整图像在界面上的显示位置。
- 调用一个名为
-
ui->opencv_show2->setPixmap(QPixmap::fromImage(disimage));
:- 将处理后的
QImage
对象disimage
转换为QPixmap
对象,然后设置到一个界面组件(可能是一个标签或图像显示区域)ui->opencv_show2
上,以显示灰度图像。
- 将处理后的
均值滤波:
-
Mat blurImage;
:- 定义一个 OpenCV 的
Mat
对象blurImage
,用于存储经过均值滤波处理后的图像。
- 定义一个 OpenCV 的
-
blur(srcImage, blurImage, Size(4, 4));
:- 使用 OpenCV 的
blur
函数对原始图像srcImage
进行均值滤波操作,并将结果存储在blurImage
中。 Size(4, 4)
指定了均值滤波的内核大小为 4x4。内核越大,滤波效果越平滑,但也可能导致图像细节丢失更多。
- 使用 OpenCV 的
-
QImage disaplayImg = QImage(blurImage.data, blurImage.cols, blurImage.rows, blurImage.cols * blurImage.channels(), QImage::Format_RGB888);
:- 创建一个
QImage
对象disaplayImg
,从滤波后的图像blurImage
中获取图像数据。参数的含义与前面类似,这里的QImage::Format_RGB888
表示图像格式为 RGB 8-8-8。
- 创建一个
-
QImage disimage = imageCenter(disaplayImg, ui->opencv_show2);
:- 调用一个名为
imageCenter
的函数,传入刚刚创建的QImage
对象disaplayImg
和一个界面组件指针ui->opencv_show2
。这个函数可能是用于对图像进行某种处理或调整图像在界面上的显示位置。
- 调用一个名为
-
ui->opencv_show2->setPixmap(QPixmap::fromImage(disimage));
:- 将处理后的
QImage
对象disimage
转换为QPixmap
对象,然后设置到一个界面组件(可能是一个标签或图像显示区域)ui->opencv_show2
上,以显示经过均值滤波处理后的图像。
- 将处理后的
边缘检测:有三种方法
-
if(srcImage.empty()){ return; }
:- 检查原始图像
srcImage
是否为空。如果为空,说明没有加载有效的图像,函数直接返回,不进行后续处理。
- 检查原始图像
-
Mat cannyImage, grayImage;
:- 定义两个 OpenCV 的
Mat
对象cannyImage
和grayImage
,分别用于存储边缘检测后的图像和灰度图像。
- 定义两个 OpenCV 的
-
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
:- 将原始的彩色图像
srcImage
转换为灰度图像grayImage
,因为许多边缘检测算法通常在灰度图像上效果更好。
- 将原始的彩色图像
1. Canny 边缘检测方法
Canny(grayImage, cannyImage, 200, 1);
:- 使用 OpenCV 的
Canny
函数进行边缘检测。 - 第一个参数是输入的灰度图像
grayImage
。 - 第二个参数是输出的边缘检测图像
cannyImage
。 - 后面两个参数分别是低阈值和高阈值。低于低阈值的像素点被认为不是边缘,高于高阈值的像素点被认为是边缘,介于两者之间的像素点如果与高于高阈值的像素点相连则被认为是边缘。调整这两个阈值可以控制检测到的边缘的数量和强度。
- 使用 OpenCV 的
2. Laplacian 边缘检测方法
Laplacian(grayImage, cannyImage, grayImage.depth());
:- 使用 OpenCV 的
Laplacian
函数进行边缘检测。 - 第一个参数是输入的灰度图像
grayImage
。 - 第二个参数是输出的边缘检测图像
cannyImage
。 - 第三个参数是输出图像的深度,这里使用与输入图像相同的深度。Laplacian 边缘检测是通过计算图像的二阶导数来检测边缘的,通常会产生较暗的结果,因为它对图像中的细节和噪声比较敏感。
- 使用 OpenCV 的
3. 基于 Sobel 算子的边缘检测及加权融合方法
Mat sobel_x, sobel_y;
:- 定义两个
Mat
对象sobel_x
和sobel_y
,分别用于存储水平方向和垂直方向的 Sobel 边缘检测结果。
- 定义两个
Sobel(grayImage, sobel_x, CV_8U, 1.2, 0);
和Sobel(grayImage, sobel_y, CV_8U, 1.2, 0);
:- 使用 OpenCV 的
Sobel
函数进行边缘检测。 - 第一个参数是输入的灰度图像
grayImage
。 - 第二个参数分别是输出的水平和垂直方向的边缘检测图像
sobel_x
和sobel_y
。 - 第三个参数
CV_8U
表示输出图像的数据类型为 8 位无符号整数。 - 第四个参数和第五个参数分别表示在 x 和 y 方向上的导数阶数以及用于计算导数的内核大小。这里导数阶数为 1.2,第五个参数为 0,表示只计算 x 方向(第一个调用)或 y 方向(第二个调用)的边缘。增大导数阶数可能会使边缘更明显,但也可能引入更多噪声。改变内核大小也会影响边缘检测的结果,较大的内核可能会使边缘更平滑,但也可能丢失一些细节。
- 使用 OpenCV 的
addWeighted(sobel_x, 0.7, sobel_y, 0.3, 2, cannyImage);
:- 使用 OpenCV 的
addWeighted
函数对水平和垂直方向的 Sobel 边缘检测结果进行加权融合。 - 第一个参数是水平方向的边缘检测图像
sobel_x
。 - 第二个参数是
sobel_x
的权重系数 0.7,表示在融合结果中sobel_x
的贡献占比。 - 第三个参数是垂直方向的边缘检测图像
sobel_y
。 - 第四个参数是
sobel_y
的权重系数 0.3,表示在融合结果中sobel_y
的贡献占比。 - 第五个参数是一个标量值 2,表示加到加权和上的亮度调整值。
- 第六个参数是输出的融合结果图像
cannyImage
。
- 使用 OpenCV 的
-
cvtColor(cannyImage, cannyImage, COLOR_GRAY2BGR);
:- 如果前面的边缘检测结果是灰度图像,将其转换回 BGR 颜色空间,以便以彩色格式显示在使用 RGB 格式的界面组件上。虽然边缘检测结果通常是灰度的,但以彩色格式显示可以在某些情况下更方便地观察边缘。
-
QImage disaplayImg = QImage(cannyImage.data, cannyImage.cols, cannyImage.rows, cannyImage.cols * cannyImage.channels(), QImage::Format_RGB888);
:- 创建一个
QImage
对象disaplayImg
,从边缘检测后的图像cannyImage
中获取图像数据。参数的含义与前面类似,这里的QImage::Format_RGB888
表示图像格式为 RGB 8-8-8。
- 创建一个
-
QImage disimage = imageCenter(disaplayImg, ui->opencv_show2);
:- 调用一个名为
imageCenter
的函数,传入刚刚创建的QImage
对象disaplayImg
和一个界面组件指针ui->opencv_show2
。这个函数可能是用于对图像进行某种处理或调整图像在界面上的显示位置。
- 调用一个名为
-
ui->opencv_show2->setPixmap(QPixmap::fromImage(disimage));
:- 将处理后的
QImage
对象disimage
转换为QPixmap
对象,然后设置到一个界面组件(可能是一个标签或图像显示区域)ui->opencv_show2
上,以显示边缘检测后的图像。
- 将处理后的
源码链接:https://download.csdn.net/download/weixin_57695658/89738890