c++视觉处理膨胀腐蚀
膨胀腐蚀的区别
膨胀(Dilation)和腐蚀(Erosion)是形态学图像处理中的两种基本操作,它们有不同的效果和应用:
-
膨胀(Dilation):
- 膨胀操作用于增加物体的尺寸,使物体变大。
- 它通过将每个像素替换为其邻域内的最大值来实现。
- 膨胀通常用于连接分离的物体、填充空洞、增加物体的面积,以及提取物体的外部轮廓。
- 在二值图像中,膨胀可以用于扩展白色物体(前景)的区域,通常与其他形态学操作(如开运算或闭运算)一起使用。
-
腐蚀(Erosion):
- 腐蚀操作用于减小物体的尺寸,使物体变小。
- 它通过将每个像素替换为其邻域内的最小值来实现。
- 腐蚀通常用于分离接触的物体、去除小的噪点、缩小物体的面积,以及提取物体的内部结构。
- 在二值图像中,腐蚀可以用于缩小白色物体(前景)的区域。
总结来说,膨胀使物体变大,而腐蚀使物体变小。这两种操作通常在形态学图像处理中配合使用,以实现不同的图像增强、分割和去噪等应用。同时,它们也是其他复杂形态学操作(如开运算和闭运算)的基本构建块。
膨胀:cv::dilate()
cv::dilate()
是OpenCV中的一个图像形态学操作函数,用于执行图像的膨胀操作。膨胀是形态学处理中的一种操作,它可以用来增强二值图像中的目标区域。膨胀操作通过将目标区域扩展,可以填充空洞、连接断裂的区域以及增加目标的尺寸。
下面是 cv::dilate()
函数的基本语法:
void cv::dilate(
cv::InputArray src, // 输入图像
cv::OutputArray dst, // 输出图像
cv::InputArray kernel, // 膨胀核
cv::Point anchor = cv::Point(-1,-1),
int iterations = 1,
int borderType = cv::BORDER_CONSTANT,
const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);
参数解释:
src
:输入图像。dst
:输出图像,将膨胀后的图像存储在这里。kernel
:膨胀核,它定义了膨胀操作的形状和大小。通常使用cv::getStructuringElement()
来创建膨胀核。anchor
:锚点位置,指示膨胀核的中心。默认值为 (-1, -1),表示核的中心。iterations
:膨胀操作的迭代次数。默认值为 1。borderType
:边界处理方式,用于处理边界像素。默认值为cv::BORDER_CONSTANT
。borderValue
:在边界处理方式为cv::BORDER_CONSTANT
时使用的边界像素值。默认值为cv::morphologyDefaultBorderValue()
。
膨胀操作的基本思想是将核在图像上滑动,如果核覆盖区域内的任何像素值为非零(白色),则将目标像素置为白色。这导致了目标区域的扩张。
创建形态学操作的结构元素:cv::getStructuringElement()
cv::getStructuringElement()
是OpenCV中的一个函数,用于创建形态学操作的结构元素(structuring element)。形态学操作(如腐蚀、膨胀、开运算、闭运算等)通常需要一个结构元素,该元素定义了操作的形状和大小。cv::getStructuringElement()
函数用于创建这样的结构元素。
以下是 cv::getStructuringElement()
函数的基本语法:
cv::Mat cv::getStructuringElement(
int shape, // 结构元素的形状,如 cv::MORPH_RECT、cv::MORPH_ELLIPSE、cv::MORPH_CROSS 等
cv::Size ksize, // 结构元素的大小,通常是一个奇数大小的矩阵
cv::Point anchor = cv::Point(-1,-1)
);
参数解释:
shape
:结构元素的形状,可以是以下常量之一:cv::MORPH_RECT
:矩形结构元素。cv::MORPH_ELLIPSE
:椭圆结构元素。cv::MORPH_CROSS
:十字形结构元素。
ksize
:结构元素的大小,通常是一个奇数大小的矩阵,表示结构元素的宽度和高度。anchor
:锚点位置,通常为 (-1, -1),表示结构元素的中心。
cv::getStructuringElement()
函数返回一个 cv::Mat
对象,表示所创建的结构元素。
以下是一个示例,演示如何使用 cv::getStructuringElement()
创建不同形状的结构元素:
#include <opencv2/opencv.hpp>
int main() {
// 创建矩形结构元素
cv::Mat rectangularElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
// 创建椭圆形结构元素
cv::Mat ellipticalElement = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));
// 创建十字形结构元素
cv::Mat crossElement = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(5, 5));
// 显示创建的结构元素
cv::imshow("Rectangular Element", rectangularElement);
cv::imshow("Elliptical Element", ellipticalElement);
cv::imshow("Cross Element", crossElement);
cv::waitKey(0);
return 0;
}
在这个示例中,我们创建了三种不同形状的结构元素:矩形、椭圆和十字形。您可以根据需要调整 cv::MORPH_RECT
、cv::MORPH_ELLIPSE
和 cv::MORPH_CROSS
常量以选择不同的结构元素形状。这些结构元素通常用于形态学操作,例如腐蚀和膨胀。
使用cv::getStructuringElement()
3x3的矩形核再使用膨胀cv::dilate()
操作
以下是一个示例,演示如何使用 cv::dilate()
函数对二值图像执行膨胀操作:
#include <opencv2/opencv.hpp>
int main() {
// 读取输入二值图像
cv::Mat binaryImage = cv::imread("binary_image.png", cv::IMREAD_GRAYSCALE);
if (binaryImage.empty()) {
std::cerr << "Failed to open the input image!" << std::endl;
return -1;
}
// 定义膨胀核(3x3的矩形核)
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
// 执行膨胀操作
cv::Mat dilatedImage;
cv::dilate(binaryImage, dilatedImage, kernel);
// 显示原始二值图像和膨胀后的图像
cv::namedWindow("Binary Image", cv::WINDOW_NORMAL);
cv::namedWindow("Dilated Image", cv::WINDOW_NORMAL);
cv::imshow("Binary Image", binaryImage);
cv::imshow("Dilated Image", dilatedImage);
cv::waitKey(0);
return 0;
}
在这个示例中,我们首先读取了一个二值图像,然后定义了一个膨胀核(3x3的矩形核)。接下来,我们使用 cv::dilate()
函数对输入的二值图像执行膨胀操作,并将结果存储在 dilatedImage
中。最后,我们显示了原始二值图像和膨胀后的图像。
腐蚀:cv::erode()
腐蚀是图像形态学处理中的一种基本操作,通常用于减小二值图像中的目标对象的尺寸。腐蚀操作通过在图像上滑动一个结构元素(通常是一个小的矩形或圆形核),将核中心与图像中的像素进行比较,如果核中的所有像素都与图像中的像素匹配(都是白色像素),则将中心像素保留为白色,否则将其置为黑色。
在OpenCV中,可以使用 cv::erode()
函数来执行腐蚀操作。
以下是 cv::erode()
函数的基本语法:
void cv::erode(
cv::InputArray src, // 输入图像
cv::OutputArray dst, // 输出图像
cv::InputArray kernel, // 结构元素核
cv::Point anchor = cv::Point(-1,-1),
int iterations = 1,
int borderType = cv::BORDER_CONSTANT,
const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);
参数解释:
src
:输入图像,通常是一个二值图像。dst
:输出图像,将腐蚀后的图像存储在这里。kernel
:结构元素核,用于定义腐蚀操作的形状和大小。anchor
:锚点位置,指示结构元素核的中心。默认值为 (-1, -1),表示核的中心。iterations
:腐蚀操作的迭代次数。默认值为 1。borderType
:边界处理方式,用于处理边界像素。默认值为cv::BORDER_CONSTANT
。borderValue
:在边界处理方式为cv::BORDER_CONSTANT
时使用的边界像素值。默认值为cv::morphologyDefaultBorderValue()
。
以下是一个示例,演示如何使用 cv::erode()
函数对二值图像执行腐蚀操作:
#include <opencv2/opencv.hpp>
int main() {
// 读取输入二值图像
cv::Mat binaryImage = cv::imread("binary_image.png", cv::IMREAD_GRAYSCALE);
if (binaryImage.empty()) {
std::cerr << "Failed to open the input image!" << std::endl;
return -1;
}
// 定义腐蚀核(3x3的矩形核)
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
// 执行腐蚀操作
cv::Mat erodedImage;
cv::erode(binaryImage, erodedImage, kernel);
// 显示原始二值图像和腐蚀后的图像
cv::namedWindow("Binary Image", cv::WINDOW_NORMAL);
cv::namedWindow("Eroded Image", cv::WINDOW_NORMAL);
cv::imshow("Binary Image", binaryImage);
cv::imshow("Eroded Image", erodedImage);
cv::waitKey(0);
return 0;
}
在这个示例中,我们首先读取了一个二值图像,然后定义了一个腐蚀核(3x3的矩形核)。接下来,我们使用 cv::erode()
函数对输入的二值图像执行腐蚀操作,并将结果存储在 erodedImage
中。最后,我们显示了原始二值图像和腐蚀后的图像。腐蚀操作通常用于去除小的噪点、分离接触的目标对象等。
使用本地相机实时膨胀处理
#include <opencv2/opencv.hpp>
// 全局变量,用于存储滑动条的值
int kernelSize = 1; // 初始核大小为1
// 回调函数,用于处理滑动条的值变化
void onTrackbar(int value, void* userdata) {
cv::VideoCapture* cap = static_cast<cv::VideoCapture*>(userdata);
// 创建窗口
cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);
while (true) {
cv::Mat frame;
// 从相机中读取一帧图像
*cap >> frame;
if (frame.empty()) {
std::cerr << "Failed to read frame from the camera!" << std::endl;
break;
}
// 定义膨胀核
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(kernelSize, kernelSize));
// 创建一个膨胀后的图像副本
cv::Mat dilatedFrame;
// 使用膨胀操作处理图像
cv::dilate(frame, dilatedFrame, kernel);
// 显示实时摄像头图像和膨胀后的图像
cv::imshow("Live Camera Feed", frame);
cv::imshow("Dilated Frame", dilatedFrame);
// 检查键盘输入,如果按下ESC键,退出循环
char key = cv::waitKey(1);
if (key == 27) // 27对应ESC键的ASCII码
break;
}
}
int main() {
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cerr << "Could not open the camera!" << std::endl;
return -1;
}
// 创建窗口
cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);
// 创建滑动条
cv::createTrackbar("Kernel Size", "Live Camera Feed", &kernelSize, 30, onTrackbar, &cap);
// 初始化一次滑动条回调函数以显示默认值
onTrackbar(kernelSize, &cap);
// 释放摄像头资源和关闭窗口
cap.release();
cv::destroyAllWindows();
return 0;
}
使用本地相机实时腐蚀处理
#include <opencv2/opencv.hpp>
// 全局变量,用于存储滑动条的值
int kernelSize = 1; // 初始核大小为1
// 回调函数,用于处理滑动条的值变化
void onTrackbar(int value, void* userdata) {
cv::VideoCapture* cap = static_cast<cv::VideoCapture*>(userdata);
// 创建窗口
cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);
while (true) {
cv::Mat frame;
// 从相机中读取一帧图像
*cap >> frame;
if (frame.empty()) {
std::cerr << "Failed to read frame from the camera!" << std::endl;
break;
}
// 定义腐蚀核
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(kernelSize, kernelSize));
// 创建一个腐蚀后的图像副本
cv::Mat erodedFrame;
// 使用腐蚀操作处理图像
cv::erode(frame, erodedFrame, kernel);
// 显示实时摄像头图像和腐蚀后的图像
cv::imshow("Live Camera Feed", frame);
cv::imshow("Eroded Frame", erodedFrame);
// 检查键盘输入,如果按下ESC键,退出循环
char key = cv::waitKey(1);
if (key == 27) // 27对应ESC键的ASCII码
break;
}
}
int main() {
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cerr << "Could not open the camera!" << std::endl;
return -1;
}
// 创建窗口
cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);
// 创建滑动条
cv::createTrackbar("Kernel Size", "Live Camera Feed", &kernelSize, 30, onTrackbar, &cap);
// 初始化一次滑动条回调函数以显示默认值
onTrackbar(kernelSize, &cap);
// 释放摄像头资源和关闭窗口
cap.release();
cv::destroyAllWindows();
return 0;
}