Bläddra i källkod

上传文件至 'src'

wang 2 veckor sedan
förälder
incheckning
8c8e2fd498
5 ändrade filer med 664 tillägg och 0 borttagningar
  1. 103 0
      src/process.cpp
  2. 97 0
      src/process.h
  3. 149 0
      src/processflowexample.cpp
  4. 43 0
      src/processflowexample.h
  5. 272 0
      src/processflowfactory.cpp

+ 103 - 0
src/process.cpp

@@ -0,0 +1,103 @@
+#include "process.h"
+#include <QDebug>
+#include <QTime>
+
+bool Process::initialize()
+{
+    qDebug() << "Initializing Process...";
+
+    // Check if all components are set
+    if (!hikvisionCamera || !imageAcquisition || !algorithmProcess || !fileSystem) {
+        qDebug() << "Not all components are set";
+        return false;
+    }
+
+    // Initialize components if needed
+    // Camera initialization is usually done in connectCamera()
+    // ImageAcquisition initialization is usually done in constructor
+    // AlgorithmProcess initialization is usually done in constructor
+    // FileSystem initialization is usually done in constructor
+
+    qDebug() << "Process initialized successfully";
+    return true;
+}
+
+bool Process::execute()
+{
+    qDebug() << "Executing Process...";
+
+    // Check if components are initialized
+    if (!hikvisionCamera || !imageAcquisition || !algorithmProcess || !fileSystem) {
+        qDebug() << "Process not initialized";
+        return false;
+    }
+
+    // 1. Connect camera
+    if (!hikvisionCamera->connectCamera()) {
+        qDebug() << "Failed to connect camera";
+        return false;
+    }
+
+    // 2. Start capture
+    if (!hikvisionCamera->startCapture()) {
+        qDebug() << "Failed to start capture";
+        hikvisionCamera->disconnectCamera();
+        return false;
+    }
+
+    // 3. Get image
+    QImage qImage = hikvisionCamera->getImage();
+    if (qImage.isNull()) {
+        qDebug() << "Failed to get image from camera";
+        hikvisionCamera->stopCapture();
+        hikvisionCamera->disconnectCamera();
+        return false;
+    }
+
+    // 4. Stop capture
+    hikvisionCamera->stopCapture();
+    hikvisionCamera->disconnectCamera();
+
+    // 5. Convert QImage to OpenCV Mat
+    cv::Mat image;
+    if (qImage.format() == QImage::Format_RGB32) {
+        image = cv::Mat(qImage.height(), qImage.width(), CV_8UC4, (uchar*)qImage.bits(), qImage.bytesPerLine());
+        cv::cvtColor(image, image, cv::COLOR_RGBA2BGR);
+    } else {
+        qDebug() << "Unsupported image format";
+        return false;
+    }
+
+    // 6. Image acquisition processing (distortion correction, etc.)
+    cv::Mat processedImage = imageAcquisition->undistortImage(image, 0);
+    if (processedImage.empty()) {
+        qDebug() << "Failed to process image";
+        return false;
+    }
+
+    // 7. Execute algorithm processing
+    cv::Mat resultImage = algorithmProcess->execute(processedImage);
+    if (resultImage.empty()) {
+        qDebug() << "Failed to execute algorithm process";
+        return false;
+    }
+
+    // 8. Save result
+    QString resultPath = "result.jpg";
+    if (!fileSystem->saveImage(resultPath, resultImage)) {
+        qDebug() << "Failed to save result image";
+        return false;
+    }
+
+    qDebug() << "Process executed successfully. Result saved to:" << resultPath;
+    
+    // Store runtime parameters
+    runtimeParams["resultPath"] = resultPath;
+    runtimeParams["imageWidth"] = image.cols;
+    runtimeParams["imageHeight"] = image.rows;
+    runtimeParams["processedImageWidth"] = processedImage.cols;
+    runtimeParams["processedImageHeight"] = processedImage.rows;
+    runtimeParams["executionTime"] = QTime::currentTime().toString();
+    
+    return true;
+}

+ 97 - 0
src/process.h

