深度学习之标注工具【Qt版】
来源:互联网 发布:人工智能用什么语言写 编辑:程序博客网 时间:2024/06/06 09:40
前几天,用Qt写了个图像标注工具,最近电脑崩了,然后界面化的东西发不了了,待我将电脑
环境,编译好再发。这里先提供Qt源代码。
测试环境:win10 64x QtCreator5.7.0, opencv2.4.13
环境配置文件.pro,根据个人电脑路径,自行配制opencv
#-------------------------------------------------## Project created by QtCreator 2017-05-25T21:01:11##-------------------------------------------------QT += core guiQT += xmlgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = image_lable_tool_uiTEMPLATE = appSOURCES += main.cpp\ mainwindow.cpp \ my_qlabel.cppHEADERS += mainwindow.h \ my_qlabel.hFORMS += mainwindow.uiINCLUDEPATH += C:/opencv-2.4.13/build/install/include \ C:/opencv-2.4.13/build/install/include/opencv \ C:/opencv-2.4.13/build/install/include/opencv2LIBS += C:/opencv-2.4.13/build/install/x86/mingw/lib/libopencv_*
由于本人将图像显示在QLabel上,而又用到鼠标事件,所以,我自己定义了一个由QLabel继承来的类
my_qlabel 头文件.h
#ifndef MY_QLABEL_H#define MY_QLABEL_H#include <QLabel>#include <QMouseEvent>#include <QDebug>#include <QEvent>class My_QLabel : public QLabel{ Q_OBJECTpublic: explicit My_QLabel(QWidget *parent=0); void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void leaveEvent(QEvent *event); int Pos_x(){return x;} int Pos_y(){return y;} inline void setPress_flag(bool a){Press_flag=a;} inline bool getPress_flag(){return Press_flag;} inline void setRelease_flag(bool a){Release_flag=a;} inline bool getRelease_flag(){return Release_flag;}private: int x,y; bool Press_flag=false; bool Release_flag=false;signals: void Mouse_Pressed(); void Mouse_Pos(); void Mouse_left(); void Mouse_Release();};#endif // MY_QLABEL_H
my_qlabel.cpp
#include "my_qlabel.h"My_QLabel::My_QLabel(QWidget *parent): QLabel(parent){}void My_QLabel::mouseMoveEvent(QMouseEvent *event){ this->x=event->x(); this->y=event->y(); emit Mouse_Pos();}void My_QLabel::mousePressEvent(QMouseEvent *event){ this->x=event->x(); this->y=event->y(); if(event->button()==Qt::LeftButton) { Press_flag=true; Release_flag=false; } else Press_flag=false; emit Mouse_Pressed();}void My_QLabel::mouseReleaseEvent(QMouseEvent *event){ if(event->button()==Qt::LeftButton) { Press_flag=false; Release_flag=true; } emit Mouse_Release();}void My_QLabel::leaveEvent(QEvent *event){ emit Mouse_left();}
mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QPushButton>#include <QImage>#include <QFileDialog>#include <opencv2/opencv.hpp>#include <QTextCodec>#include <QFileInfoList>#include <QDir>#include <QLabel>#include <QMessageBox>#include <QPainter>#include <vector>#include <QPoint>#include <QRect>#include <QPaintEvent>#include <QListWidgetItem>#include <QDomDocument>#include <QFile>#include <QTextStream>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); void displayMat(cv::Mat & image); bool checkedradioButton(); bool isDirExist(QString fullpath); void clear_current_workspace(); cv::Rect portion2scaledReal(cv::Rect_<float>&); cv::Rect portion2scaledReal_unscaled(cv::Rect_<float> &rect); QString selectedLabel(); cv::Scalar setColor(QString&); ~MainWindow();private slots: //void on_openImagepushButton_clicked(); void on_setDirpushButton_clicked(); void on_nextpushButton_clicked(); void on_previouspushButton_clicked(); void Mouse_current_pos(); void Mouse_Pressed(); void Mouse_left(); void Mouse_Release(); void on_exprotXMLpushButton_clicked(); void on_PersonradioButton_clicked(); void on_CarradioButton_clicked(); void on_BusradioButton_clicked(); void on_MotorradioButton_clicked(); void on_BicycleradioButton_clicked(); void on_BBoxlistWidget_itemClicked(QListWidgetItem*); void on_BBoxlistWidget_itemDoubleClicked(QListWidgetItem*); //void on_BBoxlistWidget_doubleClicked(const QModelIndex &index); void on_setXMLDirpushButton_clicked();private: Ui::MainWindow *ui; cv::Mat current_src_image,current_dst_image; int current_src_w,current_src_h; QImage image; QString imageDirString; QString xmlDirString; QFileInfoList imageFileInfoList; std::vector<QListWidgetItem *> listItem; int image_info_index=0; QLabel *dirLabel; QLabel *imagenameLabel; QLabel *posLabel; QLabel *xmlDirLabel; QTextCodec *code; std::vector<std::pair<QString,cv::Rect_<float> > >total_bbox; cv::Point_<float> begin_pos,end_pos; cv::Scalar rgb;};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"#include "my_qlabel.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); dirLabel=new QLabel(tr("工作目录:")); xmlDirLabel=new QLabel(tr("保存目录: ")); imagenameLabel=new QLabel(tr("图像名:")); ui->statusBar->addWidget(dirLabel); ui->statusBar->addWidget(xmlDirLabel); ui->statusBar->addWidget(imagenameLabel); posLabel=new QLabel(tr("坐标:X=NULL , Y=NULL ")); ui->statusBar->addWidget(posLabel); code = QTextCodec::codecForName("gb18030"); connect(ui->nextpushButton,SIGNAL(clicked()),this,SLOT(on_nextpushButton_clicked())); connect(ui->previouspushButton,SIGNAL(clicked()),this,SLOT(on_previouspushButton_clicked())); connect(ui->Imagelabel,SIGNAL(Mouse_Pos()),this,SLOT(Mouse_current_pos())); connect(ui->Imagelabel,SIGNAL(Mouse_Pressed()),this,SLOT(Mouse_Pressed())); connect(ui->Imagelabel,SIGNAL(Mouse_left()),this,SLOT(Mouse_left())); connect(ui->Imagelabel,SIGNAL(Mouse_Release()),this,SLOT(Mouse_Release())); connect(ui->BBoxlistWidget,SIGNAL(itemDoubleClicked(QListWidgetItem *)),this, SLOT(on_BBoxlistWidget_itemDoubleClicked(QListWidgetItem*)),Qt::UniqueConnection); connect(ui->BBoxlistWidget,SIGNAL(itemClicked(QListWidgetItem*)),this, SLOT(on_BBoxlistWidget_itemClicked(QListWidgetItem*)));}MainWindow::~MainWindow(){ delete ui; delete dirLabel; delete imagenameLabel; delete posLabel; // delete code; //delete imagenameLabel;}void MainWindow::displayMat(cv::Mat & image){ cv::Mat rgb; if(image.channels()==3) { cvtColor(image,rgb,CV_BGR2RGB); this->image=QImage((const unsigned char *)(rgb.data), rgb.cols,rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888 ); } else this->image=QImage((const unsigned char *)(rgb.data), rgb.cols,rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888 ); ui->Imagelabel->resize(image.cols,image.rows); ui->Imagelabel->setPixmap(QPixmap::fromImage(this->image));}void MainWindow::on_setDirpushButton_clicked() { QString DirName=QFileDialog::getExistingDirectory (this, tr("选择文件夹"), tr("C:/Users/CharelCHEN/Desktop/imagedata/frame"), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); this->imageDirString=DirName; //QTextCodec *code = QTextCodec::codecForName("gb18030"); QString name = code->fromUnicode(DirName).data(); QDir imageDir(name); imageDir.setFilter(QDir::Files | QDir::NoSymLinks); imageDir.setSorting(QDir::Size | QDir::Reversed); this->imageFileInfoList=imageDir.entryInfoList(); QString image_qname=imageFileInfoList.at(image_info_index).fileName(); std::string image_name = code->fromUnicode(image_qname).data(); std::string image_dir = code->fromUnicode(DirName).data(); dirLabel->setText(tr("工作目录:")+this->imageDirString); imageDir.cdUp(); xmlDirString=imageDir.absolutePath()+QString("/xml"); isDirExist(xmlDirString); xmlDirLabel->setText(tr("保存目录: ")+this->xmlDirString); if(image_name.find_last_of(".jpg")) { current_src_image=cv::imread(image_dir+'/'+image_name); current_src_h=current_src_image.rows; current_src_w=current_src_image.cols; cv::resize(current_src_image,current_src_image, cv::Size(current_src_w*0.8,current_src_h*0.8)); current_dst_image=current_src_image.clone(); imagenameLabel->setText(tr("图像名:")+imageFileInfoList.at(image_info_index).fileName()); } displayMat(current_src_image); }void MainWindow::on_nextpushButton_clicked(){ if(!imageDirString.isEmpty()) { image_info_index++; if(image_info_index==imageFileInfoList.size()) image_info_index=0; std::string name=code->fromUnicode(imageFileInfoList.at(image_info_index).fileName()).data(); std::string dir=code->fromUnicode(imageDirString).data(); if(name.find_last_of(".jpg")) { current_src_image=cv::imread(dir+'/'+name); current_src_h=current_src_image.rows; current_src_w=current_src_image.cols; cv::resize(current_src_image,current_src_image, cv::Size(current_src_w*0.8,current_src_h*0.8)); current_dst_image=current_src_image.clone(); imagenameLabel->setText(tr("图像名:")+imageFileInfoList.at(image_info_index).fileName()); } displayMat(current_src_image); } else { QMessageBox messageBox; messageBox.critical(0,"错误!","工作目录为空"); messageBox.setFixedSize(500,200); } clear_current_workspace();}void MainWindow::on_previouspushButton_clicked(){ if(!imageDirString.isEmpty()) { image_info_index--; if(image_info_index==-1) image_info_index=imageFileInfoList.size()-1; std::string name=code->fromUnicode(imageFileInfoList.at(image_info_index).fileName()).data(); std::string dir=code->fromUnicode(imageDirString).data(); if(name.find_last_of(".jpg")) { current_src_image=cv::imread(dir+'/'+name); current_src_h=current_src_image.rows; current_src_w=current_src_image.cols; cv::resize(current_src_image,current_src_image, cv::Size(current_src_w*0.8,current_src_h*0.8)); current_dst_image=current_src_image.clone(); imagenameLabel->setText(tr("图像名:")+imageFileInfoList.at(image_info_index).fileName()); } displayMat(current_src_image); } else { QMessageBox messageBox; messageBox.critical(0,"错误!","工作目录为空"); messageBox.setFixedSize(700,200); } clear_current_workspace(); //current}void MainWindow::Mouse_current_pos(){ cv::Mat intermed_image=current_dst_image.clone(); if(!current_src_image.empty()) { float x=ui->Imagelabel->Pos_x()*1.0/current_src_image.cols; float y=ui->Imagelabel->Pos_y()*1.0/current_src_image.rows; posLabel->setText(QString("坐标: X=%1 , Y=%2").arg(x).arg(y)); } else posLabel->setText(QString("坐标: X=NULL , Y=NULL")); if(ui->Imagelabel->getPress_flag()) { // QPainter painter(ui->Imagelabel); end_pos.x=ui->Imagelabel->Pos_x()*1.0/current_src_image.cols; end_pos.y=ui->Imagelabel->Pos_y()*1.0/current_src_image.rows; cv::Point begin(begin_pos.x*current_src_image.cols, begin_pos.y*current_src_image.rows); cv::Point end(end_pos.x*current_src_image.cols, end_pos.y*current_src_image.rows); if(checkedradioButton()) { cv::rectangle(intermed_image,cv::Rect(begin,end),rgb,2); } displayMat(intermed_image); // displayMat(current_src_image); //painter.drawRect(QRect(begin_pos,end_pos)); }}void MainWindow::Mouse_Pressed(){ if(ui->Imagelabel->getPress_flag()) { begin_pos.x=ui->Imagelabel->Pos_x()*1.0/current_src_image.cols; begin_pos.y=ui->Imagelabel->Pos_y()*1.0/current_src_image.rows; }}void MainWindow::Mouse_left(){ posLabel->setText(QString("坐标: X=NULL , Y=NULL"));}void MainWindow::Mouse_Release(){ current_dst_image=current_src_image.clone(); if(ui->Imagelabel->getRelease_flag()) { for(int i=0;i<total_bbox.size();i++) { cv::Rect tmp=portion2scaledReal(total_bbox[i].second); cv::Scalar RGB=setColor(total_bbox[i].first); cv::rectangle(current_dst_image,tmp,RGB,2); } displayMat(current_dst_image); end_pos.x=ui->Imagelabel->Pos_x()*1.0/current_src_image.cols; end_pos.y=ui->Imagelabel->Pos_y()*1.0/current_src_image.rows; cv::Rect_<float> tmp(begin_pos,end_pos); cv::Rect tmp_real=portion2scaledReal(tmp); if(checkedradioButton()) { cv::rectangle(current_dst_image,tmp_real,rgb,2); QString label=selectedLabel(); if(tmp.width>0.01 &&tmp.height>0.01) { total_bbox.push_back(std::make_pair(label,tmp)); QListWidgetItem *list=new QListWidgetItem(label,ui->BBoxlistWidget); ui->BBoxlistWidget->insertItem(total_bbox.size()-1,list); //list->setData(Qt::UserRole,QString(total_bbox.size()-1)); ui->BBoxlistWidget->show(); } } displayMat(current_dst_image); } ui->Imagelabel->setRelease_flag(false);}void MainWindow::on_exprotXMLpushButton_clicked(){ QDomDocument doc(""); QDomElement root=doc.createElement("annotation"); doc.appendChild(root); QDomElement tmp=doc.createElement("folder"); QDomText txt=doc.createTextNode(QDir(imageDirString). dirName()); tmp.appendChild(txt); root.appendChild(tmp); tmp=doc.createElement("filename"); txt=doc.createTextNode(imageFileInfoList [image_info_index].fileName()); tmp.appendChild(txt); root.appendChild(tmp); QDomElement src=doc.createElement("source"); tmp=doc.createElement("database"); txt=doc.createTextNode(""); root.appendChild(src); tmp.appendChild(txt); src.appendChild(tmp); tmp=doc.createElement("annotation"); txt=doc.createTextNode("MyData"); tmp.appendChild(txt); src.appendChild(tmp); tmp=doc.createElement("image"); txt=doc.createTextNode(""); tmp.appendChild(txt); src.appendChild(tmp); src=doc.createElement("owners"); tmp=doc.createElement("flickrid"); txt=doc.createTextNode(""); root.appendChild(src); tmp.appendChild(txt); src.appendChild(tmp); tmp=doc.createElement("name"); txt=doc.createTextNode(""); tmp.appendChild(txt); src.appendChild(tmp); QDomElement size=doc.createElement("size"); tmp=doc.createElement("width"); txt=doc.createTextNode(QString::number(current_src_h)); root.appendChild(size); tmp.appendChild(txt); size.appendChild(tmp); tmp=doc.createElement("height"); txt=doc.createTextNode(QString::number(current_src_w)); tmp.appendChild(txt); size.appendChild(tmp); tmp=doc.createElement("depth"); txt=doc.createTextNode(QString::number(current_dst_image.channels())); tmp.appendChild(txt); size.appendChild(tmp); tmp=doc.createElement("segmented"); txt=doc.createTextNode("0"); tmp.appendChild(txt); root.appendChild(tmp); for(int i=0;i<total_bbox.size();i++) { QDomElement object=doc.createElement("object"); QDomElement name=doc.createElement("name"); QDomText label=doc.createTextNode(total_bbox[i].first); name.appendChild(label); object.appendChild(name); root.appendChild(object); name=doc.createElement("pose"); label=doc.createTextNode(""); name.appendChild(label); object.appendChild(name); name=doc.createElement("truncated"); label=doc.createTextNode(""); name.appendChild(label); object.appendChild(name); name=doc.createElement("difficult"); label=doc.createTextNode(""); name.appendChild(label); object.appendChild(name); cv::Rect rect=portion2scaledReal_unscaled(total_bbox[i].second); QDomElement bndbox=doc.createElement("bndbox"); object.appendChild(bndbox); QDomElement xmin=doc.createElement("xmin"); QDomText txt=doc.createTextNode(QString::number(rect.x)); xmin.appendChild(txt); bndbox.appendChild(xmin); QDomElement ymin=doc.createElement("ymin"); txt=doc.createTextNode(QString::number(rect.y)); ymin.appendChild(txt); bndbox.appendChild(ymin); QDomElement xmax=doc.createElement("xmax"); txt=doc.createTextNode(QString::number(rect.x+rect.width)); xmax.appendChild(txt); bndbox.appendChild(xmax); QDomElement ymax=doc.createElement("ymax"); txt=doc.createTextNode(QString::number(rect.y+rect.height)); ymax.appendChild(txt); bndbox.appendChild(ymax); } QString xmlname=imageFileInfoList[image_info_index]. fileName().split(".")[0]+".xml"; QFile fd(xmlDirString+'/'+xmlname); if(fd.open(QIODevice::WriteOnly |QIODevice::Truncate)) { QTextStream out(&fd); out<<doc; fd.close(); }}void MainWindow::on_PersonradioButton_clicked(){ if(ui->PersonradioButton->isChecked()) rgb=cv::Scalar(255,0,0);}void MainWindow::on_CarradioButton_clicked(){ if(ui->CarradioButton->isChecked()) rgb=cv::Scalar(0,0,255);}void MainWindow::on_BusradioButton_clicked(){ if(ui->BusradioButton->isChecked()) rgb=cv::Scalar(255,255,0);}void MainWindow::on_MotorradioButton_clicked(){ if(ui->MotorradioButton->isChecked()) rgb=cv::Scalar(255,0,255);}void MainWindow::on_BicycleradioButton_clicked(){ if(ui->BicycleradioButton->isChecked()) rgb=cv::Scalar(0,255,0);}bool MainWindow::checkedradioButton(){ return ui->PersonradioButton->isChecked()|| ui->BicycleradioButton->isChecked()|| ui->CarradioButton->isChecked() || ui->BusradioButton->isChecked()|| ui->MotorradioButton->isChecked();}bool MainWindow::isDirExist(QString fullPath){ QDir dir(fullPath); if(dir.exists()) { return true; } else { bool ok=dir.mkdir(fullPath); return ok; }}void MainWindow::clear_current_workspace(){ total_bbox.clear(); for(int i=0;i<listItem.size();i++) { delete listItem[i]; }}cv::Rect MainWindow::portion2scaledReal(cv::Rect_<float> &rect){ cv::Rect tr_rect; tr_rect.x=current_src_image.cols*rect.x; tr_rect.y=current_src_image.rows*rect.y; tr_rect.width=current_src_image.cols*rect.width; tr_rect.height=current_src_image.rows*rect.height; return tr_rect;}cv::Rect MainWindow::portion2scaledReal_unscaled(cv::Rect_<float> &rect){ cv::Rect tr_rect; tr_rect.x=current_src_w*rect.x; tr_rect.y=current_src_h*rect.y; tr_rect.width=current_src_w*rect.width; tr_rect.height=current_src_h*rect.height; return tr_rect;}QString MainWindow::selectedLabel(){ if(ui->BicycleradioButton->isChecked()) return "Bicycle"; if(ui->PersonradioButton->isChecked()) return "Person"; if(ui->CarradioButton->isChecked()) return "Car"; if(ui->MotorradioButton->isChecked()) return "Motor"; if(ui->BusradioButton->isChecked()) return "Bus";}cv::Scalar MainWindow::setColor(QString &label){ cv::Scalar RGB; if(label==QString("Bicycle")) RGB=cv::Scalar(0,255,0); if(label==QString("Person")) RGB=cv::Scalar(255,0,0); if(label== QString("Car")) RGB=cv::Scalar(0,0,255); if(label== QString("Motor")) RGB=cv::Scalar(255,0,255); if(label== QString("Bus")) RGB=cv::Scalar(255,255,0); return RGB;}void MainWindow::on_BBoxlistWidget_itemClicked(QListWidgetItem* it){ int row=ui->BBoxlistWidget->row(it); cv::Mat tmp=current_src_image.clone(); setColor(total_bbox[row].first); cv::rectangle(tmp,portion2scaledReal(total_bbox[row].second),rgb,2); displayMat(tmp);}void MainWindow::on_BBoxlistWidget_itemDoubleClicked(QListWidgetItem* item){ //foreach(QListWidgetItem * item1, item) // { int row=ui->BBoxlistWidget->row(item); ui->BBoxlistWidget->takeItem(row); std::vector<std::pair<QString,cv::Rect_<float> > >::iterator it=total_bbox.begin()+row; total_bbox.erase(it); // } ui->BBoxlistWidget->show(); displayMat(current_src_image);}void MainWindow::on_setXMLDirpushButton_clicked(){ QString DirName=QFileDialog::getExistingDirectory (this, tr("选择文件夹"), tr("C:/Users/CharelCHEN/Desktop/imagedata/xml"), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QString name = code->fromUnicode(DirName).data(); this->xmlDirString=name; xmlDirLabel->setText(tr("保存目录: ")+this->xmlDirString);}
链接:http://pan.baidu.com/s/1i5zcd6H 密码:oolp
阅读全文
1 0
- 深度学习之标注工具【Qt版】
- 深度学习之图像标注工具【python版】
- 介绍| 深度学习数据集标注工具
- NLP+VS︱深度学习数据集标注工具、图像语料数据库、实验室搜索ing...
- NLP+VS︱深度学习数据集标注工具、图像语料数据库、实验室搜索ing...
- NLP+VS︱深度学习数据集标注工具、图像语料数据库、实验室搜索ing...
- NLP+VS︱深度学习数据集标注工具、图像语料数据库、实验室搜索ing...
- 自写图像标注工具 QT+Opencv
- 【深度学习】图像标注评价标准
- 深度学习之工具篇:TensorFlow安装
- 学习:图片标注工具LabelImg使用教程
- 标注工具
- 深度学习开发工具
- 深度学习工具
- 深度学习工具评论
- 深度学习工具收藏
- 深度学习工具汇总
- 深度学习工具-caffe
- 漫谈递归:递归的思想
- localtime()函数的使用问题
- vb.net指定范围内获取随机数
- git学习及基本入门
- re库主要功能函数
- 深度学习之标注工具【Qt版】
- 数组删除重复的数字1方法一:
- 集成学习(Ensemble Learning)
- Ubuntu安装使用google代码规范工具cpplint
- Android Studio安装新的字体
- 基于函数的索引+创建基于函数的索引
- 线段树入门(建树,查询,更新)hdu1754
- Linux重定向命令(stdout, stdin, stderr)
- 使用git提交代码到github及git常用指令