#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;
}
06-07