@@ -0,0 +1,97 @@
+#ifndef PROCESS_H
+#define PROCESS_H
+
+#include "hikvisioncamera.h"
+#include "imageacquisition.h"
+#include "algorithmprocess.h"
+#include "filesystem.h"
+#include <memory>
+#include <QString>
+#include <QJsonObject>
+
+class Process
+{
+public:
+    class Builder {
+    public:
+        Builder() = default;
+        
+        Builder& setCamera(std::shared_ptr<HikvisionCamera> camera) {
+            this->hikvisionCamera = camera;
+            return *this;
+        }
+        
+        Builder& setImageAcquisition(std::shared_ptr<ImageAcquisition> imageAcquisition) {
+            this->imageAcquisition = imageAcquisition;
+            return *this;
+        }
+        
+        Builder& setAlgorithmProcess(std::shared_ptr<AlgorithmProcess> algorithmProcess) {
+            this->algorithmProcess = algorithmProcess;
+            return *this;
+        }
+        
+        Builder& setFileSystem(std::shared_ptr<FileSystem> fileSystem) {
+            this->fileSystem = fileSystem;
+            return *this;
+        }
+        
+        Process build() {
+            return Process(*this);
+        }
+        
+    private:
+        std::shared_ptr<HikvisionCamera> hikvisionCamera;
+        std::shared_ptr<ImageAcquisition> imageAcquisition;
+        std::shared_ptr<AlgorithmProcess> algorithmProcess;
+        std::shared_ptr<FileSystem> fileSystem;
+        
+        friend class Process;
+    };
+    
+    // Constructor
+    Process() = default;
+    
+    // Initialize process
+    bool initialize();
+    
+    // Execute process
+    bool execute();
+    
+    // Get components
+    std::shared_ptr<HikvisionCamera> getCamera() const {
+        return hikvisionCamera;
+    }
+    
+    std::shared_ptr<ImageAcquisition> getImageAcquisition() const {
+        return imageAcquisition;
+    }
+    
+    std::shared_ptr<AlgorithmProcess> getAlgorithmProcess() const {
+        return algorithmProcess;
+    }
+    
+    std::shared_ptr<FileSystem> getFileSystem() const {
+        return fileSystem;
+    }
+    
+private:
+    // Components
+    std::shared_ptr<HikvisionCamera> hikvisionCamera;
+    std::shared_ptr<ImageAcquisition> imageAcquisition;
+    std::shared_ptr<AlgorithmProcess> algorithmProcess;
+    std::shared_ptr<FileSystem> fileSystem;
+    
+    // Runtime parameters
+    QJsonObject runtimeParams;
+    
+    // Constructor from Builder
+    Process(const Builder& builder) :
+        hikvisionCamera(builder.hikvisionCamera),
+        imageAcquisition(builder.imageAcquisition),
+        algorithmProcess(builder.algorithmProcess),
+        fileSystem(builder.fileSystem)
+    {}
+};
+
+#endif // PROCESS_H

+ 149 - 0
src/processflowexample.cpp

