经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
Qt加Opencv实现 梯度矫正 功能
来源:cnblogs  作者:十一的杂文录  时间:2024/4/10 15:18:32  对本文有异议

废话:

有时候我们是从物品的斜上方拍摄的图片,看起来不直观,需要把视角拉正,这样的一个操作就叫做 梯度矫正,需要用到的技术是 Opencv 的 透视变换。

这个只是一个简单的演示demo,如果完善一下,比如物品检测,可以应用更多的场景,比如常见的:文件、资料上传,软管摄像头的应用等,怎么说也是一个技术点吧

 

重要代码:

  1. /**
  2. * @brief hDLL_gradientAuto 梯度矫正
  3. * @param src 输入图像
  4. * @param dst 输出图像
  5. * @param flag 方向,[0(左),1(上),2(右),3(下)]
  6. * @param val 矫正度数,像素,[10 ~ 100]
  7. * @return 0(成功),-1(失败)
  8. */
  9. int MainWindow::hDLL_gradientAuto(Mat &src, Mat &dst, int flag, int val)
  10. {
  11. if(flag != 0 && flag != 1 && flag != 2 && flag != 3) return -1;
  12. if(val < 10 || val > 100) return -1;
  13. int width = src.cols;
  14. int height = src.rows;
  15. Mat M;
  16. // flag 方向,[0(左),1(上),2(右),3(下)]
  17. switch (flag) {
  18. case 0:
  19. {
  20. Point2f pts_src[] = { Point(val,val), Point(width, 0), Point(width, height), Point(val, height-val)};
  21. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  22. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  23. }break;
  24. case 1:
  25. {
  26. Point2f pts_src[] = { Point(val,val), Point(width-val, val), Point(width, height), Point(0, height)};
  27. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  28. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  29. }break;
  30. case 2:
  31. {
  32. Point2f pts_src[] = { Point(0,0), Point(width-val, val), Point(width-val, height-val), Point(0, height)};
  33. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  34. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  35. }break;
  36. case 3:
  37. {
  38. Point2f pts_src[] = { Point(0,0), Point(width, 0), Point(width-val, height-val), Point(val, height-val)};
  39. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  40. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  41. }break;
  42. }
  43. cv::warpPerspective(src, dst, M, dst.size(), cv::INTER_LINEAR , cv::BORDER_REPLICATE);
  44. return 0;
  45. }

 

 

Demo演示:

 

完整代码:

.h

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include <QImage>
  5. #include <QDebug>
  6. #include <QtMath>
  7. #include "opencv2/opencv.hpp"
  8. using namespace cv;
  9. QT_BEGIN_NAMESPACE
  10. namespace Ui {
  11. class MainWindow;
  12. }
  13. QT_END_NAMESPACE
  14. class MainWindow : public QMainWindow
  15. {
  16. Q_OBJECT
  17. public:
  18. MainWindow(QWidget *parent = nullptr);
  19. ~MainWindow();
  20. void updateQLabelImage();
  21. Mat QImage2Mat(QImage &img);
  22. QImage Mat2QImage(Mat &img);
  23. /**
  24. * @brief hDLL_gradientAuto 梯度矫正
  25. * @param src 输入图像
  26. * @param dst 输出图像
  27. * @param flag 方向,[0(左),1(上),2(右),3(下)]
  28. * @param val 矫正度数,像素,[10 ~ 100]
  29. * @return 0(成功),-1(失败)
  30. */
  31. int hDLL_gradientAuto(Mat &src, Mat &dst, int flag, int val);
  32. public slots:
  33. void horChange(int index);
  34. void verChange(int index);
  35. private:
  36. Ui::MainWindow *ui;
  37. QImage m_img; // 原图
  38. QImage m_img_dst; // 处理过的图像
  39. };
  40. #endif // MAINWINDOW_H

 

