0%

常用函数

简介

  • OpenCV 常用的函数

cv::morphologyEx() 函数 详解

cv::morphologyEx() 是 OpenCV 中的一个高级形态学变换函数,它可以执行一系列的形态学操作,如开运算、闭运算、梯度、顶帽和黑帽变换。

1. 函数原型

1
2
3
4
5
6
7
8
9
10
void cv::morphologyEx(
InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1, -1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue()
);

2. 参数说明

  • src:输入图像,通常是灰度图(CV_8U)。
  • dst:输出图像,类型与输入图像相同。
  • op:指定要执行的形态学操作,可选值:
    • cv::MORPH_OPEN(开运算)= 2
    • cv::MORPH_CLOSE(闭运算)= 3
    • cv::MORPH_GRADIENT(形态学梯度)= 4
    • cv::MORPH_TOPHAT(顶帽变换)= 5
    • cv::MORPH_BLACKHAT(黑帽变换)= 6
    • cv::MORPH_HITMISS(命中或未命中变换)= 7
  • kernel:用于形态学操作的结构元素,可以使用 cv::getStructuringElement() 生成。
  • anchor:锚点(通常为 (-1, -1),表示位于结构元素的中心)。
  • iterations:形态学操作的迭代次数(默认 1)。
  • borderType:边界填充类型,默认为 cv::BORDER_CONSTANT
  • borderValue:边界填充值(仅在 borderType = BORDER_CONSTANT 时生效)。

3. 各种形态学操作的作用

  1. 开运算(MORPH_OPEN = 先腐蚀后膨胀

    • 用于去除噪声(特别是小的白色噪声点)。
    • 适用于分离目标物体。
  2. 闭运算(MORPH_CLOSE = 先膨胀后腐蚀

    • 用于填充小的黑色孔洞(如文本或物体上的小裂缝)。
  3. 形态学梯度(MORPH_GRADIENT = 膨胀图像 - 腐蚀图像

    • 可以突出物体的边缘。
  4. 顶帽(MORPH_TOPHAT = 原图像 - 开运算

    • 适用于增强亮的区域。
  5. 黑帽(MORPH_BLACKHAT = 闭运算 - 原图像

    • 适用于增强暗的区域。

4. 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
// 读取灰度图
Mat src = imread("example.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
cout << "无法加载图像!" << endl;
return -1;
}

// 创建结构元素(3x3 矩形)
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));

// 进行形态学操作
Mat dst;
morphologyEx(src, dst, MORPH_OPEN, kernel);

// 显示图像
imshow("Original", src);
imshow("MorphologyEx - Open", dst);

waitKey(0);
return 0;
}

5. 总结

  • cv::morphologyEx() 用于执行高级形态学操作,如开闭运算、梯度、顶帽和黑帽变换。
  • 选择合适的 kernel 形状和大小对结果影响很大。
  • 在降噪、边缘检测、背景提取等任务中非常有用。

如果你有更具体的需求,可以告诉我,我可以帮助你调整参数或提供更详细的示例代码!

cv::getStructuringElement() 函数 详解

cv::getStructuringElement() 是 OpenCV 中用于生成结构元素(kernel)的函数,它在形态学操作(如腐蚀、膨胀、开运算、闭运算等)中起着关键作用。


1. 函数原型

1
2
3
4
5
Mat cv::getStructuringElement(
int shape,
Size ksize,
Point anchor = Point(-1, -1)
);

2. 参数说明

  • shape:结构元素的形状,可以取以下值:
    • cv::MORPH_RECT(矩形)
    • cv::MORPH_ELLIPSE(椭圆)
    • cv::MORPH_CROSS(十字形)
  • ksize:结构元素的大小(Size(width, height))。
  • anchor(可选):锚点,默认为 (-1, -1),表示锚点在结构元素的中心。

3. 形状示例

1. 矩形 (MORPH_RECT)

1
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));

输出:

1
2
3
4
5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

矩形结构元素通常用于基本的膨胀和腐蚀操作。


2. 椭圆 (MORPH_ELLIPSE)

1
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));

输出:

1
2
3
4
5
0 0 1 0 0
0 1 1 1 0
1 1 1 1 1
0 1 1 1 0
0 0 1 0 0

适用于平滑形状的处理,比如去除噪声而不改变物体的整体形态。


3. 十字形 (MORPH_CROSS)

1
Mat kernel = getStructuringElement(MORPH_CROSS, Size(5, 5));

输出:

1
2
3
4
5
0 0 1 0 0
0 0 1 0 0
1 1 1 1 1
0 0 1 0 0
0 0 1 0 0

适用于精确提取垂直或水平线结构。


4. 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
// 读取灰度图
Mat src = imread("example.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
cout << "无法加载图像!" << endl;
return -1;
}

// 生成结构元素
Mat rectKernel = getStructuringElement(MORPH_RECT, Size(5, 5));
Mat ellipseKernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));
Mat crossKernel = getStructuringElement(MORPH_CROSS, Size(5, 5));

// 形态学操作
Mat dst;
morphologyEx(src, dst, MORPH_OPEN, rectKernel);

// 显示图像
imshow("Original", src);
imshow("Morphology - Open", dst);

waitKey(0);
return 0;
}

5. 结构元素选择建议

  • 去除小噪点:使用 MORPH_ELLIPSE,避免矩形对图像的边缘造成较大影响。
  • 连通细小区域:使用 MORPH_RECT,对所有方向的膨胀或腐蚀效果均匀。
  • 提取直线结构:使用 MORPH_CROSS,对十字交叉的结构较敏感。

6. 总结

  • cv::getStructuringElement() 生成形态学操作所需的核(kernel)。
  • 选择合适的形状和大小对形态学处理的结果影响很大。
  • 常用于 cv::erode()cv::dilate()cv::morphologyEx()

如果你有更具体的应用需求,欢迎讨论! 😊

cv::drawContours() 函数 详解

cv::drawContours() 是 OpenCV 提供的一个函数,用于在图像上绘制轮廓(contours)。它通常与 cv::findContours() 搭配使用,后者用于检测图像中的轮廓,而 cv::drawContours() 则用于可视化这些轮廓。


1. 函数原型

1
2
3
4
5
6
7
8
9
10
11
void cv::drawContours(
InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar& color,
int thickness = 1,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
);

2. 参数说明

  • image:输入/输出图像(Mat 类型),轮廓会被绘制在这个图像上,必须是彩色(如 CV_8UC3)或 灰度CV_8UC1)图像。
  • contours:轮廓数组,通常由 cv::findContours() 生成,类型为 vector<vector<Point>>
  • contourIdx
    • 指定要绘制的轮廓索引(从 0 开始)。
    • 若设为 -1,则绘制所有轮廓。
  • color:轮廓的颜色(Scalar(B, G, R))。
  • thickness(可选):轮廓的线条宽度:
    • 设为 12 以绘制细线。
    • 设为 FILLED-1 以填充轮廓。
  • lineType(可选):线条类型:
    • LINE_8(默认):8 连接线。
    • LINE_4:4 连接线。
    • LINE_AA:抗锯齿线。
  • hierarchy(可选):轮廓的层级信息,通常由 cv::findContours() 计算,若不使用可设为 noArray()
  • maxLevel(可选):绘制的轮廓层级,默认值 INT_MAX 绘制所有层级。
  • offset(可选):用于偏移轮廓坐标,默认为 (0, 0)

3. 使用示例

示例 1:绘制所有轮廓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
// 读取灰度图
Mat src = imread("example.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
cout << "无法加载图像!" << endl;
return -1;
}

// 二值化处理
Mat binary;
threshold(src, binary, 128, 255, THRESH_BINARY);

// 轮廓检测
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

// 绘制轮廓
Mat dst = Mat::zeros(src.size(), CV_8UC3);
drawContours(dst, contours, -1, Scalar(0, 255, 0), 2);

// 显示结果
imshow("Contours", dst);
waitKey(0);
return 0;
}