@@ -0,0 +1,149 @@
+#include "processflowexample.h"
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QFileDialog>
+#include <QMessageBox>
+
+ProcessFlowExample::ProcessFlowExample(QObject *parent)
+    : QObject(parent)
+    , flowFactory(ProcessFlowFactory::getInstance())
+{
+}
+
+ProcessFlowExample::~ProcessFlowExample()
+{
+}
+
+void ProcessFlowExample::createSimpleImageProcessingFlow()
+{
+    // 清空现有流程
+    flowFactory->clearSteps();
+    flowFactory->setFlowName("简单图像处理流程");
+
+    // 步骤1: 图像提取
+    ImageExtractStep* extractStep = flowFactory->createImageExtractStep("加载图像");
+    extractStep->setImageSource(ImageExtractStep::FromFile);
+    // 图像路径将在执行时设置
+    flowFactory->addStep(extractStep);
+
+    // 步骤2: 灰度转换算法
+    AlgorithmRunStep* grayStep = flowFactory->createAlgorithmRunStep("灰度转换");
+    grayStep->setAlgorithmType("Grayscale");
+    flowFactory->addStep(grayStep);
+
+    // 步骤3: 高斯模糊算法
+    AlgorithmRunStep* blurStep = flowFactory->createAlgorithmRunStep("高斯模糊");
+    blurStep->setAlgorithmType("GaussianBlur");
+    QJsonObject blurParams;
+    blurParams["KernelSize"] = 5;
+    blurParams["SigmaX"] = 1.5;
+    blurStep->setAlgorithmParams(blurParams);
+    flowFactory->addStep(blurStep);
+}
+
+void ProcessFlowExample::createMultiAlgorithmFlow()
+{
+    // 清空现有流程
+    flowFactory->clearSteps();
+    flowFactory->setFlowName("多算法组合流程");
+
+    // 步骤1: 图像提取
+    ImageExtractStep* extractStep = flowFactory->createImageExtractStep("加载图像");
+    extractStep->setImageSource(ImageExtractStep::FromFile);
+    flowFactory->addStep(extractStep);
+
+    // 步骤2: 灰度转换
+    AlgorithmRunStep* grayStep = flowFactory->createAlgorithmRunStep("灰度转换");
+    grayStep->setAlgorithmType("Grayscale");
+    flowFactory->addStep(grayStep);
+
+    // 步骤3: Canny边缘检测
+    AlgorithmRunStep* cannyStep = flowFactory->createAlgorithmRunStep("Canny边缘检测");
+    cannyStep->setAlgorithmType("CannyEdge");
+    QJsonObject cannyParams;
+    cannyParams["Threshold1"] = 50;
+    cannyParams["Threshold2"] = 150;
+    cannyParams["ApertureSize"] = 3;
+    cannyStep->setAlgorithmParams(cannyParams);
+    flowFactory->addStep(cannyStep);
+
+    // 步骤4: 膨胀操作
+    AlgorithmRunStep* dilateStep = flowFactory->createAlgorithmRunStep("膨胀");
+    dilateStep->setAlgorithmType("Dilate");
+    QJsonObject dilateParams;
+    dilateParams["KernerSize"] = 3;
+    dilateParams["Iterations"] = 1;
+    dilateStep->setAlgorithmParams(dilateParams);
+    flowFactory->addStep(dilateStep);
+}
+
+bool ProcessFlowExample::loadFlowFromFile(const QString& filePath)
+{
+    bool result = flowFactory->loadFromFile(filePath);
+    if (!result) {
+        lastError = flowFactory->getLastError();
+    }
+    return result;
+}
+
+bool ProcessFlowExample::saveFlowToFile(const QString& filePath)
+{
+    bool result = flowFactory->saveToFile(filePath);
+    if (!result) {
+        lastError = flowFactory->getLastError();
+    }
+    return result;
+}
+
+QImage ProcessFlowExample::executeFlow(const QString& imagePath)
+{
+    // 获取第一个步骤(应该是图像提取步骤)
+    if (flowFactory->getStepCount() == 0) {
+        lastError = "流程中没有步骤";
+        return QImage();
+    }
+
+    // 设置图像路径到第一个图像提取步骤
+    ProcessStep* firstStep = flowFactory->getStep(0);
+    if (firstStep->getType() == ProcessStep::ImageExtract) {
+        ImageExtractStep* extractStep = static_cast<ImageExtractStep*>(firstStep);
+        extractStep->setImagePath(imagePath);
+    }
+
+    // 执行流程
+    cv::Mat result = flowFactory->executeFlow();
+
+    if (result.empty()) {
+        lastError = flowFactory->getLastError();
+        return QImage();
+    }
+
+    // 转换为QImage
+    return cvMatToQImage(result);
+}
+
+QString ProcessFlowExample::getLastError() const
+{
+    return lastError;
+}
+
+QImage ProcessFlowExample::cvMatToQImage(const cv::Mat& mat)
+{
+    if (mat.empty()) {
+        return QImage();
+    }
+
+    // 根据通道数选择格式
+    if (mat.channels() == 1) {
+        // 灰度图像
+        return QImage((uchar*)mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_Grayscale8);
+    } else if (mat.channels() == 3) {
+        // BGR彩色图像
+        return QImage((uchar*)mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_BGR888);
+    } else if (mat.channels() == 4) {
+        // BGRA图像
+        return QImage((uchar*)mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_ARGB32);
+    }
+
+    return QImage();
+}

+ 43 - 0
src/processflowexample.h

