C++ OpenCV(超详细)

C++ OpenCV 图像处理核心方法速查

快速解决

cv::imread() 可直接读取图像文件,cv::imshow() 显示图像,cv::waitKey() 捕获键盘事件,这组方法能快速完成图像加载和可视化操作。

常用方法

方法名称 功能描述 示例代码 使用频率
cv::imread() 读取图像文件 imread("test.jpg", IMREAD_COLOR) ★★★★★★
cv::imshow() 显示图像 imshow("Output", image) ★★★★★★
cv::cvtColor() 颜色空间转换 cvtColor(src, dst, COLOR_BGR2GRAY) ★★★★★
cv::Canny() 边缘检测 Canny(gray, edges, 50, 150) ★★★★
cv::VideoCapture 视频流读取 VideoCapture(0) ★★★★
cv::resize() 图像缩放 resize(src, dst, Size(), 0.5, 0.5) ★★★
cv::warpPerspective 透视变换 warpPerspective(src, dst, M, Size()) ★★

详细说明

图像读取与显示

cv::Mat image = cv::imread("input.jpg", cv::IMREAD_COLOR); // 读取彩色图像
cv::namedWindow("Input", cv::WINDOW_NORMAL);                // 创建可调整大小的窗口
cv::imshow("Input", image);                                   // 显示图像
cv::waitKey(0);                                               // 等待按键退出

灰度图像转换

cv::Mat gray;                                                 // 定义目标矩阵
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);                // 转换颜色空间
cv::imshow("Grayscale", gray);                                // 显示灰度图像
cv::imwrite("output_gray.png", gray);                         // 保存处理结果

边缘检测应用

cv::Mat edges;                                                // 定义边缘矩阵
cv::Canny(gray, edges, 100, 200);                               // 双阈值边缘检测
std::vector<cv::Vec4i> lines;                                 // 存储霍夫直线
cv::HoughLinesP(edges, lines, 1, CV_PI/180, 50, 50, 10);        // 概率霍夫变换
for (const auto& line : lines) {                              // 绘制检测结果
    cv::line(image, cv::Point(line[0], line[1]), 
             cv::Point(line[2], line[3]), cv::Scalar(0,0,255)); 
}

高级技巧

实时视频边缘检测

cv::VideoCapture cap(0);                                      // 打开默认摄像头
cv::Mat frame, gray, edges;
while (true) {
    cap >> frame;                                             // 读取视频帧
    cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);            // 转换颜色空间
    cv::Canny(gray, edges, 50, 150);                            // 边缘检测
    cv::imshow("Edge Detection", edges);                      // 显示实时结果
    if (cv::waitKey(30) == 27) break;                         // 按ESC退出
}

多线程图像处理

#include <thread>
void processImage(const cv::Mat& input, std::promise<cv::Mat>& result) {
    cv::Mat processed;
    cv::GaussianBlur(input, processed, cv::Size(5,5), 0);        // 高斯模糊处理
    result.set_value(processed);                                // 返回结果
}

cv::Mat original = cv::imread("input.jpg");
std::promise<cv::Mat> blurPromise;
std::thread t(processImage, original, std::ref(blurPromise));
cv::Mat blurred = blurPromise.get_future().get();               // 获取处理结果
t.join();

图像拼接技术

std::vector<cv::Mat> images = {img1, img2};                   // 待拼接图像
cv::Mat pano;
cv::Stitcher::Status status = cv::Stitcher::createDefault(true) // 创建拼接器
    ->stitch(images, pano);                                    // 执行拼接
if (status == cv::Stitcher::OK) {
    cv::imwrite("panorama.jpg", pano);                        // 保存全景图
}

常见问题

Q: 使用 cv::imread 时返回空矩阵
A: 检查文件路径是否正确,建议使用绝对路径;验证文件扩展名是否匹配实际格式;添加路径是否存在中文字符

Q: imshow 窗口无法显示图像
A: 确保调用 namedWindow 创建窗口;检查矩阵是否空;添加 waitKey(1) 确保窗口刷新

Q: 颜色空间转换结果异常
A: 确认输入输出矩阵类型是否匹配;检查转换代码如 COLOR_BGR2GRAY 是否正确;避免重复转换操作

Q: 透视变换后图像黑屏
A: 检查变换矩阵计算是否正确;确保目标尺寸参数与变换矩阵维度匹配;使用 normalize() 预处理矩阵

总结

C++ OpenCV 提供了完整的图像处理方法链,从基础IO到复杂变换都能通过核心函数组合实现,掌握常用函数组合能显著提升开发效率。