说明:

  • threshold() 用于将图像转换为二值图,便于轮廓检测。
  • findContours() 负责提取轮廓。
  • drawContours() 用绿色 (Scalar(0, 255, 0)) 绘制所有轮廓(contourIdx = -1)。

示例 2:绘制特定轮廓

1
drawContours(dst, contours, 0, Scalar(0, 0, 255), 2);

说明:

  • 仅绘制索引 0 的轮廓,颜色为红色 (Scalar(0, 0, 255))。

示例 3:填充轮廓

1
drawContours(dst, contours, -1, Scalar(255, 255, 255), FILLED);

说明:

  • thickness = FILLED(或 -1)表示填充轮廓区域。

示例 4:使用层级信息

1
drawContours(dst, contours, -1, Scalar(0, 255, 0), 2, LINE_8, hierarchy, 1);

说明:

  • 只绘制层级 1 内的轮廓(子轮廓)。

4. 轮廓查找模式 findContours() 相关模式

  • cv::RETR_EXTERNAL:仅返回外部轮廓。
  • cv::RETR_LIST:返回所有轮廓,无层级关系。
  • cv::RETR_CCOMP:返回两个层级的轮廓(外部和内部)。
  • cv::RETR_TREE:返回完整的层级结构。

5. 总结

  • cv::drawContours() 用于在图像上绘制轮廓。
  • 轮廓通常由 cv::findContours() 提取。
  • 通过 contourIdx 控制绘制的轮廓索引,-1 代表绘制所有轮廓。
  • 可选择不同的 thickness 以绘制边缘或填充轮廓。

这个函数常用于对象检测、形状分析、轮廓追踪等计算机视觉任务。🚀 如果你有具体应用需求,可以告诉我,我可以帮你优化代码!

cv::boundingRect() 函数 详解

cv::boundingRect() 是 OpenCV 中用于计算给定点集(通常是轮廓)的最小外接矩形的函数。它在目标检测、形状分析等任务中常用,例如从二值图像中提取目标区域。


1. 函数原型

1
cv::Rect cv::boundingRect(InputArray points);

2. 参数说明

  • points:输入点集(可以是 std::vector<cv::Point>std::vector<std::vector<cv::Point>>)。
  • 返回值:一个 cv::Rect 矩形,表示包围整个点集的最小水平对齐矩形

3. 使用示例

示例 1:计算并绘制外接矩形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
// 读取灰度图
Mat src = imread("example.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
cout << "无法加载图像!" << endl;
return -1;
}

// 二值化
Mat binary;
threshold(src, binary, 128, 255, THRESH_BINARY);

// 轮廓检测
vector<vector<Point>> contours;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

// 计算外接矩形并绘制
Mat dst;
cvtColor(binary, dst, COLOR_GRAY2BGR); // 转换为彩色图像以便绘制
for (size_t i = 0; i < contours.size(); i++) {
Rect boundingBox = boundingRect(contours[i]);
rectangle(dst, boundingBox, Scalar(0, 255, 0), 2); // 绿色矩形
}

// 显示结果
imshow("Bounding Rectangles", dst);
waitKey(0);
return 0;
}

说明:

  1. threshold() 转换为二值图,便于轮廓检测。
  2. findContours() 提取轮廓。
  3. boundingRect() 计算每个轮廓的最小外接矩形。
  4. rectangle() 绘制矩形框。

4. 注意事项

  • 矩形是水平对齐的(不旋转),如果需要旋转最小外接矩形,请使用 cv::minAreaRect()
  • 适用于单个轮廓或点集,如果传入多个轮廓,需要逐个处理。

5. 相关函数

函数 作用
cv::boundingRect() 计算最小外接矩形(水平对齐)。
cv::minAreaRect() 计算旋转的最小外接矩形。
cv::fitEllipse() 计算最小外接椭圆(点集需≥5个)。

6. 总结

  • cv::boundingRect() 计算包围点集的最小水平对齐矩形
  • 适用于目标检测、形状分析等任务。
  • 如果需要旋转矩形,使用 cv::minAreaRect()

🚀 如果有更具体的需求,可以告诉我,我可以提供更详细的代码示例!

感谢老板支持!敬礼(^^ゞ