@@ -0,0 +1,43 @@
+#ifndef PROCESSFLOWEXAMPLE_H
+#define PROCESSFLOWEXAMPLE_H
+
+#include <QObject>
+#include <QImage>
+#include "processflowfactory.h"
+
+// 流程工厂使用示例类
+class ProcessFlowExample : public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit ProcessFlowExample(QObject *parent = nullptr);
+    ~ProcessFlowExample();
+
+    // 示例1: 创建简单的图像处理流程
+    void createSimpleImageProcessingFlow();
+
+    // 示例2: 创建多算法组合流程
+    void createMultiAlgorithmFlow();
+
+    // 示例3: 从文件加载流程配置
+    bool loadFlowFromFile(const QString& filePath);
+
+    // 示例4: 保存流程配置到文件
+    bool saveFlowToFile(const QString& filePath);
+
+    // 执行流程
+    QImage executeFlow(const QString& imagePath);
+
+    // 获取最后错误
+    QString getLastError() const;
+
+private:
+    ProcessFlowFactory* flowFactory;
+    QString lastError;
+
+    // OpenCV Mat 转 QImage
+    QImage cvMatToQImage(const cv::Mat& mat);
+};
+
+#endif // PROCESSFLOWEXAMPLE_H

+ 272 - 0
src/processflowfactory.cpp

