全景图像的展开(qt C++)非核心代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
using namespace std;
QVector<QString> stringlist_img;
QVector<QString> stringlist_txt;
cv::Mat image_class;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //第一组展开数据 x=1337 y= 945 r=235 R=982
    p1_center.x=1337;
    p1_center.y=945;
    out_R=982;//982
    ine_r=235;

}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::read_imgs()
{

    //    QString pathname = QFileDialog::getExistingDirectory(
    //                this,
    //                tr("Open Directory"),
    //                "/home",
    //                QFileDialog::ShowDirsOnly
    //                | QFileDialog::DontResolveSymlinks);
    QString pathname="D:/data_colect/YOLO_my_Dataset/data_test8/images/train2";
    QDir dir(pathname);

    //  cout<<"bian li kai shi "<<endl;
    if(!dir.exists())  return false;

    dir.setFilter(QDir::Files|QDir::NoSymLinks);
    QStringList filters;  filters<<QString("*.jpg");
    dir.setNameFilters(filters);
    int dir_cout = dir.count();
    cout<<dir_cout<<endl;

    ui->img_num_lineEdit->setText(QString::number(dir_cout));
    if(dir_cout<=0)  return false;

    QChar separator = QChar('/');
    if(!pathname.contains(separator))
    {
        separator = QChar('\\');
    }
    QChar last_char = pathname.at(pathname.length()-1);
    if(last_char == separator)
    {
        separator = QChar();
    }
    for(int i=0;i<dir_cout;i++)
    {
        QString file_name = dir[i];  //文件名称
        QString file_path = pathname + separator + file_name;   //文件全路径
        stringlist_img.append(file_path);
        QString j = stringlist_img.at(i);
        //        cout<<j.toLatin1().data()<<endl;
        ui->img_textBrowser->append(j);
    }
    return true;

}
bool MainWindow::read_txt()
{

    //    QString pathname = QFileDialog::getExistingDirectory(
    //                this,
    //                tr("Open Directory"),
    //                "/home",
    //                QFileDialog::ShowDirsOnly
    //                | QFileDialog::DontResolveSymlinks);
    QString pathname="D:/data_colect/YOLO_my_Dataset/data_test8/labels/train2";
    QDir dir(pathname);

    //  cout<<"bian li kai shi "<<endl;
    if(!dir.exists())  return false;

    dir.setFilter(QDir::Files|QDir::NoSymLinks);
    QStringList filters;  filters<<QString("*.txt");
    dir.setNameFilters(filters);
    int dir_cout = dir.count();

    cout<<dir_cout<<endl;
    ui->label_num_lineEdit->setText(QString::number(dir_cout));
    if(dir_cout<=0)  return false;

    QChar separator = QChar('/');
    if(!pathname.contains(separator))
    {
        separator = QChar('\\');
    }
    QChar last_char = pathname.at(pathname.length()-1);
    if(last_char == separator)
    {
        separator = QChar();
    }
    for(int i=0;i<dir_cout;i++)
    {

        QString file_name = dir[i];  //文件名称
        QString file_path = pathname + separator + file_name;   //文件全路径
        stringlist_txt.append(file_path);
        QString j = stringlist_txt.at(i);
        //        cout<<j.toLatin1().data()<<endl;
        ui->label_textBrowser->append(j);
    }
    return true;

}
void MainWindow::on_read_img_btn_clicked()
{
    read_imgs();
}

void MainWindow::on_read_label_btn_clicked()
{
    read_txt();
}

