拿到的数据集的图片和label分别放在一起,但是我训练模型验证这些需要将其划分为训练集,验证集,测试集.我的图片都是jpg格式,label都是txt文件,因此比较好整理.
代码工具直接试用情况
下面分享的代码只适用于我这种情况,但是稍微修改一下应该就能对其他情况进行分类了.
运行结果
这样就随机分配好了
源码
ui界面布局
mainwindow.c
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFileInfoList>
#include <QRandomGenerator>
#include <QMessageBox>
#include <algorithm>
#include <numeric>
#include <random>
#include<QDebug>
#include <iostream> // 用于调试输出
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 启用拖放支持
setAcceptDrops(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
readAllTextFilesInDirectory(QFileInfo(txtPath).path(),QFileInfo(imgPath).path());
}
//void MainWindow::readAllTextFilesInDirectory(const QString &directoryPath,const QString &directoryPathimg)
//{
// QDir dir(directoryPath);
// QStringList entryList = dir.entryList(QDir::Files);
// // 获取目录下的所有文件
// QFileInfoList fileList = dir.entryInfoList(QDir::Files);
// int x = fileList.size(); // 文件总数
// // 从界面中获取 y 和 z 的值
// bool okY, okZ;
// int y = ui->textEdit->toPlainText().toInt(&okY);
// int z = ui->textEdit_2->toPlainText().toInt(&okZ);
// // 验证输入是否有效
// if (!okY || !okZ) {
// QMessageBox::warning(this, "错误", "请输入有效的整数。");
// return;
// }
// if (x < y + z) {
// QMessageBox::warning(this, "错误", "文件数量不足,无法完成操作。");
// return;
// }
// // 创建三个文件夹
// QString folder1 = directoryPath + "/训练集";
// QString folder2 = directoryPath + "/验证集";
// QString folder3 = directoryPath + "/测试集";
// // 如果文件夹已经存在,清空文件夹内容
// if (QDir(folder1).exists()) {
// QDir(folder1).removeRecursively();
// }
// if (QDir(folder2).exists()) {
// QDir(folder2).removeRecursively();
// }
// if (QDir(folder3).exists()) {
// QDir(folder3).removeRecursively();
// }
// QDir().mkdir(folder1);
// QDir().mkdir(folder2);
// QDir().mkdir(folder3);
// ui->progressBar->setMinimum(0);
// ui->progressBar->setMaximum(x-1);
// ui->progressBar->setValue(0);
// // 随机选择 y 个文件复制到文件夹 1
// QVector<int> indices(x);
// std::iota(indices.begin(), indices.end(), 0); // 生成 0 到 x-1 的索引
// std::shuffle(indices.begin(), indices.end(), std::default_random_engine(QRandomGenerator::global()->generate())); // 随机打乱索引
// for (int i = 0; i < y; ++i) {
// QString srcFilePath = fileList[indices[i]].absoluteFilePath();
// QString dstFilePath = folder1 + "/" + fileList[indices[i]].fileName();
// QFile::copy(srcFilePath, dstFilePath);
// ui->progressBar->setValue(i); // 更新进度条
// }
// // 从剩下的文件中选择 z 个复制到文件夹 2
// for (int i = y; i < y + z; ++i) {
// QString srcFilePath = fileList[indices[i]].absoluteFilePath();
// QString dstFilePath = folder2 + "/" + fileList[indices[i]].fileName();
// QFile::copy(srcFilePath, dstFilePath);
// ui->progressBar->setValue(i); // 更新进度条
// }
// qDebug()<< x - y + z;
// // 剩下的文件复制到文件夹 3
// for (int i = y + z; i < x; ++i) {
// QString srcFilePath = fileList[indices[i]].absoluteFilePath();
// QString dstFilePath = folder3 + "/" + fileList[indices[i]].fileName();
// QFile::copy(srcFilePath, dstFilePath);
// ui->progressBar->setValue(i); // 更新进度条
// }
// // 完成进度条
// ui->progressBar->setValue(x);
// // 释放进度条
// //progressBar->deleteLater();
// QMessageBox::information(this, "成功", "文件复制完成。");
//}
void MainWindow::on_toolButton_clicked()
{
// 使用 QFileDialog 选择单个 .txt 文件
QString filePath = QFileDialog::getOpenFileName(this, tr("Open File"), "/home", tr("Text Files (*.txt);;Images (*.jpg)"));
if (!filePath.isEmpty()) {
// 将文件路径显示在 QLabel
ui->lineEdit->setText(filePath);
}
txtPath = filePath;
}
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
// 检查拖放的数据是否包含文件路径
if (event->mimeData()->hasUrls()) {
// 只接受 .txt 和 .jpg 文件
QList<QUrl> urls = event->mimeData()->urls();
if (!urls.isEmpty()) {
QString filePath = urls.first().toLocalFile();
if (filePath.endsWith(".txt") || filePath.endsWith(".jpg")) {
event->acceptProposedAction();
}
}
}
}
void MainWindow::dropEvent(QDropEvent *event)
{
// 获取拖放的文件路径
QList<QUrl> urls = event->mimeData()->urls();
if (!urls.isEmpty()) {
QString filePath = urls.first().toLocalFile();
// 检查文件路径是否为 .txt 或 .jpg 文件
if (filePath.endsWith(".txt") || filePath.endsWith(".jpg")) {
// 将文件路径显示在 QLineEdit 中
ui->lineEdit->setText(filePath);
// 记录文件路径
txtPath = filePath;
}
}
}
void MainWindow::on_toolButton_2_clicked()
{
// 使用 QFileDialog 选择单个 .txt 文件
QString filePath = QFileDialog::getOpenFileName(this, tr("Open File"), "/home", tr("Images (*.jpg);;Text Files (*.txt)"));
if (!filePath.isEmpty()) {
// 将文件路径显示在 QLabel
ui->lineEdit_2->setText(filePath);
}
imgPath = filePath;
}
void MainWindow::readAllTextFilesInDirectory(const QString &directoryPath, const QString &directoryPathimg)
{
QDir dir(directoryPath);
QDir dirImg(directoryPathimg);
QStringList entryList = dir.entryList(QDir::Files);
QStringList entryListImg = dirImg.entryList(QDir::Files);
// 获取目录下的所有文件
QFileInfoList fileList = dir.entryInfoList(QDir::Files);
QFileInfoList fileListImg = dirImg.entryInfoList(QDir::Files);
int x = fileList.size(); // 文件总数
// 从界面中获取 y 和 z 的值
bool okY, okZ;
int y = ui->textEdit->toPlainText().toInt(&okY);
int z = ui->textEdit_2->toPlainText().toInt(&okZ);
// 验证输入是否有效
if (!okY || !okZ) {
QMessageBox::warning(this, "错误", "请输入有效的整数。");
return;
}
if (x < y + z) {
QMessageBox::warning(this, "错误", "文件数量不足,无法完成操作。");
return;
}
// 创建一个名为“数据集output”的大文件夹
QString outputFolder = directoryPath + "/数据集output";
if (QDir(outputFolder).exists()) {
QDir(outputFolder).removeRecursively(); // 如果存在,先删除
}
QDir().mkdir(outputFolder);
// 创建三个文件夹
QString folder1 = outputFolder + "/label训练集";
QString folder2 = outputFolder + "/label验证集";
QString folder3 = outputFolder + "/label测试集";
// 创建对应的图片文件夹
QString imgFolder1 = outputFolder + "/img训练集";
QString imgFolder2 = outputFolder + "/img验证集";
QString imgFolder3 = outputFolder + "/img测试集";
// 如果文件夹已经存在,清空文件夹内容
if (QDir(folder1).exists()) {
QDir(folder1).removeRecursively();
}
if (QDir(folder2).exists()) {
QDir(folder2).removeRecursively();
}
if (QDir(folder3).exists()) {
QDir(folder3).removeRecursively();
}
if (QDir(imgFolder1).exists()) {
QDir(imgFolder1).removeRecursively();
}
if (QDir(imgFolder2).exists()) {
QDir(imgFolder2).removeRecursively();
}
if (QDir(imgFolder3).exists()) {
QDir(imgFolder3).removeRecursively();
}
QDir().mkdir(folder1);
QDir().mkdir(folder2);
QDir().mkdir(folder3);
QDir().mkdir(imgFolder1);
QDir().mkdir(imgFolder2);
QDir().mkdir(imgFolder3);
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(x-1);
ui->progressBar->setValue(0);
// 随机选择 y 个文件复制到文件夹 1
QVector<int> indices(x);
std::iota(indices.begin(), indices.end(), 0); // 生成 0 到 x-1 的索引
std::shuffle(indices.begin(), indices.end(), std::default_random_engine(QRandomGenerator::global()->generate())); // 随机打乱索引
for (int i = 0; i < y; ++i) {
QString srcFilePath = fileList[indices[i]].absoluteFilePath();
QString dstFilePath = folder1 + "/" + fileList[indices[i]].fileName();
QFile::copy(srcFilePath, dstFilePath);
// 复制对应的图片
QString imgFileName = fileList[indices[i]].completeBaseName() + ".jpg";
QString imgSrcFilePath = directoryPathimg + "/" + imgFileName;
QString imgDstFilePath = imgFolder1 + "/" + imgFileName;
if (QFile::exists(imgSrcFilePath)) {
QFile::copy(imgSrcFilePath, imgDstFilePath);
}
ui->progressBar->setValue(i); // 更新进度条
}
// 从剩下的文件中选择 z 个复制到文件夹 2
for (int i = y; i < y + z; ++i) {
QString srcFilePath = fileList[indices[i]].absoluteFilePath();
QString dstFilePath = folder2 + "/" + fileList[indices[i]].fileName();
QFile::copy(srcFilePath, dstFilePath);
// 复制对应的图片
QString imgFileName = fileList[indices[i]].completeBaseName() + ".jpg";
QString imgSrcFilePath = directoryPathimg + "/" + imgFileName;
QString imgDstFilePath = imgFolder2 + "/" + imgFileName;
if (QFile::exists(imgSrcFilePath)) {
QFile::copy(imgSrcFilePath, imgDstFilePath);
}
ui->progressBar->setValue(i); // 更新进度条
}
// 剩下的文件复制到文件夹 3
for (int i = y + z; i < x; ++i) {
QString srcFilePath = fileList[indices[i]].absoluteFilePath();
QString dstFilePath = folder3 + "/" + fileList[indices[i]].fileName();
QFile::copy(srcFilePath, dstFilePath);
// 复制对应的图片
QString imgFileName = fileList[indices[i]].completeBaseName() + ".jpg";
QString imgSrcFilePath = directoryPathimg + "/" + imgFileName;
QString imgDstFilePath = imgFolder3 + "/" + imgFileName;
if (QFile::exists(imgSrcFilePath)) {
QFile::copy(imgSrcFilePath, imgDstFilePath);
}
ui->progressBar->setValue(i); // 更新进度条
}
// 完成进度条
ui->progressBar->setValue(x);
QMessageBox::information(this, "成功", "文件复制完成。");
}
希望对大家有所帮助,也希望目标检测yolo大佬来带我飞.