@@ -0,0 +1,272 @@
+#include "processflowfactory.h"
+#include <QFile>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+
+// 初始化静态成员
+ProcessFlowFactory* ProcessFlowFactory::instance = nullptr;
+
+ProcessFlowFactory* ProcessFlowFactory::getInstance()
+{
+    if (!instance) {
+        instance = new ProcessFlowFactory();
+    }
+    return instance;
+}
+
+ProcessFlowFactory::ProcessFlowFactory()
+    : flowName("默认流程")
+{
+}
+
+ProcessFlowFactory::~ProcessFlowFactory()
+{
+    cleanup();
+}
+
+void ProcessFlowFactory::cleanup()
+{
+    for (ProcessStep* step : steps) {
+        delete step;
+    }
+    steps.clear();
+}
+
+ImageExtractStep* ProcessFlowFactory::createImageExtractStep(const QString& name)
+{
+    ImageExtractStep* step = new ImageExtractStep(name);
+    return step;
+}
+
+AlgorithmRunStep* ProcessFlowFactory::createAlgorithmRunStep(const QString& name)
+{
+    AlgorithmRunStep* step = new AlgorithmRunStep(name);
+    return step;
+}
+
+void ProcessFlowFactory::addStep(ProcessStep* step)
+{
+    if (step) {
+        steps.append(step);
+    }
+}
+
+void ProcessFlowFactory::insertStep(int index, ProcessStep* step)
+{
+    if (step && index >= 0 && index <= steps.size()) {
+        steps.insert(index, step);
+    }
+}
+
+void ProcessFlowFactory::removeStep(int index)
+{
+    if (index >= 0 && index < steps.size()) {
+        delete steps[index];
+        steps.removeAt(index);
+    }
+}
+
+ProcessStep* ProcessFlowFactory::getStep(int index) const
+{
+    if (index >= 0 && index < steps.size()) {
+        return steps[index];
+    }
+    return nullptr;
+}
+
+void ProcessFlowFactory::clearSteps()
+{
+    cleanup();
+}
+
+cv::Mat ProcessFlowFactory::executeFlow(const cv::Mat& inputImage)
+{
+    lastError.clear();
+
+    if (steps.isEmpty()) {
+        setError("流程中没有步骤");
+        return cv::Mat();
+    }
+
+    cv::Mat currentImage = inputImage;
+
+    // 依次执行每个步骤
+    for (int i = 0; i < steps.size(); ++i) {
+        ProcessStep* step = steps[i];
+
+        // 跳过禁用的步骤
+        if (!step->isEnabled()) {
+            continue;
+        }
+
+        // 执行步骤
+        currentImage = step->execute(currentImage);
+
+        // 检查执行结果
+        if (currentImage.empty()) {
+            setError(QString("步骤 %1 (%2) 执行失败: %3")
+                     .arg(i + 1)
+                     .arg(step->getName())
+                     .arg(step->getLastError()));
+            return cv::Mat();
+        }
+    }
+
+    return currentImage;
+}
+
+cv::Mat ProcessFlowFactory::executeStep(int index, const cv::Mat& inputImage)
+{
+    lastError.clear();
+
+    if (index < 0 || index >= steps.size()) {
+        setError("步骤索引超出范围");
+        return cv::Mat();
+    }
+
+    ProcessStep* step = steps[index];
+    if (!step->isEnabled()) {
+        setError("步骤已被禁用");
+        return cv::Mat();
+    }
+
+    cv::Mat result = step->execute(inputImage);
+
+    if (result.empty()) {
+        setError(QString("步骤执行失败: %1").arg(step->getLastError()));
+    }
+
+    return result;
+}
+
+bool ProcessFlowFactory::loadFromJson(const QJsonObject& json)
+{
+    clearSteps();
+
+    // 加载流程名称
+    flowName = json.value("flowName").toString("默认流程");
+
+    // 加载步骤
+    QJsonArray stepsArray = json.value("steps").toArray();
+    for (const QJsonValue& stepValue : stepsArray) {
+        QJsonObject stepObj = stepValue.toObject();
+        QString stepType = stepObj.value("type").toString();
+        QString stepName = stepObj.value("name").toString();
+
+        ProcessStep* step = nullptr;
+
+        if (stepType == "ImageExtract") {
+            ImageExtractStep* extractStep = createImageExtractStep(stepName);
+
+            // 加载图像提取参数
+            QJsonObject params = stepObj.value("params").toObject();
+            int source = params.value("source").toInt(0);
+            QString imagePath = params.value("imagePath").toString();
+            int cameraIndex = params.value("cameraIndex").toInt(0);
+
+            extractStep->setImageSource(static_cast<ImageExtractStep::ImageSource>(source));
+            extractStep->setImagePath(imagePath);
+            extractStep->setCameraIndex(cameraIndex);
+
+            step = extractStep;
+        } else if (stepType == "AlgorithmRun") {
+            AlgorithmRunStep* algoStep = createAlgorithmRunStep(stepName);
+
+            // 加载算法参数
+            QJsonObject params = stepObj.value("params").toObject();
+            QString algoType = params.value("algorithmType").toString();
+            QJsonObject algoParams = params.value("algorithmParams").toObject();
+
+            algoStep->setAlgorithmType(algoType);
+            algoStep->setAlgorithmParams(algoParams);
+
+            step = algoStep;
+        }
+
+        if (step) {
+            // 加载启用状态
+            bool enabled = stepObj.value("enabled").toBool(true);
+            step->setEnabled(enabled);
+
+            addStep(step);
+        }
+    }
+
+    return true;
+}
+
+QJsonObject ProcessFlowFactory::saveToJson() const
+{
+    QJsonObject json;
+    json["flowName"] = flowName;
+
+    QJsonArray stepsArray;
+    for (ProcessStep* step : steps) {
+        QJsonObject stepObj;
+        stepObj["name"] = step->getName();
+        stepObj["enabled"] = step->isEnabled();
+
+        if (step->getType() == ProcessStep::ImageExtract) {
+            stepObj["type"] = "ImageExtract";
+
+            ImageExtractStep* extractStep = static_cast<ImageExtractStep*>(step);
+            QJsonObject params;
+            params["source"] = static_cast<int>(extractStep->getImageSource());
+            params["imagePath"] = extractStep->getImagePath();
+            params["cameraIndex"] = extractStep->getCameraIndex();
+
+            stepObj["params"] = params;
+        } else if (step->getType() == ProcessStep::AlgorithmRun) {
+            stepObj["type"] = "AlgorithmRun";
+
+            AlgorithmRunStep* algoStep = static_cast<AlgorithmRunStep*>(step);
+            QJsonObject params;
+            params["algorithmType"] = algoStep->getAlgorithmType();
+            params["algorithmParams"] = algoStep->getAlgorithmParams();
+
+            stepObj["params"] = params;
+        }
+
+        stepsArray.append(stepObj);
+    }
+
+    json["steps"] = stepsArray;
+    return json;
+}
+
+bool ProcessFlowFactory::loadFromFile(const QString& filePath)
+{
+    QFile file(filePath);
+    if (!file.open(QIODevice::ReadOnly)) {
+        setError("无法打开文件: " + filePath);
+        return false;
+    }
+
+    QByteArray data = file.readAll();
+    file.close();
+
+    QJsonDocument doc = QJsonDocument::fromJson(data);
+    if (doc.isNull()) {
+        setError("无效的JSON文件");
+        return false;
+    }
+
+    return loadFromJson(doc.object());
+}
+
+bool ProcessFlowFactory::saveToFile(const QString& filePath) const
+{
+    QFile file(filePath);
+    if (!file.open(QIODevice::WriteOnly)) {
+        setError("无法创建文件: " + filePath);
+        return false;
+    }
+
+    QJsonObject json = saveToJson();
+    QJsonDocument doc(json);
+    file.write(doc.toJson(QJsonDocument::Indented));
+    file.close();
+
+    return true;
+}