项目实战:Qt+OpenCV透视变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出变换后的图等等)

需求

  1.打开图片;
  2.矫正识别角点;
  3.四点对应偏移距离;
  4.支持设置棋盘格的行列角点数;
  5.导出结果图片;

 

背景

  深入研究图像拼接细分支算法,产出的效果查看工具,验证算法单步思路。

 

相关博客

  《项目实战:Qt+OpenCV透视变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出变换后的图等等)》
  《项目实战:Qt+OpenCV仿射变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出变换后的图等等)》
  《项目实战:Qt+Opencv相机标定工具v1.3.0(支持打开摄像头、视频文件和网络地址,支持标定过程查看、删除和动态评价误差率,支持追加标定等等)》
  《OpenCV开发笔记(〇):使用mingw530_32编译openCV3.4.1源码,搭建Qt5.9.3的openCV开发环境》
  《OpenCV开发笔记(三):OpenCV图像的概念和基本操作》
  《OpenCV开发笔记(四):OpenCV图片和视频数据的读取与存储》
  《OpenCV开发笔记(六):OpenCV基础数据结构、颜色转换函数和颜色空间》
  《OpenCV开发笔记(四十六):红胖子8分钟带你深入了解仿射变化(图文并茂+浅显易懂+程序源码)》
  《OpenCV开发笔记(五十一):红胖子8分钟带你深入了解透视变换(图文并茂+浅显易懂+程序源码)》
  《OpenCV开发笔记(七十六):相机标定(一):识别棋盘并绘制角点》
  《OpenCV开发笔记(七十七):相机标定(二):通过棋盘标定计算相机内参矩阵矫正畸变摄像头图像》

 

Demo:perspectTool_v1.1.0 windows运行包

  图片[1]-项目实战:Qt+OpenCV透视变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出变换后的图等等)-后端开发牛翰社区-编程开发-牛翰网
  

  

  

  

 

模块化部署

  

关键源码

AffineManager.h

#ifndef PERSPECTMANAGER_H #define PERSPECTMANAGER_H // opencv #include "opencv/highgui.h" #include "opencv/cxcore.h" #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/opencv.hpp" #include "opencv2/xphoto.hpp" #include "opencv2/dnn/dnn.hpp" // opencv_contrib #include <opencv2/xphoto.hpp> #include <opencv2/ximgproc.hpp> #include <opencv2/calib3d.hpp> #include <opencv2/features2d.hpp> #include <opencv2/xfeatures2d.hpp> #include <opencv2/xfeatures2d/nonfree.hpp> #include "cvui.h" #include <QImage> #include <QTimer> class PerspectManager: public QObject { Q_OBJECT public: explicit PerspectManager(QObject *parent = 0); ~PerspectManager(); public slots: void testOpencvEnv(); // 测试环境 public: cv::Point2f getLeftBottomOffsetPoint() const; cv::Point2f getRightBottomOffsetPoint() const; cv::Point2f getLeftTopOffsetPoint() const; cv::Point2f getRightTopOffsetPoint() const; int getChessboardColCornerCount() const; int getChessboardRowCornerCount() const; public: void setLeftBottomOffsetPoint(const cv::Point2f &offsetPoint); void setRightBottomOffsetPoint(const cv::Point2f &offsetPoint); void setLeftTopOffsetPoint(const cv::Point2f &leftTopOffsetPoint); void setRightTopOffsetPoint(const cv::Point2f &rightTopOffsetPoint); void setChessboardColCornerCount(int chessboardColCornerCount); void setChessboardRowCornerCount(int chessboardRowCornerCount); signals: void signal_srcImage(QImage image); void signal_srcImage(cv::Mat mat); void signal_resultImage(QImage image); void signal_resultImage(cv::Mat mat); void signal_inited(bool result); public slots: void slot_openImage(QString filePath); void slot_initImage(); void slot_perspectImage(); protected: void initControl(); protected: bool findChessboard(int rowCornerCount, int colCornerCount, cv::Mat &mat, std::vector<cv::Point2f> &vectorPoint2fCorners); public: static QImage mat2Image(cv::Mat mat); // cv::Mat 转 QImage private: cv::Mat _mat; // 缓存一帧 cv::Mat _resultMat; // 结果 int _chessboardColCornerCount; // 一列多少个角点 int _chessboardRowCornerCount; // 一行多少个角点 private: // 计算内参和畸变系数 cv::Point2f _leftBottomPoint; // 透射四点,对应原始 cv::Point2f _rightBottomPoint; // 透射四点,对应原始 cv::Point2f _leftTopPoint; // 透射四点,对应原始 cv::Point2f _rightTopPoint; // 透射四点,对应原始 cv::Point2f _leftBottomOffsetPoint; // 透射四点,对应偏移 cv::Point2f _rightBottomOffsetPoint;// 透射四点,对应偏移 cv::Point2f _leftTopOffsetPoint; // 透射四点,对应偏移 cv::Point2f _rightTopOffsetPoint; // 透射四点,对应偏移 bool _drawPoint; }; #endif // PERSPECTMANAGER_H 

AffineManager.cpp

... void PerspectManager::slot_perspectImage() { cv::Point2f srcTraingle[4]; cv::Point2f dstTraingle[4]; srcTraingle[0] = _leftTopPoint; srcTraingle[1] = _rightTopPoint; srcTraingle[2] = _rightBottomPoint; srcTraingle[3] = _leftBottomPoint; dstTraingle[0] = _leftTopPoint + _leftTopOffsetPoint; dstTraingle[1] = _rightTopPoint + _rightTopOffsetPoint; dstTraingle[2] = _rightBottomPoint + _rightBottomOffsetPoint; dstTraingle[3] = _leftBottomPoint + _leftBottomOffsetPoint; #if 0 dstTraingle[0].x = dstTraingle[3].x; dstTraingle[0].y = dstTraingle[1].y; dstTraingle[2].x = dstTraingle[1].x; dstTraingle[2].y = dstTraingle[3].y; #endif cv::Mat mat = cv::getPerspectiveTransform(srcTraingle, dstTraingle); LOG << "============================================="; LOG << " 左上点 右上点 右下点 左下点"; LOG << "原始点:" << srcTraingle[0].x << "," << srcTraingle[0].y << ";" << srcTraingle[1].x << "," << srcTraingle[1].y << ";" << srcTraingle[2].x << "," << srcTraingle[2].y << ";" << srcTraingle[3].x << "," << srcTraingle[3].y << ";"; LOG << "偏移后:" << dstTraingle[0].x << "," << dstTraingle[0].y << ";" << dstTraingle[1].x << "," << dstTraingle[1].y << ";" << dstTraingle[2].x << "," << dstTraingle[2].y << ";" << dstTraingle[3].x << "," << dstTraingle[3].y << ";"; cv::warpPerspective(_mat, _resultMat, mat, cv::Size(_mat.cols, _mat.rows)); QImage image = mat2Image(_resultMat); emit signal_resultImage(image); } 

 

入坑

  算法的研究优化过程中,思路需要开拓编写代码,查看效果,逐步研究出算法的优化路径,坑多暂时未记录。

请登录后发表评论

    没有回复内容