void MainWindow::test_r()
{
    //第一组展开数据 x=1337 y= 945 r=235 R=982
    cv::Mat image;
    //得到展开的图像--没旋转的
    cv::Mat expand1,expand2,last_rotate;//expand1  是直接展开后压缩的, expand2 是展开压缩后进行镜像的 last_rotate 对径向后的进行旋转
    cv::Mat  last_result;
    cv::Mat segmen_two_half,segmen_two_leave ,result_roate;
    cv::Mat segmen_first_half,segmen_first_leave;
    cv::Mat result;
    cv::Mat last_img_result;
    vector< cv::Mat>imgs3;vector< cv::Mat>imgs4;vector< cv::Mat>imgs5;
    qDebug()<<stringlist_img.size();
    for (int i=0;i<stringlist_img.size(); i++)//stringlist_img.size()
    {
        image=cv::imread(stringlist_img.at(i).toStdString());
        qDebug()<<"stringlist_img.at(i).toStdString()"<<stringlist_img.at(i);
        cv::Mat expand =my_expand.expandmat(image,ine_r,out_R,p1_center);
        cv::resize(expand,expand1,cv::Size(5120,720),cv::INTER_LINEAR);
        flip(expand1, expand2, 1);//水平翻转 围绕Y轴
        my_expand.rotateImage(expand2,180,last_rotate);
        //这里为了减少中间会出现断层,所以对其进行扩充

        //先将rotateImage 换成拼成两块
        segmen_two_half=last_rotate;
        segmen_two_leave=last_rotate;
        imgs4.push_back(segmen_two_half);
        imgs4.push_back(segmen_two_leave);
        hconcat(segmen_two_half,segmen_two_leave,result_roate);

        segmen_first_half=result_roate( cv::Range(0,result_roate.rows), cv::Range(0,result_roate.cols*0.25+100));
        segmen_first_leave=result_roate( cv::Range(0,result_roate.rows), cv::Range(result_roate.cols*0.25,result_roate.cols*0.5+100));
        //        qDebug()<<"segmen_first_half.dims"<<segmen_first_half.dims;
        //        qDebug()<<"segmen_first_leave.dims"<<segmen_first_leave.dims;


        imgs3.push_back(segmen_first_half);
        imgs3.push_back(segmen_first_leave);
        vconcat(segmen_first_half,segmen_first_leave, result);

        std::string numb=QString::number(i,10).toStdString();
        QString str_img=QString("D://data_colect//YOLO_my_Dataset//data_test8//new_images2//%1.jpg").arg(i+1);


        cv::imwrite(str_img.toStdString(),result);

        //通过全景里面的坐标读取展开后的坐标。
        QFile file(stringlist_txt.at(i)); //打开文件

        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) //判断能否打开
        {
            return;
        }
        QTextStream in(&file);   //读取文件流

        //读取每一行的内容
        //这里要造一个容器,保存读取每一行的转化数据
        QVector<yolo_data_txt>yolo_data;

        QString line3=in.readLine();
        while(!line3.isNull())
        {
            yolo_data_txt yolo_data_line;
            yolo_data_line.detectionclass=line3.section(' ',0,0).toInt();	//将此次循环的行数据按照' '即空格进行拆分,并取第0个保存为xlocation;
            yolo_data_line.w=int(line3.section(' ',3,3).toDouble()*image.size().width);//将此次循环的行数据按照' '即空格进行拆分,并取第0个保存为xlocation;
            yolo_data_line.h=int(line3.section(' ',4,4).toDouble()*image.size().height);	//将此次循环的行数据按照' '即空格进行拆分,并取第0个保存为xlocation;
            yolo_data_line.x=int(line3.section(' ',1,1).toDouble()*image.size().width-yolo_data_line.w/2);	//将此次循环的行数据按照' '即空格进行拆分,并取第0个保存为xlocation;
            yolo_data_line.y=int(line3.section(' ',2,2).toDouble()*image.size().height-yolo_data_line.h/2);	//将此次循环的行数据按照' '即空格进行拆分,并取第0个保存为xlocation;

            //yolo_data.append()

            yolo_data.append(yolo_data_line);
            //            qDebug()<<"yolo_data_line.detectionclass "<<yolo_data_line.detectionclass<<"yolo_data_line.x: "<<yolo_data_line.x<<"yolo_data_line.y"<<yolo_data_line.y;
            line3=in.readLine();
        }
        //把新的标签记录在txt 文件里
        QString str_txt=QString("D://data_colect//YOLO_my_Dataset//data_test8//new_labels2//%1.txt").arg(i+1);
        QFile p_txt_file(str_txt);
        //这里面是循环每一行的内容的
        for (int j=0;j<yolo_data.size();j++ ) {
            //现在基本上每个点的坐标都有了,我们进行一个转换 将全景里面的坐标转到展开图像中的坐标。
            //            cv::Point p1,p2,p3,p4;
            cv::Point p1(yolo_data.at(j).x,                   yolo_data.at(j).y); //这个是顶点坐标
            cv::Point p2(yolo_data.at(j).x+yolo_data.at(j).w, yolo_data.at(j).y); // 这个是顺时针的 第二个坐标
            cv::Point p3(yolo_data.at(j).x+yolo_data.at(j).w, yolo_data.at(j).y+yolo_data.at(j).h);
            cv::Point p4(yolo_data.                           at(j).x,yolo_data.at(j).y+yolo_data.at(j).h);
            cv::Point p5_center(yolo_data.at(j).x+yolo_data.at(j).w/2,yolo_data.at(j).y+yolo_data.at(j).h/2);
            cv::Point p_test(500,500);
            //获取到展开图上的坐标
            cv::Point p1_expand_2 =quanjing_point_2_expand_point(p1,image);
            cv::Point p2_expand_2 =quanjing_point_2_expand_point(p2,image);
            cv::Point p3_expand_2 =quanjing_point_2_expand_point(p3,image);
            cv::Point p4_expand_2 =quanjing_point_2_expand_point(p4,image);

            //物体的中心这么求才准确
            cv::Point p5_expand_center=quanjing_point_2_expand_point(p5_center,image);

            //这里加一个判断这四个点是否是在同一行,也就是都是上半部分嘛,如果不是,is_split=true

            bool is_split;
            if((p4_expand_2.y<720&&p2_expand_2.y>720)&&((p1_expand_2.x<result.size().width/2)||(p2_expand_2.x<result.size().width/2)))//1 ,4在右上(第一象限),2,3 在左下(第三想想)
            {
                is_split=true;
                // 如果是分开 的判断中心是靠近p1 还是p3
                if(p5_expand_center.y>720 ) //中心在下面
                {

                    p3_expand_2.x=0;
                    p4_expand_2.x=0;
                    p3_expand_2.y=p2_expand_2.y;
                    p4_expand_2.y=p1_expand_2.y;

                }else if(p5_expand_center.y<720)//中心在上面
                {
                    p1_expand_2.x=result.size().width; //
                    p2_expand_2.x=result.size().width;
                    p1_expand_2.y=p4_expand_2.y;
                    p2_expand_2.y=p3_expand_2.y;
                }
            }

            else if(p1_expand_2.y>720&&p3_expand_2.y<720&&p1_expand_2.x>result.size().width/2) //1 ,2在下(),3,4在上()
            {
                is_split=true;
                // 如果是分开 的判断中心是靠近p1 还是p3
                if(p5_expand_center.y>720 ) //中心在下面的时候
                {

                    p3_expand_2.x=result.size().width;
                    p3_expand_2.y=p2_expand_2.y;
                    p4_expand_2.x=result.size().width;
                    p4_expand_2.y=p1_expand_2.y;
                }else if(p5_expand_center.y<720)//中心在上面的时候
                {
                    p1_expand_2.x=0;
                    p1_expand_2.y=p4_expand_2.y;

                    p2_expand_2.x=0;
                    p2_expand_2.y=p3_expand_2.y;
                }

            }else{
                is_split=false;
            }



            //物体四个点求出中心点的坐标
            cv::Point class_center;
            int wM_class,w1_class ,w2_class,hM_class,h1_class,h2_class;
            w1_class=abs(p1_expand_2.x-p3_expand_2.x);
            h1_class=abs(p1_expand_2.y-p3_expand_2.y);
            w2_class=abs(p2_expand_2.x-p4_expand_2.x);
            h2_class=abs(p2_expand_2.y-p4_expand_2.y);
            //            qDebug()<<"w1_class: "<<w1_class<<"w2_class "<<w2_class;
            //这里都是取最大的
            if(w1_class>w2_class)
            {
                wM_class=w1_class;
            }else
            {
                wM_class=w2_class;
            }
            if(h1_class>h2_class)
            {
                hM_class=h1_class;
            }else
            {
                hM_class=h2_class;
            }

            class_center.x=(p1_expand_2.x+p3_expand_2.x)/2;
            class_center.y=(p1_expand_2.y+p3_expand_2.y)/2;


            class_center=p5_expand_center;
            if(yolo_data.at(j).detectionclass==0&&hM_class>70)
            {
                hM_class=70;
                class_center.y=class_center.y-24;
            }

            double w_nirmalization=double(wM_class)/double(result.size().width);
            double h_nirmalization=double(hM_class)/double(result.size().height);
            double x_nirmalization=double(class_center.x)/double(result.size().width);
            double y_nirmalization=double(class_center.y)/double(result.size().height);
            QString line = QString("%1 %2 %3 %4 %5").arg(yolo_data.at(j).detectionclass).arg(x_nirmalization).arg(y_nirmalization).arg(w_nirmalization).arg(h_nirmalization);
            appendLineToFile(str_txt,line);
            //            qDebug()<<"str_txt"<<str_txt;

            //下面这一快都是测试代码:
            //            qDebug()<<" class_center.x" <<class_center.x<<" class_center.y"<< class_center.y;

            //  qDebug()<<p1_expand_2.x<<p1_expand_2.y;
            cv::circle(result,p1_expand_2,3,cv::Scalar(0,0,255),3);//纯红色
            cv::circle(result,p2_expand_2,3,cv::Scalar(255,0,0),3);//纯蓝色
            cv::circle(result,p3_expand_2,3,cv::Scalar(0,255,0),3);// 纯绿色
            cv::circle(result,p4_expand_2,3,cv::Scalar(0,255,255),3);//黄色
            cv::circle(result,class_center,3,cv::Scalar(255,250,0),3);//

            cv::circle(image,p1,3,cv::Scalar(0,0,255),3);//
            cv::circle(image,p2,3,cv::Scalar(255,0,0),3);//
            cv::circle(image,p3,3,cv::Scalar(0,255,0),3);//
            cv::circle(image,p4,3,cv::Scalar(0,255,255),3);//
            cv::Rect rect_box(yolo_data.at(j).x,yolo_data.at(j).y,yolo_data.at(j).w,yolo_data.at(j).h);//在原图上画
            cv::Rect rect_box2(class_center.x-wM_class/2,class_center.y-hM_class/2,wM_class,hM_class);//在原图上画
            cv::rectangle(image,rect_box,cv::Scalar(255,0,255));
            cv::rectangle(result,rect_box2,cv::Scalar(255,0,255));

            // cv::imwrite("D://1.jpg",image);
            // cv::imwrite("D://2.jpg",result);
//            QString str_quanjing_img=QString("D://data_colect//YOLO_my_Dataset//data_test8//test_quanjing_images//%1.jpg").arg(i+1);
//            QString str_expand_img=QString("D://data_colect//YOLO_my_Dataset//data_test8//test_expand_images//%1.jpg").arg(i+1);
//            cv::imwrite(str_quanjing_img.toStdString(),image);
//            cv::imwrite(str_expand_img.toStdString(),result);
            // //画图 --为了验证位置的准确性
        }



    }



}
// 追加一行文本到文件末尾
void MainWindow::appendLineToFile(const QString& fileName, const QString& line)
{
    QFile file(fileName);
    if (!file.open(QIODevice::Append| QIODevice::Text))
        return;

    QTextStream out(&file);
    out <<line<<endl ;
}
void MainWindow::on_copy_cpast_start_btn_clicked()
{
    test_r();
}
//传过来值可以直接得到展开图像上的点 --这个展开图是
cv::Point MainWindow::quanjing_point_2_expand_point(cv::Point p_,cv::Mat img_ini)
{

    cv::Point pt,p1_expand;// 这个是转换后的坐标
    //首先计算出 半径和弧度

    double dw_Angle,theat_Angle;// theat_Angle点和圆心的弧度 这个不是角度, dw_Angle 是弧长, 角度的画要转换一下(theat/3.14)*180
    double Radius; // 这是点和圆心的距离
    Radius =sqrt((p_.x-p1_center.x)*(p_.x-p1_center.x) +(p_.y-p1_center.y)*(p_.y-p1_center.y));   //根号下(x^2 +y^2)求出它和圆心的半径
    if(Radius>out_R) //判断这个点是否超过圆的边界对它
    {
        Radius=out_R;
    }


    if(p_.x-p1_center.x>=0&&p_.y-p1_center.y<=0)//判断在第一象限
    {
        theat_Angle =2*3.1415926-qAcos((p_.x-p1_center.x)/Radius); // 这个求出弧度,
    }
    else if(p_.x-p1_center.x<=0 &&p_.y-p1_center.y<=0)//判断在第二象限
    {
        theat_Angle =qAcos((p1_center.x-p_.x)/Radius)+3.1415926; // 这个求出弧度,
    }
    else if(p_.x-p1_center.x<=0 &&p_.y-p1_center.y>=0)
    {
        theat_Angle =3.14-qAcos((p1_center.x-p_.x)/Radius); // 这个求出弧度,
    }
    else //这个是第四象限
    {
        theat_Angle =qAcos((p_.x-p1_center.x)/Radius); // 这个求出弧度,
    }


    dw_Angle =(theat_Angle/(2*3.1415926))*(2*3.14*out_R);   //弧长 0
    p1_expand.x= dw_Angle;
    p1_expand.y= Radius-ine_r;

    //上面是直接将 全景坐标换成展开坐标




    //由于展开图等比例放大了, 所以我们也等比例放大点的坐标         cv::resize(expand,expand1,cv::Size(5120,720),cv::INTER_LINEAR);
    cv::Point size_p1_expand;
    size_p1_expand.x=int(double((5120/double(2*3.14*out_R)))*double(p1_expand.x));

    size_p1_expand.y=int(double((720/double(out_R-ine_r)))*double(p1_expand.y));
    //由于图像进行了水平翻转  x 变,y 不变
    cv::Point p2_flip;
    p2_flip.x=5120-size_p1_expand.x;
    p2_flip.y=size_p1_expand.y;
    //图片又进行了一个旋转  x 变,y 变
    cv::Point roation_P;
    roation_P.x=5120-p2_flip.x;
    roation_P.y=720-p2_flip.y;
    //图片进行裁剪成一半 然后重新拼接
    cv::Point contact_p;
    if(roation_P.x>2660) //这里应该有个堆区所以对它进行扩充了100,
    {
        contact_p.x=roation_P.x-2560;
        contact_p.y=roation_P.y+720;
    }else
    {
        contact_p.x=roation_P.x;
        contact_p.y=roation_P.y;
    }
    pt=contact_p;

    return pt;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

V建模忠哥V

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值