| 825 | } |
| 826 | |
| 827 | bool Utils::saveDebugImg(const cv::Mat& scrShot, const cv::Rect& templateRoi, const int& clickX, const int& clickY, const QString& hint){ |
| 828 | try { |
| 829 | // 检查输入图像是否为空 |
| 830 | if (scrShot.empty()) { |
| 831 | qWarning() << "Input image is empty!"; |
| 832 | return false; |
| 833 | } |
| 834 | |
| 835 | // 转换图像为 8UC3 格式 |
| 836 | cv::Mat img; |
| 837 | if (scrShot.channels() == 1) { |
| 838 | cv::cvtColor(scrShot, img, cv::COLOR_GRAY2BGR); |
| 839 | } else if (scrShot.channels() == 3) { |
| 840 | img = scrShot.clone(); |
| 841 | } else { |
| 842 | qWarning() << "Unsupported image format!"; |
| 843 | return false; |
| 844 | } |
| 845 | |
| 846 | // 绘制蓝色矩形,线条宽度为 2 |
| 847 | cv::rectangle(img, templateRoi, cv::Scalar(255, 0, 0), 2); |
| 848 | |
| 849 | // 绘制红色实心圆,半径为 2 |
| 850 | cv::circle(img, cv::Point(clickX, clickY), 2, cv::Scalar(0, 0, 255), cv::FILLED); |
| 851 | |
| 852 | // 构造保存路径 |
| 853 | QString outputPath = IMAGE_DIR_DEBUG() + "/" + QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss_") + hint + ".bmp"; |
| 854 | |
| 855 | // 保存调试图像 |
| 856 | if (!cv::imwrite(outputPath.toLocal8Bit().toStdString(), img)) { |
| 857 | qWarning() << "Failed to save debug image! " + outputPath; |
| 858 | return false; |
| 859 | } |
| 860 | |
| 861 | return true; |
| 862 | } catch (const cv::Exception& e) { |
| 863 | qWarning() << "OpenCV exception:" << e.what(); |
| 864 | return false; |
| 865 | } catch (const std::exception& e) { |
| 866 | qWarning() << "Standard exception:" << e.what(); |
| 867 | return false; |
| 868 | } catch (...) { |
| 869 | qWarning() << "Unknown exception occurred!"; |
| 870 | return false; |
| 871 | } |
| 872 | } |
| 873 | |
| 874 | bool Utils::myCreateProcess(const std::wstring &exePath, const std::wstring &workingDir) |
| 875 | { |