.cpp

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. MainWindow::MainWindow(QWidget *parent)
  4. : QMainWindow(parent)
  5. , ui(new Ui::MainWindow)
  6. {
  7. ui->setupUi(this);
  8. connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(horChange(int)));
  9. connect(ui->verticalSlider, SIGNAL(valueChanged(int)), this, SLOT(verChange(int)));
  10. m_img = QImage("F:1.jpg");
  11. m_img_dst = m_img;
  12. updateQLabelImage();
  13. }
  14. MainWindow::~MainWindow()
  15. {
  16. delete ui;
  17. }
  18. // 更新QLabel里面的图像
  19. void MainWindow::updateQLabelImage()
  20. {
  21. // m_img = m_img.scaled(ui->label->width(), ui->label->height());
  22. QImage img_show = m_img_dst.scaled(ui->label->width(), ui->label->height());
  23. ui->label->setPixmap(QPixmap::fromImage(img_show));
  24. }
  25. Mat MainWindow::QImage2Mat(QImage &img)
  26. {
  27. cv::Mat mat;
  28. switch (img.format())
  29. {
  30. case QImage::Format_RGB32: //一般Qt读入彩色图后为此格式
  31. mat = cv::Mat(img.height(), img.width(), CV_8UC4, (void*)img.constBits(), img.bytesPerLine());
  32. cv::cvtColor(mat,mat,cv::COLOR_BGRA2BGR); //转3通道
  33. break;
  34. case QImage::Format_RGB888:
  35. mat = cv::Mat(img.height(), img.width(), CV_8UC3, (void*)img.constBits(), img.bytesPerLine());
  36. cv::cvtColor(mat,mat,cv::COLOR_RGB2BGR);
  37. break;
  38. case QImage::Format_Indexed8:
  39. mat = cv::Mat(img.height(), img.width(), CV_8UC1, (void*)img.constBits(), img.bytesPerLine());
  40. break;
  41. }
  42. return mat;
  43. }
  44. QImage MainWindow::Mat2QImage(Mat &img)
  45. {
  46. if(img.type()==CV_8UC1 || img.type()==CV_8U)
  47. {
  48. QImage image((const uchar *)img.data, img.cols, img.rows, img.step, QImage::Format_Grayscale8);
  49. return image;
  50. }
  51. else if(img.type()==CV_8UC3)
  52. {
  53. QImage image((const uchar *)img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
  54. return image.rgbSwapped(); //r与b调换
  55. }
  56. }
  57. int MainWindow::hDLL_gradientAuto(Mat &src, Mat &dst, int flag, int val)
  58. {
  59. if(flag != 0 && flag != 1 && flag != 2 && flag != 3) return -1;
  60. if(val < 10 || val > 100) return -1;
  61. int width = src.cols;
  62. int height = src.rows;
  63. Mat M;
  64. // flag 方向,[0(左),1(上),2(右),3(下)]
  65. switch (flag) {
  66. case 0:
  67. {
  68. Point2f pts_src[] = { Point(val,val), Point(width, 0), Point(width, height), Point(val, height-val)};
  69. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  70. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  71. }break;
  72. case 1:
  73. {
  74. Point2f pts_src[] = { Point(val,val), Point(width-val, val), Point(width, height), Point(0, height)};
  75. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  76. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  77. }break;
  78. case 2:
  79. {
  80. Point2f pts_src[] = { Point(0,0), Point(width-val, val), Point(width-val, height-val), Point(0, height)};
  81. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  82. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  83. }break;
  84. case 3:
  85. {
  86. Point2f pts_src[] = { Point(0,0), Point(width, 0), Point(width-val, height-val), Point(val, height-val)};
  87. Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
  88. M = cv::getPerspectiveTransform(pts_src, pts_dst);
  89. }break;
  90. }
  91. cv::warpPerspective(src, dst, M, dst.size(), cv::INTER_LINEAR , cv::BORDER_REPLICATE);
  92. return 0;
  93. }
  94. // 横向改变
  95. void MainWindow::horChange(int index)
  96. {
  97. qDebug() << "hor:" << index;
  98. if(index == 0)
  99. {
  100. m_img_dst = m_img;
  101. }
  102. else if(index < 0)
  103. {
  104. int val = abs(index) * 10;
  105. Mat src = QImage2Mat(m_img);
  106. Mat dst;
  107. hDLL_gradientAuto(src, dst, 0, val);
  108. m_img_dst = Mat2QImage(dst);
  109. }
  110. else if (index > 0)
  111. {
  112. int val = abs(index) * 10;
  113. Mat src = QImage2Mat(m_img);
  114. Mat dst;
  115. hDLL_gradientAuto(src, dst, 2, val);
  116. m_img_dst = Mat2QImage(dst);
  117. }
  118. updateQLabelImage();
  119. }
  120. // 竖向改变
  121. void MainWindow::verChange(int index)
  122. {
  123. qDebug() << "ver:" << index;
  124. if(index == 0)
  125. {
  126. m_img_dst = m_img;
  127. }
  128. else if(index < 0)
  129. {
  130. int val = abs(index) * 10;
  131. Mat src = QImage2Mat(m_img);
  132. Mat dst;
  133. hDLL_gradientAuto(src, dst, 3, val);
  134. m_img_dst = Mat2QImage(dst);
  135. }
  136. else if (index > 0)
  137. {
  138. int val = abs(index) * 10;
  139. Mat src = QImage2Mat(m_img);
  140. Mat dst;
  141. hDLL_gradientAuto(src, dst, 1, val);
  142. m_img_dst = Mat2QImage(dst);
  143. }
  144. updateQLabelImage();
  145. }

 

 

 

代码下载:

我的环境是:Qt 5.15.2 + Opencv V4.8.0,如果需要下载代码,自己调试,自己配置环境即可

代码仓库:https://gitee.com/vvvj/qt-test-gradient-auto

 

原文链接:https://www.cnblogs.com/shiyixirui/p/18123967

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号