近来有点烦,不想看论文,不想做项目,无聊之余把好久之前想到的用qt做一个图片透视变换的小工具的想法实现了一下。。。详细如下:

说明:对于有些平时拍的图片可能产生了透视效果,而你想得到正向拍摄的效果,你就可以根据opencv中的透视变换,选择矩形物体图片中的四个点,变换到正常图像状态,还有其他用处,自己去想吧,哈哈。

0. 首先看一下效果,有兴趣可以继续往下看,

1. 使用说明

(1)首先打开一张图片,调整需要透视变换物体在左边图形框中完全显示。

(2)点击左下角 ‘选择角点’ 按钮,然后按照顺时针顺序依次点击四个角点,点击“选择结束”,不点也没关系。

(3)输入转换后的图片高度和宽度,默认值为200,320,点击“透视变换“ 按钮即可显示变换后的图像。

(4)点击”保存图片“ 按钮,选择保存位置,输入文件名,不要忘了加后缀 ”.jpg“ 。

2.创建一个qt桌面项目,添加opencv库,pro文件如下

#-------------------------------------------------
#
# Project created by QtCreator 2019-03-04T09:22:39
#
#-------------------------------------------------QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = perspective_img
TEMPLATE = app
#include opencv files
INCLUDEPATH += /usr/include \/usr/include/opencv \/usr/include/opencv2LIBS += /usr/lib/x86_64-linux-gnu/libopencv_highgui.so \/usr/lib/x86_64-linux-gnu/libopencv_core.so    \/usr/lib/x86_64-linux-gnu/libopencv_imgproc.so#作者:Shawn-HT
#来源:CSDN
#原文:https://blog.csdn.net/shawn_ht/article/details/40795039
版权声明:本文为博主原创文章,转载请附上博文链接!DEFINES += QT_DEPRECATED_WARNINGSSOURCES += \main.cpp \mainwindow.cpp
HEADERS += \mainwindow.h
FORMS += \mainwindow.ui

3. 在界面.ui文件中对需要显示的部件进行布局

4. main.cpp 文件没变,主要修改mainwindow.h 和mainwindow.cpp文件

mainwindow.h 文件如下

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QFileDialog>
#include <opencv2/opencv.hpp>
using namespace cv;namespace Ui {
class MainWindow;
}
class QLabel;class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();void DisplayMat(cv::Mat image);void mousePressEvent(QMouseEvent *event);//void paintEvent(QPaintEvent *event);bool eventFilter(QObject *watched, QEvent *event);Mat perspectivetransfer(Mat srcImage);signals:void button_click_update();
public slots:void drawRedCircle();//void drawRedPoint(int x,int y);void on_actionAbout_triggered();void on_actionSpecifications_triggered();private slots:void on_pushButton_open_clicked();void on_pushButton_choose_clicked(bool checked);void on_pushButton_perspective_clicked();void on_pushButton_save_clicked();private:Ui::MainWindow *ui;cv::Mat image;QLabel *label;int count;//initial for corners orderint point_x = 10;int point_y = 10;Point point_lt,point_rt,point_rb,point_lb;Mat src_resize;Mat save_image;
};#endif // MAINWINDOW_H

