OpenCV-将摄像头拍摄的画面储存为视频

这篇博客详细介绍了如何利用OpenCV的Python接口将摄像头捕捉到的实时画面保存为视频文件,包括必要的代码示例和步骤说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

opencv-python

代码如下:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)
#Define the codec and create VideoWrite object, 10 is fps, (640,480) is screen size
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('./video/cameravideo/cameraoutput.avi', fourcc, 10, (640,480))

while(1):
    #get a frame
    ret, frame = cap.read()
    #save a frame
    out.write(frame)
    #show a frame
    cv2.imshow("capture", frame)
    #press 'q' to quit
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
		
cap.release()
out.release()
cv2.destroyAllWindows()

opencv c++ 代码:

#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/video/video.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>

<think>嗯,用户想用C++和OpenCV实现摄像头画面矫正。首先,我得回忆一下摄像头标定和畸变矫正的步骤。根据之前看到的引用内容,标定需要先获取标定板的图像,比如棋盘格。然后检测角点,计算相机参数,最后应用矫正。 首先,用户可能需要了解整个流程的步骤。比如,准备标定板、采集图像、角点检测、计算参数、矫正图像。这些步骤在引用[2]和引用[3]里都有提到。特别是引用[2]详细说明了使用C++实现的流程,而引用[3]提到了calibrateCamera函数的使用。 然后,用户可能需要具体的代码示例。比如,如何读取图像,找到角点,存储对象点和图像点。然后调用calibrateCamera得到相机矩阵和畸变系数,最后用undistort函数矫正图像。需要注意的是,标定板的参数,比如棋盘格的内部角点数量,需要正确设置,否则角点检测会失败。 另外,用户可能遇到的问题包括标定板图像采集不够多或者角度不够多样,导致标定不准确。或者角点检测失败,这时候可能需要检查标定板的摆放或者光照条件。引用[3]中的total_err变量可以用来评估标定的误差,用户应该关注这个误差值,确保它在合理范围内。 最后,用户可能还需要知道如何实时应用矫正,而不仅仅是处理静态图像。这时候可能需要结合摄像头实时捕获的画面,逐帧进行矫正。这部分可能需要用到VideoCapture类,在循环中处理每一帧。 总结一下,回答应该分步骤讲解流程,提供代码示例,指出注意事项,提醒用户如何验证标定结果的有效性。同时,根据用户提供的引用,引用相关部分来支持回答的正确性,比如calibrateCamera的参数设置和误差计算。</think>以下是使用C++和OpenCV实现摄像头画面矫正的完整步骤指南: ### 一、实现步骤 1. **标定板准备** - 使用国际象棋棋盘格(默认尺寸8x6),文件路径需与代码匹配[^2] - 打印标定板保持平面平整,建议使用A4纸打印 2. **数据采集** ```cpp #include <opencv2/opencv.hpp> cv::VideoCapture cap(0); std::vector<cv::Mat> calibrationImages; while(calibrationImages.size() < 20) { // 至少采集20张不同角度图像 cv::Mat frame; cap >> frame; if(cv::waitKey(30) == 's') { // 按s键保存 calibrationImages.push_back(frame.clone()); } } ``` 3. **角点检测** ```cpp cv::Size patternSize(7,7); // 棋盘格内部角点数(需小于实际格子数) std::vector<std::vector<cv::Point2f>> imagePoints; for(auto& img : calibrationImages) { cv::Mat gray; cvtColor(img, gray, cv::COLOR_BGR2GRAY); std::vector<cv::Point2f> corners; bool found = cv::findChessboardCorners(gray, patternSize, corners); if(found) { cornerSubPix(gray, corners, cv::Size(11,11), cv::Size(-1,-1), cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.1)); imagePoints.push_back(corners); } } ``` 4. **标定计算** ```cpp std::vector<std::vector<cv::Point3f>> objectPoints; cv::Mat cameraMatrix, distCoeffs; std::vector<cv::Mat> rvecs, tvecs; // 生成3D坐标(假设棋盘格尺寸为25mm) for(int i=0; i<imagePoints.size(); ++i) { std::vector<cv::Point3f> obj; for(int y=0; y<patternSize.height; ++y) for(int x=0; x<patternSize.width; ++x) obj.emplace_back(x*25.0f, y*25.0f, 0.0f); objectPoints.push_back(obj); } // 执行标定[^3] double reprojErr = cv::calibrateCamera(objectPoints, imagePoints, calibrationImages[0].size(), cameraMatrix, distCoeffs, rvecs, tvecs, cv::CALIB_FIX_K3 | cv::CALIB_ZERO_TANGENT_DIST); std::cout << "标定误差: " << reprojErr << " (建议小于0.5)" << std::endl; ``` 5. **实时矫正** ```cpp cv::Mat map1, map2; cv::initUndistortRectifyMap(cameraMatrix, distCoeffs, cv::Mat(), cameraMatrix, calibrationImages[0].size(), CV_16SC2, map1, map2); while(true) { cv::Mat frame, undistorted; cap >> frame; cv::remap(frame, undistorted, map1, map2, cv::INTER_LINEAR); cv::imshow("原始画面", frame); cv::imshow("矫正画面", undistorted); if(cv::waitKey(1) == 27) break; } ``` ### 二、关键参数说明 1. **CALIB_FIX_K3**:固定径向畸变的k3系数,避免过拟合 2. **标定误差(reprojErr)**:反映标定精度,建议控制在0.5像素以下[^3] 3. **map1/map2**:预计算的矫正映射表,提升实时处理效率 ### 三、注意事项 1. 标定板需覆盖画面不同区域(中心、四角、边缘) 2. 不同拍摄角度间隔建议大于15度 3. 光照应均匀,避免反光和阴影 4. 保存标定参数(建议使用FileStorage): ```cpp cv::FileStorage fs("calibration.yml", cv::FileStorage::WRITE); fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs; ``` ### 四、效果验证 $$ \text{矫正质量} = \frac{\sum_{i=1}^{n}| \text{原始边缘曲率} - \text{矫正后边缘曲率} |}{n} $$ 当该值趋近于0时,说明畸变矫正效果良好[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值