0%

OpenCV 面试笔记

简介

  • OpenCV 相关编程技巧

OpenCV 面试知识点

以下是针对OpenCV面试的核心知识点总结,涵盖高频问题、核心概念及实战代码示例,帮助系统化复习:


一、OpenCV 核心数据结构

1. cv::Mat

  • 核心特性:多维数组,支持图像、矩阵存储,自动内存管理(引用计数)。
  • 浅拷贝 vs 深拷贝
    • 浅拷贝:Mat B = A;(共享数据指针,引用计数+1)。
    • 深拷贝:Mat B = A.clone();A.copyTo(B);(复制数据到新内存)。
  • 关键操作
    1
    2
    3
    4
    cv::Mat img = cv::imread("image.jpg"); // 读取BGR图像
    cv::Mat roi = img(cv::Rect(10,10,100,100)); // ROI操作
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY); // 颜色空间转换

2. cv::UMat

  • 作用:利用OpenCL加速计算(GPU/CPU异构计算),适用于大规模数据处理。
  • 示例
    1
    2
    cv::UMat uSrc, uDst;
    cv::blur(src, uDst, cv::Size(5,5)); // 自动使用硬件加速

二、图像处理基础

1. 图像滤波

  • 高斯滤波(去噪):
    1
    cv::GaussianBlur(src, dst, cv::Size(5,5), 1.5); // 核大小需为奇数
  • 中值滤波(去除椒盐噪声):
    1
    cv::medianBlur(src, dst, 5);

2. 边缘检测

  • Canny边缘检测
    1
    cv::Canny(src, edges, 50, 150); // 双阈值:低阈值50,高阈值150
  • Sobel算子(梯度计算):
    1
    2
    cv::Sobel(src, gradX, CV_16S, 1, 0); // X方向梯度
    cv::convertScaleAbs(gradX, absGradX); // 转回8UC1

3. 形态学操作

  • 腐蚀与膨胀
    1
    2
    3
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3,3));
    cv::erode(src, dst, kernel); // 腐蚀
    cv::dilate(src, dst, kernel); // 膨胀
  • 开运算与闭运算(去噪/填充孔洞):
    1
    2
    cv::morphologyEx(src, dst, cv::MORPH_OPEN, kernel);
    cv::morphologyEx(src, dst, cv::MORPH_CLOSE, kernel);

三、特征检测与匹配

1. 关键点检测

  • SIFT(尺度不变特征):
    1
    2
    3
    4
    auto sift = cv::SIFT::create();
    std::vector<cv::KeyPoint> keypoints;
    cv::Mat descriptors;
    sift->detectAndCompute(img, cv::noArray(), keypoints, descriptors);
  • ORB(实时特征,替代SIFT):
    1
    2
    auto orb = cv::ORB::create();
    orb->detectAndCompute(img, cv::noArray(), keypoints, descriptors);

2. 特征匹配

  • BFMatcher(暴力匹配)
    1
    2
    3
    cv::BFMatcher matcher(cv::NORM_HAMMING);
    std::vector<cv::DMatch> matches;
    matcher.match(descriptors1, descriptors2, matches);
  • FLANN匹配(高效近似)
    1
    2
    auto flann = cv::FlannBasedMatcher::create();
    flann->match(descriptors1, descriptors2, matches);

3. RANSAC与外点剔除

1
2
3
std::vector<cv::Point2f> points1, points2;
// 提取匹配点对...
cv::Mat H = cv::findHomography(points1, points2, cv::RANSAC, 3.0);

四、视频处理与摄像头

1. 视频读取与处理

1
2
3
4
5
6
cv::VideoCapture cap("video.mp4");
while (cap.read(frame)) {
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
// 处理每一帧...
}
cap.release(); // 释放资源

2. 摄像头实时处理

1
2
3
4
5
6
7
8
cv::VideoCapture cap(0); // 打开默认摄像头
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
while (true) {
cap.read(frame);
cv::imshow("Live", frame);
if (cv::waitKey(1) == 27) break; // ESC退出
}

五、性能优化技巧

  1. 避免冗余拷贝
    • 使用cv::Mat::rowRange/colRange或ROI操作处理局部图像。
  2. 并行化加速
    • 启用OpenCV的TBB或OpenMP支持(编译时配置-DWITH_TBB=ON)。
  3. 使用UMat加速
    1
    2
    cv::UMat uSrc, uDst;
    cv::cvtColor(uSrc, uDst, cv::COLOR_BGR2GRAY); // 自动使用OpenCL

六、实战高频问题

1. 如何实现图像拼接(Image Stitching)?

  • 步骤:特征检测 → 匹配 → 计算单应性矩阵 → 图像融合。
  • OpenCV API:
    1
    2
    cv::Ptr<cv::Stitcher> stitcher = cv::Stitcher::create();
    cv::Stitcher::Status status = stitcher->stitch(imgs, panorama);

2. 如何检测并绘制轮廓?

1
2
3
std::vector<std::vector<cv::Point>> contours;
cv::findContours(binaryImg, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
cv::drawContours(resultImg, contours, -1, cv::Scalar(0,255,0), 2);

3. 如何计算直方图?

1
2
3
4
5
6
cv::Mat hist;
int channels[] = {0};
int histSize[] = {256};
float range[] = {0, 256};
const float* ranges[] = {range};
cv::calcHist(&grayImg, 1, channels, cv::Mat(), hist, 1, histSize, ranges);

七、OpenCV版本差异

  • OpenCV3 vs OpenCV4
    • CV_LOAD_IMAGE_COLORcv::IMREAD_COLOR
    • SIFT/SURF移至opencv_contrib,需额外编译。
    • C++11 API成为主流(如cv::Ptr代替裸指针)。

附:面试常见问题分类

类别 高频问题
数据结构 Mat内存管理、浅拷贝与深拷贝、数据类型转换
图像处理 滤波、边缘检测、形态学操作、直方图均衡化
特征与匹配 SIFT/ORB原理、RANSAC、特征匹配优化
视频处理 摄像头操作、视频帧处理、光流法(Optical Flow)
性能优化 UMat、多线程、算法复杂度分析
项目经验 图像拼接、人脸检测、AR应用、算法调参技巧

掌握以上知识点后,建议结合实际项目代码(如GitHub开源项目)加深理解,并练习手写核心算法(如边缘检测、特征匹配)的伪代码。

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