网站开发大学有哪些,网站建设公司做网站需要注意什么,汕头百姓网二手房出售,南昌网站建设品牌若该文为原创文章#xff0c;转载请注明原文出处 本文章博客地址#xff1a;https://blog.csdn.net/qq21497936/article/details/136535848 各位读者#xff0c;知识无穷而人力有穷#xff0c;要么改需求#xff0c;要么找专业人士#xff0c;要么自己研究 红胖子(红模仿…若该文为原创文章转载请注明原文出处 本文章博客地址https://blog.csdn.net/qq21497936/article/details/136535848 各位读者知识无穷而人力有穷要么改需求要么找专业人士要么自己研究 红胖子(红模仿)的博文大全开发技术集合包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等持续更新中…点击传送门
OpenCV开发专栏点击传送门
上一篇《OpenCV开发笔记七十五相机标定矫正中使用remap重映射进行畸变矫正》 下一篇持续补充中… 前言 知道图像畸变矫映射的原理之后那么如何得到相机的内参是矫正的第一步内参决定了内参矩阵中心点、焦距等用内参矩阵才能计算出投影矩阵从而将原本畸变的图像矫正为平面投影图像。 本篇描述了相机成形的原理并绘制出识别的角点。 Demo 相机成形的原理
小孔成像原理 得到矩阵计算原理 得到计算过程 相机的畸变 相机的畸变是指相机镜头对物体所成的像相对于物体本身而言的失真程度它是光学透镜的固有特性。畸变产生的原因主要是透镜的边缘部分和中心部分的放大倍率不一样。 畸变分为以下几类
径向畸变切向畸变薄棱镜畸变 通常情况下径向畸变的影响要远远大于其他畸变。畸变是不可消除的但在实际的应用中可以通过一些软件来进行畸变的补偿如OpenCV、MATLAB等。
径向畸变 主要由透镜不同部位放大倍率不同造成它又分为枕形畸变和桶形畸变两种。枕形畸变也称为鞍形形变视野中边缘区域的放大率远大于光轴中心区域的放大率常用在远摄镜头中。桶形畸变则与枕形畸变相反视野中光轴中心区域的放大率远大于边缘区域的放大率常出现在广角镜头和鱼眼镜头中。
切向畸变 主要由透镜安装与成像平面不平行造成类似于透视原理如近大远小、圆变椭圆等。
薄棱镜畸变 由透镜设计缺陷和加工安装误差造成又称为线性畸变。其影响较小一般忽略不计。 棋牌识别步骤
步骤一标定采集的数据图像 采集一张棋盘图片要确认他是可以被识别的。 读取图像这里由于图片较大我们重设大小为原来宽高的1/2 // 使用图片std::string srcFilePath D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/chessboard.png;
// std::string srcFilePath D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/24.jpg;cv::Mat srcMat cv::imread(srcFilePath);int chessboardColCornerCount 6;int chessboardRowCornerCount 9;// 步骤一读取文件
// cv::imshow(1, srcMat);
// cv::waitKey(0);// 步骤二缩放太大了缩放下可省略cv::resize(srcMat, srcMat, cv::Size(srcMat.cols / 2, srcMat.rows / 2));cv::Mat srcMat2 srcMat.clone();cv::Mat srcMat3 srcMat.clone();
// cv::imshow(2, srcMat);
// cv::waitKey(0);步骤二图像处理提取角点并绘制出来 先灰度化然后输入预制的纵向横向角数量使用棋盘角点函数提取角点 // 步骤三灰度化cv::Mat grayMat;cv::cvtColor(srcMat, grayMat, cv::COLOR_BGR2GRAY);cv::imshow(3, grayMat);
// cv::waitKey(0);// 步骤四检测角点std::vectorcv::Point2f vectorPoint2fCorners;bool patternWasFound false;patternWasFound cv::findChessboardCorners(grayMat,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK | cv::CALIB_CB_NORMALIZE_IMAGE);/*enum { CALIB_CB_ADAPTIVE_THRESH 1, // 使用自适应阈值将图像转化成二值图像CALIB_CB_NORMALIZE_IMAGE 2, // 归一化图像灰度系数(用直方图均衡化或者自适应阈值)CALIB_CB_FILTER_QUADS 4, // 在轮廓提取阶段使用附加条件排除错误的假设CALIB_CB_FAST_CHECK 8 // 快速检测};*/cvui::printf(srcMat, 0, 0, 1.0, 0xFF0000, found %s, patternWasFound ? true : false);cvui::printf(srcMat, 0, 24, 1.0, 0xFF0000, count %d, vectorPoint2fCorners.size());qDebug() __FILE__ __LINE__ vectorPoint2fCorners.size();// 步骤五绘制棋盘点cv::drawChessboardCorners(srcMat2,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,patternWasFound);步骤三进行亚像素角点计算进一步提取图片准确性
// 步骤六进一步提取亚像素角点cv::TermCriteria criteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, // 类型30, // 参数二: 最大次数0.001); // 参数三迭代终止阈值/*#define CV_TERMCRIT_ITER 1 // 终止条件为: 达到最大迭代次数终止#define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER //#define CV_TERMCRIT_EPS 2 // 终止条件为: 迭代到阈值终止*/qDebug() __FILE__ __LINE__ vectorPoint2fCorners.size();cv::cornerSubPix(grayMat,vectorPoint2fCorners,cv::Size(11, 11),cv::Size(-1, -1),criteria);函数原型
findChessboardCorners识别预制棋盘角点数量的棋盘 OpenCV 中用于检测图像中棋盘角点的函数。
bool cv::findChessboardCorners(InputArray image,Size patternSize,OutputArray corners,int flagsCALIB_CB_ADAPTIVE_THRESHCALIB_CB_NORMALIZE_IMAGE)参数解释
image输入的图像通常是一个灰度图像因为角点检测在灰度空间中进行更为准确。patternSize棋盘的内角点数量例如一个 8x6 的棋盘会有 48 个内角点所以 patternSize 会是 Size(8, 6)。corners检测到的角点输出数组。flags不同的标志用于指定角点检测的不同方法。可以是以下的一个或多个标志的组合 CALIB_CB_ADAPTIVE_THRESH使用自适应阈值将图像转换为二值图像而不是使用固定的全局阈值。 CALIB_CB_NORMALIZE_IMAGE在寻找角点之前先对图像进行归一化以提高鲁棒性。 CALIB_CB_FAST_CHECK仅检查角点候选者中的少量点用于快速检测但可能不如标准方法准确。 函数返回值是一个布尔值如果找到足够的角点以形成一个棋盘模式则返回 true否则返回 false。 findChessboardCorners 函数通常用于相机标定通过检测棋盘角点来确定图像与真实世界之间的对应关系。一旦角点被检测到就可以使用这些点来估计相机的内参如焦距、主点和外参如旋转和平移矩阵。
drawChessboardCorners绘制棋盘角点 OpenCV中的一个函数用于在检测到的棋盘角点周围绘制方框。这对于相机标定、图像对齐等应用非常有用。
void cv::drawChessboardCorners(InputOutputArray image,Size patternSize,InputArray corners,bool patternWasFound)参数解释
image输入的图像通常是一个彩色图像函数会在这个图像上绘制角点。patternSize棋盘的内角点数量例如一个 8x6 的棋盘会有 48 个内角点所以 patternSize 会是 Size(8, 6)。corners检测到的角点通常是通过 findChessboardCorners 函数得到的。patternWasFound一个布尔值表示是否找到了足够的角点来形成一个棋盘模式。如果为 true则函数会在角点周围绘制彩色的方框如果为 false则只会绘制白色的方框。 这个函数通常与 findChessboardCorners 结合使用以检测图像中的棋盘角点并在检测到的角点周围绘制方框。这对于视觉校准和相机标定等任务非常有用。
TermCriteria迭代终止模板类 TermCriteria是OpenCV中用于指定迭代算法终止条件的模板类。它取代了之前的CvTermCriteria并且在许多OpenCV算法中作为迭代求解的结构被使用。
struct TermCriteria { enum { COUNT1, MAX_ITERCOUNT, EPS2 }; TermCriteria(); TermCriteria(int type, int maxCount, double epsilon); TermCriteria(const CvTermCriteria criteria);
};构造时需要三个参数
类型type它决定了迭代终止的条件。类型可以是CV_TERMCRIT_ITER、CV_TERMCRIT_EPS或CV_TERMCRIT_ITERCV_TERMCRIT_EPS。在C中这些宏对应的版本分别为TermCriteria::COUNT、TermCriteria::EPS。 CV_TERMCRIT_ITER或TermCriteria::COUNT表示迭代终止条件为达到最大迭代次数 CV_TERMCRIT_EPS或TermCriteria::EPS表示迭代到特定的阈值就终止 CV_TERMCRIT_ITERCV_TERMCRIT_EPS则表示两者都作为迭代终止条件。迭代的最大次数maxCount这是算法可以执行的最大迭代次数。特定的阈值epsilon当满足这个精确度时迭代算法会停止。
cornerSubPix亚像素角点提取 OpenCV中用于精确化角点位置其函数原型如下
void cv::cornerSubPix(InputArray image,InputOutputArray corners,Size winSize,Size zeroZone,TermCriteria criteria);参数解释
image输入图像的像素矩阵最好是8位灰度图像这样检测效率会更高。corners初始的角点坐标向量同时作为亚像素坐标位置的输出因此需要是浮点型数据。winSize搜索窗口的大小它表示的是搜索窗口的一半尺寸。zeroZone死区的一半尺寸死区是搜索窗口内不对中央位置做求和运算的区域。这是为了避免自相关矩阵出现某些可能的奇异性。criteria角点搜索的停止条件通常包括迭代次数、角点位置变化量或角点误差变化量等。 cornerSubPix函数用于在初步提取的角点信息上进一步提取亚像素信息从而提高相机标定的精度。在相机标定、目标跟踪和三维重建等应用中精确的角点位置是非常重要的因此cornerSubPix函数在这些领域有广泛的应用。 Demo源码
void OpenCVManager::testFindChessboardCorners()
{
#define FindChessboardCornersUseCamera 1
#if !FindChessboardCornersUseCamera// 使用图片std::string srcFilePath D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/chessboard.png;
// std::string srcFilePath D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/24.jpg;cv::Mat srcMat cv::imread(srcFilePath);
#else// 使用摄像头cv::VideoCapture capture;// 插入USB摄像头默认为0if(!capture.open(0)){qDebug() __FILE__ __LINE__ Failed to open camera: 0;}else{qDebug() __FILE__ __LINE__ Succeed to open camera: 0;}while(true){cv::Mat srcMat;capture srcMat;
#endifint chessboardColCornerCount 6;int chessboardRowCornerCount 9;// 步骤一读取文件
// cv::imshow(1, srcMat);
// cv::waitKey(0);// 步骤二缩放太大了缩放下可省略cv::resize(srcMat, srcMat, cv::Size(srcMat.cols / 2, srcMat.rows / 2));cv::Mat srcMat2 srcMat.clone();cv::Mat srcMat3 srcMat.clone();
// cv::imshow(2, srcMat);
// cv::waitKey(0);// 步骤三灰度化cv::Mat grayMat;cv::cvtColor(srcMat, grayMat, cv::COLOR_BGR2GRAY);cv::imshow(3, grayMat);
// cv::waitKey(0);// 步骤四检测角点std::vectorcv::Point2f vectorPoint2fCorners;bool patternWasFound false;patternWasFound cv::findChessboardCorners(grayMat,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK | cv::CALIB_CB_NORMALIZE_IMAGE);/*enum { CALIB_CB_ADAPTIVE_THRESH 1, // 使用自适应阈值将图像转化成二值图像CALIB_CB_NORMALIZE_IMAGE 2, // 归一化图像灰度系数(用直方图均衡化或者自适应阈值)CALIB_CB_FILTER_QUADS 4, // 在轮廓提取阶段使用附加条件排除错误的假设CALIB_CB_FAST_CHECK 8 // 快速检测};*/cvui::printf(srcMat, 0, 0, 1.0, 0xFF0000, found %s, patternWasFound ? true : false);cvui::printf(srcMat, 0, 24, 1.0, 0xFF0000, count %d, vectorPoint2fCorners.size());qDebug() __FILE__ __LINE__ vectorPoint2fCorners.size();// 步骤五绘制棋盘点cv::drawChessboardCorners(srcMat2,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,patternWasFound);
#if FindChessboardCornersUseCameracv::imshow(0, srcMat);cv::imshow(4, srcMat2);if(!patternWasFound){cv::imshow(5, srcMat3);cv::waitKey(1);continue;}
#endif// 步骤六进一步提取亚像素角点cv::TermCriteria criteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, // 类型30, // 参数二: 最大次数0.001); // 参数三迭代终止阈值/*#define CV_TERMCRIT_ITER 1 // 终止条件为: 达到最大迭代次数终止#define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER //#define CV_TERMCRIT_EPS 2 // 终止条件为: 迭代到阈值终止*/qDebug() __FILE__ __LINE__ vectorPoint2fCorners.size();cv::cornerSubPix(grayMat,vectorPoint2fCorners,cv::Size(11, 11),cv::Size(-1, -1),criteria);// 步骤七绘制棋盘点cv::drawChessboardCorners(srcMat3,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,patternWasFound);cv::imshow(5, srcMat3);
// cv::waitKey(0);#if FindChessboardCornersUseCameracv::waitKey(1);}
// cv::imshow(_windowTitle.toStdString(), dstMat);
#elsecv::waitKey(0);
#endif}对应工程模板v1.67.0 入坑
入坑一无法检测出角点
问题 检测角点失败
原因 输入棋牌横向竖向角点的数量入函数而不是输入行数和列数。
解决 输入正确的横向纵向角点数量即可。
入坑二检测亚像素角点崩溃
问题 检测亚像素角点函数崩溃
原因 输入要是灰度mat
解决 将灰度图输入即可。 上一篇《OpenCV开发笔记七十五相机标定矫正中使用remap重映射进行畸变矫正》 下一篇持续补充中… 若该文为原创文章转载请注明原文出处 本文章博客地址https://blog.csdn.net/qq21497936/article/details/136535848