发现由OPENAI 01生成的问答

探索OPENAI01回答的公开问题

OpenAI 01 迷你版

Token Validation in Electron

const { app, BrowserWindow, session } = require('electron'); function createWindow() { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: false, contextIsolation: true, devTools: false, // 禁用主窗口开发者工具 }, }); // 禁用 F12 和 Ctrl+Shift+I 开发者工具快捷键 win.webContents.on('before-input-event', (event, input) => { if (input.key === 'F12' || (input.control && input.shift && input.key === 'I')) { event.preventDefault(); // 禁止 F12 和 Ctrl+Shift+I } }); // 处理新窗口的打开行为 win.webContents.setWindowOpenHandler(({ url }) => { // 如果你想禁止所有新窗口弹出,可以返回 { action: 'deny' } return { action: 'allow', // 允许新窗口打开 overrideBrowserWindowOptions: { webPreferences: { devTools: false, // 禁用新窗口的开发者工具 nodeIntegration: false, contextIsolation: true, } } }; }); // 处理新窗口的创建 app.on('web-contents-created', (event, contents) => { // 拦截所有窗口和 WebView 创建事件 if (contents.getType() === 'webview' || contents.getType() === 'window') { // 禁用新窗口的开发者工具 contents.on('before-input-event', (event, input) => { if (input.key === 'F12' || (input.control && input.shift && input.key === 'I')) { event.preventDefault(); // 禁用新窗口的快捷键 } }); contents.on('devtools-opened', () => { contents.closeDevTools(); // 强制关闭任何已打开的开发者工具 }); } }); win.loadURL( 'https://foo.bar' ); } app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); }); =========== 在 win.loadURL( 'https://foo.bar' );之前加一段程序,先弹出一个输入框,输入一个Token字符串,这个字符串有2部分组成,中间用"mclubmclub"隔开,例如20240101mclubmclubhttp://foo.bar,前一部分是这个Token字符串的expireDate,后面一部分是Token后面win.loadURL的首页。输入完字符串后js要判断如果过期则提示用户并退出系统,如果没过期则load首页。所有程序都只放在一个main.js中完成,输入框也放在这个唯一的js文件中

由 wu joe 与 OPENAI01 创建
OpenAI 01 迷你版

Token验证与页面加载

const { app, BrowserWindow, session } = require('electron'); function createWindow() { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: false, contextIsolation: true, devTools: false, // 禁用主窗口开发者工具 }, }); // 禁用 F12 和 Ctrl+Shift+I 开发者工具快捷键 win.webContents.on('before-input-event', (event, input) => { if (input.key === 'F12' || (input.control && input.shift && input.key === 'I')) { event.preventDefault(); // 禁止 F12 和 Ctrl+Shift+I } }); // 处理新窗口的打开行为 win.webContents.setWindowOpenHandler(({ url }) => { // 如果你想禁止所有新窗口弹出,可以返回 { action: 'deny' } return { action: 'allow', // 允许新窗口打开 overrideBrowserWindowOptions: { webPreferences: { devTools: false, // 禁用新窗口的开发者工具 nodeIntegration: false, contextIsolation: true, } } }; }); // 处理新窗口的创建 app.on('web-contents-created', (event, contents) => { // 拦截所有窗口和 WebView 创建事件 if (contents.getType() === 'webview' || contents.getType() === 'window') { // 禁用新窗口的开发者工具 contents.on('before-input-event', (event, input) => { if (input.key === 'F12' || (input.control && input.shift && input.key === 'I')) { event.preventDefault(); // 禁用新窗口的快捷键 } }); contents.on('devtools-opened', () => { contents.closeDevTools(); // 强制关闭任何已打开的开发者工具 }); } }); win.loadURL( 'https://foo.bar' ); } app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); }); =========== 在 win.loadURL( 'https://foo.bar' );之前加一段程序,先弹出一个输入框,输入一个Token字符串,这个字符串有2部分组成,中间用"mclubmclub"隔开,例如20240101mclubmclubhttp://foo.bar,前一部分是这个Token字符串的expireDate,后面一部分是Token后面win.loadURL的首页。输入完字符串后js要判断如果过期则提示用户并退出系统,如果没过期则load首页。所有程序都放在一个main.js中完成

由 wu joe 与 OPENAI01 创建
OpenAI 01 迷你版

Token Validation in Electron

const { app, BrowserWindow, session } = require('electron'); function createWindow() { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: false, contextIsolation: true, devTools: false, // 禁用主窗口开发者工具 }, }); // 禁用 F12 和 Ctrl+Shift+I 开发者工具快捷键 win.webContents.on('before-input-event', (event, input) => { if (input.key === 'F12' || (input.control && input.shift && input.key === 'I')) { event.preventDefault(); // 禁止 F12 和 Ctrl+Shift+I } }); // 处理新窗口的打开行为 win.webContents.setWindowOpenHandler(({ url }) => { // 如果你想禁止所有新窗口弹出,可以返回 { action: 'deny' } return { action: 'allow', // 允许新窗口打开 overrideBrowserWindowOptions: { webPreferences: { devTools: false, // 禁用新窗口的开发者工具 nodeIntegration: false, contextIsolation: true, } } }; }); // 处理新窗口的创建 app.on('web-contents-created', (event, contents) => { // 拦截所有窗口和 WebView 创建事件 if (contents.getType() === 'webview' || contents.getType() === 'window') { // 禁用新窗口的开发者工具 contents.on('before-input-event', (event, input) => { if (input.key === 'F12' || (input.control && input.shift && input.key === 'I')) { event.preventDefault(); // 禁用新窗口的快捷键 } }); contents.on('devtools-opened', () => { contents.closeDevTools(); // 强制关闭任何已打开的开发者工具 }); } }); win.loadURL( 'https://foo.bar' ); } app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); }); =========== 在 win.loadURL( 'https://foo.bar' );之前加一段程序,先弹出一个输入框,输入一个Token字符串,这个字符串有2部分组成,中间用"mclubmclub"隔开,例如20240101mclubmclubhttp://foo.bar,前一部分是这个Token字符串的expireDate,后面一部分是Token后面win.loadURL的首页。输入完字符串后js要判断如果过期则提示用户并退出系统,如果没过期则load首页。

由 wu joe 与 OPENAI01 创建
OpenAI 01 迷你版

数据集合并与处理

# First, let's identify the different data sets from the files you provided. # We have several names such as dolphin, golden_fish, griffen, mermaid, seahorse, shark, butterfly, unicorn. # We will group them accordingly and then combine the same datasets across different algorithms. import os # Prepare the base names for grouping base_names = ["butterfly", "dolphin", "golden_fish", "griffen", "mermaid", "seahorse", "shark", "unicorn"] # Function to load the CSV files and combine them for comparison by dataset def load_and_combine(base_name): # Load the CSV files for the specified base name ppo_df = pd.read_csv(f"/mnt/data/{base_name}_ppo.csv") sac_df = pd.read_csv(f"/mnt/data/{base_name}_sac.csv") xu_df = pd.read_csv(f"/mnt/data/{base_name}_xu.csv") zhao_df = pd.read_csv(f"/mnt/data/{base_name}_zhao.csv") # Combine into a single dataframe combined_df = pd.DataFrame( { "指标": ppo_df["指标"], f"{base_name}_ppo": ppo_df["数值"], f"{base_name}_sac": sac_df["数值"], f"{base_name}_xu": xu_df["数值"], f"{base_name}_zhao": zhao_df["数值"], } ) return combined_df # Initialize a dictionary to store combined dataframes for each dataset combined_datasets = {base: load_and_combine(base) for base in base_names} # Save each combined dataset into CSV for base, df in combined_datasets.items(): df.to_csv(f"/mnt/data/comparison_{base}.csv", index=False) # List all the generated CSV files for the user to download generated_files = [f"comparison_{base}.csv" for base in base_names] generated_files 对于以上代码,参考下面文件进行修改 ❯ ls 3_ppo.csv 5_sac.csv 7_xu.csv butterfly_zhao.csv dolphin_zhao.csv griffen_ppo.csv mermaid_sac.csv seahorse_xu.csv shark_zhao.csv 3_sac.csv 5_xu.csv 7_zhao.csv data_gen.py golden_fish_ppo.csv griffen_sac.csv mermaid_xu.csv seahorse_zhao.csv unicorn_ppo.csv 3_xu.csv 5_zhao.csv butterfly_ppo.csv dolphin_ppo.csv golden_fish_sac.csv griffen_xu.csv mermaid_zhao.csv shark_ppo.csv unicorn_sac.csv 3_zhao.csv 7_ppo.csv butterfly_sac.csv dolphin_sac.csv golden_fish_xu.csv griffen_zhao.csv seahorse_ppo.csv shark_sac.csv unicorn_xu.csv 5_ppo.csv 7_sac.csv butterfly_xu.csv dolphin_xu.csv golden_fish_zhao.csv mermaid_ppo.csv seahorse_sac.csv shark_xu.csv unicorn_zhao.csv

由 张晋 与 OPENAI01 创建
OpenAI 01 迷你版

GPU Task Assignment Script

#!/bin/bash # ================================ # Configuration # ================================ # 数据集列表 data_list=("3" "5" "7" "butterfly" "dolphin" "golden_fish" "griffen" "mermaid" "seahorse" "shark" "unicorn") # Concat 环境名称 CONDA_ENV="kirl" # GPU 数量 NUM_GPUS=8 # 每个 GPU 的最大任务数 MAX_TASKS_PER_GPU=2 # 日志目录 LOG_DIR="./logs" # ================================ # Function Definitions # ================================ # 初始化日志目录 init_logs() { if [ ! -d "$LOG_DIR" ]; then mkdir -p "$LOG_DIR" if [ $? -ne 0 ]; then echo "Error: Failed to create log directory at $LOG_DIR" exit 1 fi fi } # 激活 conda 环境 activate_conda_env() { # 尝试找到 conda 的安装路径 if [ -f "$HOME/miniconda3/etc/profile.d/conda.sh" ]; then source "$HOME/miniconda3/etc/profile.d/conda.sh" elif [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then source "$HOME/anaconda3/etc/profile.d/conda.sh" else echo "Error: Conda not found. Please ensure Conda is installed." exit 1 fi # 激活指定的 conda 环境 conda activate "$CONDA_ENV" if [ $? -ne 0 ]; then echo "Error: Failed to activate conda environment '$CONDA_ENV'" exit 1 fi } # 分配 GPU assign_gpus() { # 创建一个数组来跟踪每个 GPU 的当前任务数 for ((i=0; i<NUM_GPUS; i++)); do gpu_tasks[$i]=0 done } # 获取下一个可用的 GPU get_available_gpu() { for ((i=0; i<NUM_GPUS; i++)); do if [ "${gpu_tasks[$i]}" -lt "$MAX_TASKS_PER_GPU" ]; then echo "$i" return fi done # 如果所有 GPU 都满了,等待一段时间后重试 echo "-1" } # ================================ # Main Script # ================================ # 初始化日志目录 init_logs # 激活 conda 环境 # activate_conda_env # 分配 GPU assign_gpus # 遍历数据集列表并分配任务 for data in "${data_list[@]}"; do assigned=false while [ "$assigned" = false ]; do gpu_id=$(get_available_gpu) if [ "$gpu_id" -ge "0" ]; then # 分配 GPU gpu_tasks[$gpu_id]=$((gpu_tasks[$gpu_id] + 1)) assigned=true # 设置 CUDA_VISIBLE_DEVICES 并运行训练脚本 ( export CUDA_VISIBLE_DEVICES=$gpu_id # 运行 train.py python train.py --data "$data" > "$LOG_DIR/train_${data}.log" 2>&1 if [ $? -ne 0 ]; then echo "Error: train.py failed for data '$data'. Check log: $LOG_DIR/train_${data}.log" fi # 运行 train_sac.py python train_sac.py --data "$data" > "$LOG_DIR/train_sac_${data}.log" 2>&1 if [ $? -ne 0 ]; then echo "Error: train_sac.py failed for data '$data'. Check log: $LOG_DIR/train_sac_${data}.log" fi # 任务完成,减少 GPU 任务计数 gpu_tasks[$gpu_id]=$((gpu_tasks[$gpu_id] - 1)) ) & else # 所有 GPU 都满了,等待一秒后重试 sleep 1 fi done done # 等待所有后台任务完成 wait echo "All training tasks have been completed." # ================================ # End of Script # ================================ 参考以上代码,实现一个评估的脚本,其中的核心为: python eval.py --data "$data" 以及 python eval_sac.py --data "$data"

由 张晋 与 OPENAI01 创建
OpenAI 01 迷你版

Python PyQt LabCD 实现

使用python和pyqt实现以下代码: #include <iostream> #include <QMenuBar> #include <QToolBar> #include <QStatusBar> #include <QDockWidget> #include <QGraphicsView> #include <QAction> #include <QString> #include <QDesktopServices> #include <QFile> #include <QFileInfo> #include <QMessageBox> #include <QColorDialog> #include <QFileDialog> #include <QInputDialog> #include <QtConcurrent/qtconcurrentrun.h> #include <opencv2/opencv.hpp> #include "labcd.h" #include "utils/fileworker.h" #include "utils/imgpress.h" #include "widgets/annotationview.h" LabCD::LabCD(QWidget* parent) : QMainWindow(parent) { setting = new QSettings("./configs/setting.ini", QSettings::IniFormat); isCN = setting->value("language").toString() != "EN"; /* 状态栏 */ QStatusBar* lcdStatusBar = statusBar(); messageState = new QLabel("", this); // 用于显示消息 QLabel* messageLocal = new QLabel("", this); // 用于显示坐标 lcdStatusBar->addWidget(messageState); lcdStatusBar->addPermanentWidget(messageLocal); /* 菜单栏 */ QMenuBar* lcdMenuBar = menuBar(); QMenu* fileMenu = new QMenu(tr("文件"), this); QAction* opensAct = fileMenu->addAction( QIcon(":/menu/resources/Folder.png"), tr("打开文件夹")); opensAct->setShortcut(QKeySequence("Ctrl+O")); connect(opensAct, &QAction::triggered, this, &LabCD::openDir); fileMenu->addSeparator(); QAction* splitAct = fileMenu->addAction( QIcon(":/menu/resources/Split.png"), tr("切分大图")); splitAct->setShortcut(QKeySequence("Ctrl+B")); connect(splitAct, &QAction::triggered, this, &LabCD::openBigImageFile); QAction* mergeAct = fileMenu->addAction( QIcon(":/menu/resources/Merge.png"), tr("合并大图")); mergeAct->setShortcut(QKeySequence("Ctrl+M")); connect(mergeAct, &QAction::triggered, this, &LabCD::mergeBigImage); QAction* clearAct = fileMenu->addAction( QIcon(":/menu/resources/ClearMask.png"), tr("清理空白标签")); connect(clearAct, &QAction::triggered, this, &LabCD::clearEmptyMask); QAction* convertAct = fileMenu->addAction( QIcon(":/menu/resources/Convert.png"), tr("从标签建立标注")); connect(convertAct, &QAction::triggered, this, &LabCD::convertMask2Json); lcdMenuBar->addMenu(fileMenu); QMenu* aboutMenu = new QMenu(tr("关于"), this); QAction* githubAct = aboutMenu->addAction( QIcon(":/menu/resources/Github.png"), tr("github主页")); connect(githubAct, &QAction::triggered, [=]() { QDesktopServices::openUrl(QUrl("https://github.com/geoyee/LabCD")); }); QAction* helpAct = aboutMenu->addAction( QIcon(":/menu/resources/Help.png"), tr("使用帮助")); connect(helpAct, &QAction::triggered, [=]() { QString tutorial = "https://github.com/geoyee/LabCD/tree/develop/docs/Usage_tutorial.md"; if (!isCN) tutorial = "https://github.com/geoyee/LabCD/tree/develop/docs/Usage_tutorial_en.md"; QDesktopServices::openUrl(QUrl(tutorial)); }); helpAct->setShortcut(QKeySequence("Ctrl+H")); lcdMenuBar->addMenu(aboutMenu); QMenu* languMenu = new QMenu(tr("语言"), this); QAction* setLangeAct; if (isCN) setLangeAct = languMenu->addAction( QIcon(":/menu/resources/English.png"), tr("英文")); else setLangeAct = languMenu->addAction( QIcon(":/menu/resources/Chinese.png"), tr("中文")); connect(setLangeAct, &QAction::triggered, [=]() { if (isCN) { setLangeAct->setIcon(QIcon(":/menu/resources/Chinese.png")); setLangeAct->setText(tr("中文")); setting->setValue("language", "EN"); } else { setLangeAct->setIcon(QIcon(":/menu/resources/English.png")); setLangeAct->setText(tr("英文")); setting->setValue("language", "CN"); } isCN = !isCN; QMessageBox::information( parent, QObject::tr("提示"), QObject::tr("重启软件后更新语言设置。") ); }); lcdMenuBar->addMenu(languMenu); /* 绘图界面 */ drawCanvas = new MultCanvas(this); connect(drawCanvas->t1Canva->aView, &AnnotationView::mousePosChanged, [=](double x, double y) { messageLocal->setText( tr("当前坐标:") + \ QString::fromStdString(std::to_string(x)) + ", " + \ QString::fromStdString(std::to_string(y))); }); connect(drawCanvas->t2Canva->aView, &AnnotationView::mousePosChanged, [=](double x, double y) { messageLocal->setText( tr("当前坐标:") + \ QString::fromStdString(std::to_string(x)) + ", " + \ QString::fromStdString(std::to_string(y))); }); setCentralWidget(drawCanvas); /* 图像文件列表 */ QDockWidget* filesDock = new QDockWidget(tr("数据列表"), this); filesDock->setMinimumWidth(200); filesDock->setAllowedAreas(Qt::RightDockWidgetArea); fListWidget = new FileList(this); // 保存图像 connect(fListWidget, &FileList::saveLastFileRequest, this, &LabCD::save); // 加载图像 connect(fListWidget, &FileList::FileClickRequest, [=](QString t1Path, QString t2Path, QString jsonPath) { drawCanvas->loadImages(t1Path, t2Path, jsonPath); updatePolysColor(); QFileInfo fileInfo(t1Path); fileName = fileInfo.fileName(); messageState->setText(tr("加载图像:") + t1Path); }); filesDock->setWidget(fListWidget); addDockWidget(Qt::RightDockWidgetArea, filesDock); /* 标签列表 */ QDockWidget* labelsDock = new QDockWidget(tr("标签列表"), this); labelsDock->setMinimumWidth(200); labelsDock->setAllowedAreas(Qt::RightDockWidgetArea); labTableWidget = new LabelTable(this); labelsDock->setWidget(labTableWidget); connect(labTableWidget, &LabelTable::labelSelected, [=](Label* nowLabel) { drawCanvas->labelSelected(nowLabel); messageState->setText(tr("当前标签:[") + \ QString::fromStdString(std::to_string(nowLabel->getIndex())) + \ "] " + nowLabel->getName()); }); connect(labTableWidget, &LabelTable::colorChanged, [=](int labelIndex, QColor newColor) { // 更新界面上的多边形颜色 for (int i = 0; i < drawCanvas->t1Canva->aScene->polygonItems.count(); ++i) { if (drawCanvas->t1Canva->aScene->polygonItems[i]->labelIndex == \ labelIndex) { drawCanvas->t1Canva->aScene->polygonItems[i]->setColor( newColor, newColor); drawCanvas->t2Canva->aScene->polygonItems[i]->setColor( newColor, newColor); } drawCanvas->t1Canva->aScene->setColor(newColor, newColor); drawCanvas->t2Canva->aScene->setColor(newColor, newColor); } }); // 同步Json的加载 connect(drawCanvas->t1Canva, &Canvas::addJsonPoly, \ labTableWidget, &LabelTable::changeLabelDuotoAddPolyJson); addDockWidget(Qt::RightDockWidgetArea, labelsDock); /* 工具栏 */ QToolBar* lcdToolBar = new QToolBar(this); QAction* saveAct = lcdToolBar->addAction( QIcon(":/tools/resources/Save.png"), tr("保存")); saveAct->setShortcut(QKeySequence("Ctrl+S")); connect(saveAct, &QAction::triggered, this, &LabCD::save); lcdToolBar->addSeparator(); QAction* lastAct = lcdToolBar->addAction( QIcon(":/tools/resources/Last.png"), tr("上一张")); connect(lastAct, &QAction::triggered, [=]() { save(); fListWidget->gotoLastItem(); }); lastAct->setShortcut(QKeySequence("S")); QAction* nextAct = lcdToolBar->addAction( QIcon(":/tools/resources/Next.png"), tr("下一张")); nextAct->setShortcut(QKeySequence("F")); connect(nextAct, &QAction::triggered, [=]() { save(); fListWidget->gotoNextItem(); }); lcdToolBar->addSeparator(); QAction* enlargeAct = lcdToolBar->addAction( QIcon(":/tools/resources/Enlarge.png"), tr("放大")); connect(enlargeAct, &QAction::triggered, [=]() { drawCanvas->t1Canva->aView->scaleZoom(1.1); // 自动同步t2 }); QAction* narrowAct = lcdToolBar->addAction( QIcon(":/tools/resources/Narrow.png"), tr("缩小")); connect(narrowAct, &QAction::triggered, [=]() { drawCanvas->t1Canva->aView->scaleZoom(0.9); // 自动同步t2 }); QAction* fullAct = lcdToolBar->addAction( QIcon(":/tools/resources/Full.png"), tr("全幅缩放")); fullAct->setShortcut(QKeySequence("Ctrl+F")); connect(fullAct, &QAction::triggered, [=]() { if (drawCanvas->imageWidth != 0 && drawCanvas->imageHeight != 0) drawCanvas->t1Canva->resetZoom( drawCanvas->imageWidth, drawCanvas->imageHeight); // 自动同步t2 }); lcdToolBar->addSeparator(); QAction* delPolyAct = lcdToolBar->addAction( QIcon(":/tools/resources/DeletePolygon.png"), tr("删除多边形")); connect(delPolyAct, &QAction::triggered, [=]() { int f1Index = drawCanvas->t1Canva->aScene->findFocusPolygon(); int f2Index = drawCanvas->t2Canva->aScene->findFocusPolygon(); int delIndex = f1Index > f2Index ? f1Index : f2Index; drawCanvas->t1Canva->aScene->delPoly(delIndex); drawCanvas->t2Canva->aScene->delPoly(delIndex); }); delPolyAct->setShortcut(QKeySequence("Backspace")); QAction* delAllPolysAct = lcdToolBar->addAction( QIcon(":/tools/resources/DeleteAllPolygons.png"), tr("删除所有多边形")); connect(delAllPolysAct, &QAction::triggered, [=]() { drawCanvas->t1Canva->aScene->removeAllPolygons(); drawCanvas->t2Canva->aScene->removeAllPolygons(); }); delAllPolysAct->setShortcut(QKeySequence("Delete")); lcdToolBar->addSeparator(); QAction* crossColorAct = lcdToolBar->addAction( QIcon(":/tools/resources/Color.png"), tr("设置十字丝颜色")); connect(crossColorAct, &QAction::triggered, this, &LabCD::setCrossPenColor); lcdToolBar->addSeparator(); QAction* isCVAAct = lcdToolBar->addAction( QIcon(":/tools/resources/Reference.png"), tr("打开变化参考图")); isCVAAct->setCheckable(true); // 完成 lcdToolBar->setMovable(false); addToolBar(Qt::LeftToolBarArea, lcdToolBar); /* 变化参考图 */ QDockWidget* refDock = new QDockWidget(tr("光谱变化向量强度参考图"), this); refDock->setAllowedAreas(Qt::NoDockWidgetArea); QLabel* imgRef = new QLabel(this); refDock->setFloating(true); refDock->hide(); connect(drawCanvas, &MultCanvas::addimgDiff, [=](cv::Mat imgDiff) { if (isCVAAct->isChecked()) { refNewHeight = refNewWidth * imgDiff.rows / imgDiff.cols; cv::cvtColor(imgDiff, imgDiff, cv::COLOR_RGB2BGR); cv::resize(imgDiff, imgDiff, cv::Size(refNewWidth, refNewHeight)); QImage qimg = QImage( (const uchar*)(imgDiff.data), imgDiff.cols, imgDiff.rows, imgDiff.cols * imgDiff.channels(), QImage::Format_RGB888 ); imgRef->setPixmap(QPixmap::fromImage(qimg)); refDock->setFixedSize(refNewWidth, refNewHeight); refDock->show(); } }); refDock->setWidget(imgRef); addDockWidget(Qt::NoDockWidgetArea, refDock); /* 界面设置 */ resize(1200, 600); setWindowTitle(tr("LabCD - 遥感变化检测标注工具")); setWindowIcon(QIcon(":/main/resources/Icon.png")); } LabCD::~LabCD() { } void LabCD::openDir() { QStringList t1List; QStringList t2List; if (FileWorker::openImageDir(&t1List, &t2List, nullptr, this)) { // 新建保存目录 QFileInfo fileInfo(t1List.at(0)); savePath = fileInfo.path(); savePath = savePath.replace("\\", "/"); savePath = savePath.section("/", 0, -2); QString saveImgPath = savePath + "/GT"; FileWorker::createFolder(saveImgPath); // 加载已有标签 QString jsonPath = savePath + "/label.json"; QFileInfo jsonFileInfo(jsonPath); if (jsonFileInfo.isFile()) labTableWidget->importLabelFromFile(jsonPath); // 加载图像 fListWidget->addFileNames(t1List, t2List); fListWidget->gotoItem(0); // 加载总进度 fListWidget->resetProgress(); } } void LabCD::openBigImageFile() { // 获取文件路径 QString fileName = QFileDialog::getOpenFileName( this, tr("打开大图像"), QString(), tr("栅格图像文件 (*.tif *.tiff)") ); if (fileName == "") return; QString saveDir = QFileInfo(fileName).absolutePath() + \ QDir::separator() + "split_output"; saveDir = saveDir.replace("\\", "/"); FileWorker::createFolder(saveDir); // 获取切分大小 bool blockOk = false; int blockSize = QInputDialog::getInt( this, tr("设置"), tr("设置切块大小"), 512, 1, 2048, 1, &blockOk ); if (!blockOk) return; QtConcurrent::run([=]() { if (ImagePress::splitTiff(fileName, saveDir, blockSize, blockSize)) messageState->setText(tr("切分完成,保存至:") + saveDir); else messageState->setText(tr("切分失败,可能是不支持的类型或超出范围的切块大小")); }); } void LabCD::mergeBigImage() { QString dirPath = QFileDialog::getExistingDirectory( this, QObject::tr("打开图像文件夹"), QString(), QFileDialog::ShowDirsOnly ); if (dirPath.isEmpty()) return; QtConcurrent::run([=]() { if (ImagePress::mergeTiff(dirPath)) messageState->setText( tr("合并完成,保存至:") + dirPath + "/merge.tif"); else messageState->setText(tr("合并失败")); }); } void LabCD::clearEmptyMask() { QStringList t1List; QStringList t2List; QStringList GTList; if (FileWorker::openImageDir(&t1List, &t2List, &GTList, this)) { QtConcurrent::run([=]() { LabCD::_clearEmptyMask(t1List, t2List, GTList); }); messageState->setText(tr("清理完成")); } } void LabCD::_clearEmptyMask( QStringList t1List, QStringList t2List, QStringList GTList) { std::sort(t1List.begin(), t1List.end()); std::sort(t2List.begin(), t2List.end()); std::sort(GTList.begin(), GTList.end()); QFileInfo fInfo; QString pathName; for (int i = 0; i < GTList.size(); ++i) { if (ImagePress::maskIsEmpty(GTList.at(i))) { // 清理图像 QFile::remove(t1List.at(i)); QFile::remove(t2List.at(i)); // 清理标签 fInfo = QFileInfo(GTList.at(i)); pathName = fInfo.path() + "/" + fInfo.baseName(); QFile::remove(GTList.at(i)); QFile::remove(pathName + ".json"); QFile::remove(pathName + "_pseudo.png"); } } } void LabCD::convertMask2Json() { QString dirPath = QFileDialog::getExistingDirectory( this, QObject::tr("打开标签文件夹"), QString(), QFileDialog::ShowDirsOnly ); if (dirPath.isEmpty()) return; QtConcurrent::run([=]() { LabCD::_convertMask2Json(dirPath); }); messageState->setText(tr("转换完成")); } void LabCD::_convertMask2Json(QString dirPath) { QDir maskDir(dirPath); QStringList nameFilters; nameFilters << "*.jpg" << "*.jpeg" << "*.png" << "*.tif" << "*.tiff"; QStringList maskList = (maskDir).entryList( nameFilters, QDir::Readable | QDir::Files, QDir::Name); QString maskPath; for (int i = 0; i < maskList.size(); ++i) { maskPath = dirPath + "/" + maskList.at(i); ImagePress::savePolygonFromMask(maskPath); } } void LabCD::save() { if (drawCanvas->imageWidth != 0 && drawCanvas->imageHeight != 0) { QString saveImgPath = savePath + "/GT/" + fileName; int labNum = labTableWidget->getLen(); drawCanvas->finished(); ImagePress::saveResultFromPolygon( saveImgPath, labNum, drawCanvas->imageHeight, drawCanvas->imageWidth, drawCanvas->t1Canva->aScene->polygonItems, drawCanvas->projs, drawCanvas->trans ); fListWidget->finishedCurrentItem(); messageState->setText(tr("保存图像:") + saveImgPath); fListWidget->progressUpAdd(); } } void LabCD::setCrossPenColor() { QColor nowCrossColor = drawCanvas->getCrossPenColor(); QColor color = QColorDialog::getColor( nowCrossColor, this, tr("设置十字丝颜色"), QColorDialog::ShowAlphaChannel ); setting->setValue("cross_color", color); drawCanvas->setCrossPenColor(color); } void LabCD::updatePolysColor() { for (int i = 0; i < drawCanvas->t1Canva->aScene->polygonItems.count(); ++i) { int idx = drawCanvas->t1Canva->aScene->polygonItems[i]->getLabelIndex(); QColor polyColor = drawCanvas->t1Canva->aScene->polygonItems[i]->getColor(); QColor labColor = labTableWidget->getColorByIndex(idx); if (polyColor.rgb() != labColor.rgb()) { drawCanvas->t1Canva->aScene->polygonItems[i]->setColor( labColor, labColor); drawCanvas->t2Canva->aScene->polygonItems[i]->setColor( labColor, labColor); } } } void LabCD::closeEvent(QCloseEvent* ev) { // 保存标签 if (savePath != "") { QString jsonPath = savePath + "/label.json"; labTableWidget->exportLabelToFile(jsonPath); } // 保存界面 setting->setValue("layout_status", QByteArray(saveState())); QMainWindow::closeEvent(ev); }

由 张法国 与 OPENAI01 创建