1. 从零开始创建OpenCV画布
在计算机视觉项目中,画布是我们进行图像处理和图形绘制的基础工作区。OpenCV提供了简单而强大的画布创建功能,让我们能够像在真实画布上一样进行各种图形操作。
1.1 创建空白画布的基本方法
创建空白画布是OpenCV图形操作的起点。最常用的方法是使用cv::Mat类的构造函数:
cpp复制#include <opencv2/opencv.hpp>
int main() {
// 创建一个800x600的白色画布(3通道BGR格式)
cv::Mat canvas(600, 800, CV_8UC3, cv::Scalar(255, 255, 255));
// 显示画布
cv::imshow("My Canvas", canvas);
cv::waitKey(0);
return 0;
}
这段代码创建了一个800像素宽、600像素高的白色画布。关键参数说明:
600:画布高度(行数)800:画布宽度(列数)CV_8UC3:图像类型,8位无符号整数,3通道(BGR)cv::Scalar(255, 255, 255):初始化颜色(白色)
提示:在OpenCV中,图像矩阵的第一个维度是高度(行数),第二个维度是宽度(列数),这与我们通常的"宽×高"习惯相反,初学者容易混淆。
1.2 画布的色彩空间选择
根据不同的应用场景,我们可以选择不同的色彩空间和数据类型:
-
灰度画布:单通道,适合简单的图像处理
cpp复制cv::Mat grayCanvas(600, 800, CV_8UC1, cv::Scalar(128)); // 中灰色 -
彩色画布:三通道BGR,最常用
cpp复制cv::Mat colorCanvas(600, 800, CV_8UC3, cv::Scalar(0, 0, 255)); // 纯红色 -
带透明通道的画布:四通道BGRA
cpp复制cv::Mat transparentCanvas(600, 800, CV_8UC4, cv::Scalar(0, 255, 0, 128)); // 半透明绿色 -
高精度画布:16位或浮点类型,适合专业图像处理
cpp复制cv::Mat highPrecisionCanvas(600, 800, CV_32FC3, cv::Scalar(1.0f, 0.5f, 0.0f)); // 浮点橙色
1.3 画布初始化技巧
在实际项目中,我们经常需要特定的初始化方式:
cpp复制// 创建渐变背景的画布
cv::Mat gradientCanvas(600, 800, CV_8UC3);
for (int y = 0; y < gradientCanvas.rows; ++y) {
for (int x = 0; x < gradientCanvas.cols; ++x) {
// 从左到右的蓝色渐变
gradientCanvas.at<cv::Vec3b>(y, x) = cv::Vec3b(
255 * x / gradientCanvas.cols, // Blue
128, // Green
255 - 255 * x / gradientCanvas.cols // Red
);
}
}
// 创建带网格线的画布
cv::Mat gridCanvas(600, 800, CV_8UC3, cv::Scalar(240, 240, 240));
const int gridSize = 20;
for (int x = 0; x < gridCanvas.cols; x += gridSize) {
cv::line(gridCanvas, cv::Point(x, 0), cv::Point(x, gridCanvas.rows), cv::Scalar(200, 200, 200));
}
for (int y = 0; y < gridCanvas.rows; y += gridSize) {
cv::line(gridCanvas, cv::Point(0, y), cv::Point(gridCanvas.cols, y), cv::Scalar(200, 200, 200));
}
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 静态图形绘制技术
OpenCV提供了丰富的2D绘图函数,可以绘制各种几何图形和文字。这些功能在数据可视化、界面设计和计算机视觉结果标注中非常有用。
2.1 基本几何图形绘制
2.1.1 线条绘制
线条是最基础的图形元素,OpenCV提供了灵活的线条绘制函数:
cpp复制// 绘制一条从(100,100)到(700,500)的红色直线,线宽3像素
cv::line(canvas,
cv::Point(100, 100),
cv::Point(700, 500),
cv::Scalar(0, 0, 255), // BGR颜色值
3); // 线宽
// 绘制带抗锯齿的线条(需要先转换为浮点再绘制)
cv::Mat tempCanvas;
canvas.convertTo(tempCanvas, CV_32FC3, 1.0/255);
cv::line(tempCanvas,
cv::Point2f(150.5f, 150.5f),
cv::Point2f(750.5f, 550.5f),
cv::Scalar(0.0f, 0.0f, 1.0f),
3,
cv::LINE_AA); // 抗锯齿标志
tempCanvas.convertTo(canvas, CV_8UC3, 255);
2.1.2 矩形绘制
矩形绘制有两种常用方式:实心矩形和边框矩形:
cpp复制// 绘制边框矩形(绿色,线宽2)
cv::rectangle(canvas,
cv::Point(200, 150),
