文档
OpenCV 毕设入门教程——计算机视觉实战
前言
OpenCV 是毕设中图像处理/计算机视觉方向的首选库。常见毕设题目:车牌识别、人脸考勤系统、手势识别、医学图像分割、车道线检测。
第一章:OpenCV 核心数据结构
cv::Mat —— 一切图像的基础
cv::Mat img; // 空矩阵
img = cv::imread("photo.jpg"); // 读取图片
img = cv::Mat(480, 640, CV_8UC3); // 创建 480×640 彩色图
常用属性:
img.rows/img.cols— 高/宽img.channels()— 通道数(灰度=1,彩色=3)img.type()— 数据类型
像素访问
// 灰度图
uchar pixel = gray.at<uchar>(y, x);
// 彩色图 (BGR)
cv::Vec3b pixel = img.at<cv::Vec3b>(y, x);
uchar blue = pixel[0], green = pixel[1], red = pixel[2];
第二章:毕设十大常用操作
1. 灰度化
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
2. 高斯模糊
cv::GaussianBlur(src, dst, cv::Size(5,5), 0);
3. 边缘检测
cv::Canny(gray, edges, 50, 150);
4. 二值化
cv::threshold(gray, binary, 127, 255, cv::THRESH_BINARY);
// 自适应二值化(光照不均时用)
cv::adaptiveThreshold(gray, binary, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C,
cv::THRESH_BINARY, 11, 2);
5. 形态学操作
cv::dilate(binary, dilated, kernel); // 膨胀
cv::erode(binary, eroded, kernel); // 腐蚀
cv::morphologyEx(binary, opened, cv::MORPH_OPEN, kernel); // 开运算
6. 轮廓查找
std::vector<std::vector<cv::Point>> contours;
cv::findContours(binary, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
for (size_t i = 0; i < contours.size(); i++) {
cv::drawContours(img, contours, i, cv::Scalar(0, 255, 0), 2);
}
7. 人脸检测
cv::CascadeClassifier face_cascade;
face_cascade.load("haarcascade_frontalface_default.xml");
std::vector<cv::Rect> faces;
face_cascade.detectMultiScale(gray, faces, 1.1, 3);
8. 颜色空间转换
cv::cvtColor(img, hsv, cv::COLOR_BGR2HSV);
// HSV 更适合颜色筛选:H(色调) 0-180, S(饱和度) 0-255, V(明度) 0-255
9. 图像缩放
cv::resize(src, dst, cv::Size(320, 240));
10. 视频读取
cv::VideoCapture cap(0); // 摄像头
// cv::VideoCapture cap("video.mp4"); // 视频文件
cv::Mat frame;
while (cap.read(frame)) {
cv::imshow("Video", frame);
if (cv::waitKey(30) == 27) break; // ESC 退出
}
第三章:毕设经典方案——车牌识别
简化流水线
读图 → 灰度 → 高斯模糊 → Canny边缘 → 轮廓查找 →
筛选矩形轮廓(车牌区域)→ OCR 字符识别
关键代码片段
// 轮廓筛选:找到近似矩形的轮廓
for (const auto& contour : contours) {
double peri = cv::arcLength(contour, true);
std::vector<cv::Point> approx;
cv::approxPolyDP(contour, approx, 0.02 * peri, true);
// 4顶点 + 面积合理 → 可能是车牌
if (approx.size() == 4 && cv::contourArea(approx) > 1000) {
cv::Rect roi = cv::boundingRect(approx);
cv::Mat plate = img(roi);
// 送入 OCR...
}
}
第四章:答辩准备
- 准备对比图:原图 vs 处理结果,效果最直观
- 录屏演示:实时摄像头识别比静态图片更有说服力
- 说明参数调优:展示你对算法理解的程度
- 备用方案:如果现场光线差,准备一段预先录好的视频
思考题
- Canny 的高低阈值如何影响边缘检测结果?
- 为什么颜色检测常用 HSV 而不是 RGB?
- 如何提升人脸检测在侧脸/遮挡情况下的准确率?