5. mainwindow.cpp 文件如下

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QDebug>
#include <QMessageBox>
#include <QTextCodec>
#include <QLabel>
#include <QMouseEvent>
#include <QPoint>
#include <QPainter>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);setWindowTitle(tr("Image Perspective tool-2019.03.10"));label = new QLabel(ui->scrollArea);//构造函数中注册事件过滤器//ui->labelimage->installEventFilter(this);//QObject::connect(this,SIGNAL(button_click_update()),this,SLOT(drawRedCircle()));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_actionAbout_triggered() {QMessageBox::about(this, tr("About ..."),tr("<h2>Image Perspective:1.0 </h2><p>Copyright 龙性的腾飞 </p>""<p>School of Electrical and Information Engineering,Tianjin University</p>"));
}void MainWindow::on_actionSpecifications_triggered() {QMessageBox::about(this, tr("Specifications"),tr("<h2>Steps as follows: </h2><p>1.Open a picture, do not contain chinese characters in the path. </p>""<p>2. Press 'Choose Corners' button and click four corners of the object you want to perspective transform in a clockwise. </p>""<p>3. Press 'Perspective Transform' button, then save the picture transformed.</p>"));
}bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{if (watched == ui->labelimage && event->type() == QEvent::Paint)drawRedCircle();return QWidget::eventFilter(watched, event);}void MainWindow::drawRedCircle()
{//在label上绘制图形---->一个红色圆点QPainter painter(ui->labelimage);painter.drawLine (QPoint(0,0),QPoint(100,100));painter.setPen(Qt::NoPen);painter.setRenderHint(QPainter::Antialiasing,true);painter.setBrush(QColor(255,0,0));painter.drawLine (QPoint(0,0),QPoint(100,100));qDebug() << "left click";painter.drawEllipse(point_x,point_y,4,4);qDebug() << point_x;//update();
}void MainWindow::mousePressEvent(QMouseEvent *event)
{// 如果是鼠标左键按下//---------------------//作者:祥知道//来源:CSDN//原文:https://blog.csdn.net/humanking7/article/details/80707591//版权声明:本文为博主原创文章,转载请附上博文链接!if (event->button() == Qt::LeftButton && ui->lineEdit_LB->isEnabled()){QPoint global_pos = event->globalPos();QPoint label_pos = label->mapFromGlobal(global_pos);point_x = label_pos.x();point_y = label_pos.y();QString x = QString::number(label_pos.x(), 10);QString y = QString::number(label_pos.y(), 10);QString point = "("+x+","+y+")";if (ui->pushButton_choose->isChecked()){count += 1;update();//emit button_click_update();//drawRedPoint(point_x,point_y);switch (count) {case 1:ui->lineEdit_LT->setText(point);point_lt.x = label_pos.x();point_lt.y = label_pos.y();break;case 2:ui->lineEdit_RT->setText(point);point_rt.x = label_pos.x();point_rt.y = label_pos.y();break;case 3:ui->lineEdit_RB->setText(point);point_rb.x = label_pos.x();point_rb.y = label_pos.y();break;case 4:ui->lineEdit_LB->setText(point);point_lb.x = label_pos.x();point_lb.y = label_pos.y();break;}}//qDebug() << "left click"<<event->pos()<<"global:"<<event->globalPos()<<"label_pos:"<<label_pos;}
}void MainWindow::on_pushButton_open_clicked()
{QString filename = QFileDialog::getOpenFileName(this,tr("Open Image"),"/home/sun/",tr("Image File (*.jpg *.png *.bmp)"));qDebug()<<"filenames:"<<filename;QTextCodec *code = QTextCodec::codecForName("gb18030");std::string name = code->fromUnicode(filename).data();//filename.toAscii().data()image = cv::imread(name);QString w = QString::number(image.size().width, 10);QString h = QString::number(image.size().height, 10);QString w_h = " width: "+w+" height: "+h;//https://blog.csdn.net/ei__nino/article/details/7297791//QString s = QString::number(a, 10);             // s == "63"ui->statusBar->showMessage(filename+w_h);if(!image.data){ui->pushButton_perspective->setEnabled(false);QMessageBox msgBox;msgBox.setText(tr("Image Data Is Null"));msgBox.exec();}else {//DisplayMat(image);//https://blog.csdn.net/xiezhongyuan07/article/details/79621467//https://blog.csdn.net/qq_37233607/article/details/79082243ui->pushButton_perspective->setEnabled(true);QImage qimage(filename);int q_width = qimage.size().width();int q_height = qimage.size().height();if (q_width>640 || q_height>480 ){//label = new QLabel(ui->scrollArea);cv::resize(image,image,Size(640,q_height*640/q_width));//sr= image.resize(640);//resize(image, src_resize, Size(640,q_height*640/q_width));label->setPixmap(QPixmap::fromImage(qimage).scaled(QSize(640,q_height*640/q_width),Qt::KeepAspectRatio));label->setAlignment(Qt::AlignTop);ui->scrollArea->setWidget(label);qDebug()<<"labelsize:"<<qimage.size();}else{label = new QLabel(ui->scrollArea);label->setPixmap(QPixmap::fromImage(qimage));label->setAlignment(Qt::AlignTop);ui->scrollArea->setWidget(label);}}
}void MainWindow::DisplayMat(cv::Mat image)
{cv::Mat rgb;QImage img;if(image.channels() == 3){cvtColor(image,rgb,CV_BGR2RGB);img = QImage((const unsigned char*)(rgb.data),rgb.cols,rgb.rows,rgb.cols*rgb.channels(),//rgb.cols*rgb.channels()可以替换为image.stepQImage::Format_RGB888);}else{img = QImage((const unsigned char*)(image.data),image.cols,image.rows,rgb.cols*image.channels(),QImage::Format_RGB888);}QSize label_resize = QSize(image.size().width,image.size().height);//qDebug()<<"imagesize:"<<image.size();ui->labelimage->setPixmap(QPixmap::fromImage(img).scaled(label_resize));//setPixelmap(QPixmap::fromImage(img));ui->labelimage->resize(ui->labelimage->pixmap()->size());//resize(ui->label->pixmap()->size());//ui->scrollArea->setWidget(ui->labelimage);会出现崩溃,必须QLabel创建才可以//qDebug()<<"labelsize:"<<ui->labelimage->size();}
//---------------------
//作者:call_me_yang
//来源:CSDN
//原文:https://blog.csdn.net/yang6464158/article/details/38109415
//版权声明:本文为博主原创文章,转载请附上博文链接!void MainWindow::on_pushButton_choose_clicked(bool checked)
{if(checked){ui->pushButton_choose->setText("选择结束");count = 0;ui->lineEdit_LT->setEnabled(true);ui->lineEdit_LT->clear();ui->lineEdit_RT->setEnabled(true);ui->lineEdit_RT->clear();ui->lineEdit_RB->setEnabled(true);ui->lineEdit_RB->clear();ui->lineEdit_LB->setEnabled(true);ui->lineEdit_LB->clear();}else{ ui->pushButton_choose->setText("选择角点"); }
}
/*void MainWindow::paintEvent(QPaintEvent *)
{QPainter painter(this);qDebug()<<"labelsize";QPen pen(Qt::red,5,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin);painter.setPen(pen);painter.drawLine (QPoint(0,0),QPoint(100,100));//must use QImage
}*/
Mat MainWindow::perspectivetransfer(Mat srcImage)
{   //选择的待变换角点Point2f pts_src[] = { point_lt,point_rt,point_rb,point_lb};//透视变换后的角点int height = ui->lineEdit_height->text().toInt();int width = ui->lineEdit_width->text().toInt();Point2f pts_dst[] = {Point(10, 10),Point(10+width, 10),Point(10+width, 10+height) ,Point(10, 10+height) };Mat &&M = cv::getPerspectiveTransform(pts_src, pts_dst);Mat warp;Mat PerspectivedImg(height+20, width+20, CV_8UC1);PerspectivedImg.setTo(0);cv::warpPerspective(srcImage, warp, M, PerspectivedImg.size(), cv::INTER_LINEAR , cv::BORDER_REPLICATE);//imshow("After Perspectived", warp);return warp;
}void MainWindow::on_pushButton_perspective_clicked()
{save_image = perspectivetransfer(image);DisplayMat(save_image);
}void MainWindow::on_pushButton_save_clicked()
{QString filename =QFileDialog::getSaveFileName(this,tr("Save Image..."),"/home/sun/deeplearning",tr("Image File (*.jpg *.png *.bmp)"));qDebug()<<"filenames:"<<filename;std::string After_perspective = filename.toStdString();imwrite(After_perspective,save_image);
}

6.总结

代码都是现用现查的,相关代码来源网址已附在程序中,还有以前的一些代码稍微拼了拼就出来了,由于水平有限,代码写的不是那么规范,以及操作不当会出现崩溃情况,还大家多多交流。

代码中有关于绘图的代码没有用,我也没删除,主要是开始想在点击图片选点时没点一个点可以显示一个位置红点,无奈对paintevent理解不够,一直无法实现,没再花时间搞,对变换功能影响不大。

待我有时间把代码传到github,先留个空,有问题和想法欢迎留言交流!

https://github.com/sunyuzhe2017/Perspective

QT实现一个图片透视变换的小玩意相关推荐

  1. QT实现一个图片显示器,有登录界面(附图片,源码可直接使用)

    QT-图片浏览器(显示器)的实现(含登录界面) 一.设计要求 1.登录界面 ​ 创建一个窗体,设计用户登录的界面(含有用户名.密码),并实现用户登录的功能,要求用户提交的登录按钮时能获取界面中的用户名 ...

  2. QT制作一个图片播放器

    前言:使用qt制作了一个简单的图片播放器,可以播放gif.png等格式图片 先来看看播放器的功能(当然是很简陋的,没有很深入的设计): 1.点击图片列表中图片进行播放. 2.自动播放,播放的图片的间隔 ...

  3. 用Qt设计一个图片浏览器

    本人分享的是不用ui界面的图片浏览器,它可以从系统文件里面选取各种格式的图片(可以自己设置),然后点击左右的按钮来浏览这些图片,而且还支持图片多选的功能. 以下是Widget.h中的代码: #ifnd ...

  4. 使用QT实现一个图像处理软件1 —— 图片的加载和显示

    为了实现图片的加载和显示,本文主要将使用到Qt中的几个类,分别是: QImage,这是Qt实现的一个存储图片信息的类,支持大部分的图片格式,支持像素操作,后续所有的图像处理算法都将在这个类的基础上进行 ...

  5. OpenCV(3):用Vs+Qt制作一个查看图片相似度的窗口程序

    OpenCV(2):用Vs+Qt制作一个显示两张图片的窗口程序 在制作了窗口程序后,在网上找了比较两张图片差异度的算法. 哈希值方法:https://blog.csdn.net/fengbingchu ...

  6. qt 启动画面显示图片_Qt程序起动画面QSplashScreen

    Qt程序启动画面QSplashScreen QSplashScreen会在应用程序的主窗口出现之前显示一个图片! #include "qmain.h" #include #incl ...

  7. linux qt显示gif图片,QT显示GIF图片

    在QT中要显示GIF图片,不能通过单单的添加部件来完成. 还需要手动的编写程序. 工具:QT Creator 新建一个工程,我们先在designer中,添加一个QLabel部件. 如下图: 将QLab ...

  8. qt实现简易图片转换功能

    qt图片转换 1.ui控件及布局 ​ 通过上方控件中,寻找所适合的控件,之后将其拖拽到自己合适的位置上: ​ 具体布局如下图所示: 2.设置ui控件名称 ​ 如上图所示,我将每一个单选按钮都设置了相对 ...

  9. 如何用Qt抠一个圆形头像出来

    如题,如何使用Qt抠一个圆形头像出来? 先来看效果: 首先加载一张图片,显示一个透明圆形,圆形外半透明,滚动鼠标滚轮,圆形区域变大变小. 鼠标按下可以拖动图片移动,来选定要截取的图片位置,按下&quo ...

最新文章

  1. MongoDB权威指南
  2. 如何起诉一辆自动驾驶汽车?
  3. Spring Framework------version4.3.5-----Reference学习心得-----总结
  4. linux基础(day19)
  5. timerpickerview使用_详解iOS App中UIPickerView滚动选择栏的添加方法
  6. Ember By Examples(总体介绍)
  7. idea 玩转 码云 -- idea安装码云插件
  8. (转)CKEditor和CKFinder在ASP.NET中的应用
  9. C语言SetConsoleCursorPosition()函数来定位光标位置
  10. 【剑指offer】链表中环的入口
  11. 中职计算机专业英语说课稿,中职英语说课稿模板.doc
  12. matlab的fprintf写不进文件,fprintf写不进文件
  13. 解决nacos不停刷日志 ClientWorker get changedGroupKeys:[] 问题
  14. 手把手教你如何巧用Github的Action功能
  15. gitee团队协作使用
  16. 计算机l符号代表什么意思,衣服sml代表什么意思 分别是什么的标记
  17. 【AlexNet】ImageNet Classification with Deep Convolutional Neural Networks
  18. 联想拯救者y7000p电池怎么卸下来_联想拯救者R7000P怎么样 联想拯救者R7000P全面评测_笔记本_硬件教程...
  19. mysql模糊查找英文可以查找中文不行(详细记录)
  20. 诺基亚升级Android10,诺基亚发布第五次Android 10更新 ,诺基亚7+可升级

热门文章

  1. linux 下sh命令:command not found
  2. java并发编程入门_Java并发编程入门,看这一篇就够了
  3. iphone 内存管理1
  4. centos安装anaconda教程
  5. java ee包含哪些技术_JavaEE基本了解
  6. 交叉编译:linaro-gdb调试core文件,堆栈显示问号
  7. 幽灵交易策略_千万级 交易商 独家 策略 开盘区间 突破 PZ Stretch 指标
  8. go拉取包报错 128
  9. JS播放音频 JS播放mp3 JS播放音乐 Java播放音频 Java播放音乐 Java播放mp3 的jmp123.jar包安装 语音播报 Java获取根路径
  10. 马云说今年他要读100本书,你呢?