深度学习之标注工具【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

原创粉丝点击