添加项目文件。
This commit is contained in:
61
NodeEditorPro/examples/calculator/AdditionModel.hpp
Normal file
61
NodeEditorPro/examples/calculator/AdditionModel.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "MathOperationDataModel.hpp"
|
||||
#include "DecimalData.hpp"
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class AdditionModel : public MathOperationDataModel
|
||||
{
|
||||
public:
|
||||
|
||||
virtual
|
||||
~AdditionModel() {}
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("加法");
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("加法");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
compute() override
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
|
||||
auto n1 = _number1.lock();
|
||||
auto n2 = _number2.lock();
|
||||
|
||||
if (n1 && n2)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
_result = std::make_shared<DecimalData>(n1->number() +
|
||||
n2->number());
|
||||
}
|
||||
else
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("未连接或运行失败!");
|
||||
_result.reset();
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
}
|
||||
};
|
5
NodeEditorPro/examples/calculator/CMakeLists.txt
Normal file
5
NodeEditorPro/examples/calculator/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
file(GLOB_RECURSE CPPS ./*.cpp )
|
||||
|
||||
add_executable(calculator ${CPPS})
|
||||
|
||||
target_link_libraries(calculator nodes)
|
46
NodeEditorPro/examples/calculator/Converters.cpp
Normal file
46
NodeEditorPro/examples/calculator/Converters.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "Converters.hpp"
|
||||
|
||||
#include <QtGui/QDoubleValidator>
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
#include "IntegerData.hpp"
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
DecimalToIntegerConverter::
|
||||
operator()(std::shared_ptr<NodeData> data)
|
||||
{
|
||||
auto numberData =
|
||||
std::dynamic_pointer_cast<DecimalData>(data);
|
||||
|
||||
if (numberData)
|
||||
{
|
||||
_integer = std::make_shared<IntegerData>(numberData->number());
|
||||
}
|
||||
else
|
||||
{
|
||||
_integer.reset();
|
||||
}
|
||||
|
||||
return _integer;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
IntegerToDecimalConverter::
|
||||
operator()(std::shared_ptr<NodeData> data)
|
||||
{
|
||||
auto numberData =
|
||||
std::dynamic_pointer_cast<IntegerData>(data);
|
||||
|
||||
if (numberData)
|
||||
{
|
||||
_decimal = std::make_shared<DecimalData>(numberData->number());
|
||||
}
|
||||
else
|
||||
{
|
||||
_decimal.reset();
|
||||
}
|
||||
|
||||
return _decimal;
|
||||
}
|
41
NodeEditorPro/examples/calculator/Converters.hpp
Normal file
41
NodeEditorPro/examples/calculator/Converters.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
#include "IntegerData.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
|
||||
class DecimalData;
|
||||
class IntegerData;
|
||||
|
||||
|
||||
class DecimalToIntegerConverter
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
operator()(std::shared_ptr<NodeData> data);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<NodeData> _integer;
|
||||
};
|
||||
|
||||
|
||||
class IntegerToDecimalConverter
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
operator()(std::shared_ptr<NodeData> data);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<NodeData> _decimal;
|
||||
};
|
41
NodeEditorPro/examples/calculator/DecimalData.hpp
Normal file
41
NodeEditorPro/examples/calculator/DecimalData.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeData;
|
||||
|
||||
/// The class can potentially incapsulate any user data which
|
||||
/// need to be transferred within the Node Editor graph
|
||||
class DecimalData : public NodeData
|
||||
{
|
||||
public:
|
||||
|
||||
DecimalData()
|
||||
: _number(0.0)
|
||||
{}
|
||||
|
||||
DecimalData(double const number)
|
||||
: _number(number)
|
||||
{}
|
||||
|
||||
NodeDataType type() const override
|
||||
{
|
||||
return NodeDataType{ "decimal",
|
||||
QStringLiteral("浮点数") };
|
||||
}
|
||||
|
||||
double number() const
|
||||
{
|
||||
return _number;
|
||||
}
|
||||
|
||||
QString numberAsText() const
|
||||
{
|
||||
return QString::number(_number, 'f');
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
double _number;
|
||||
};
|
95
NodeEditorPro/examples/calculator/DivisionModel.hpp
Normal file
95
NodeEditorPro/examples/calculator/DivisionModel.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "MathOperationDataModel.hpp"
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class DivisionModel : public MathOperationDataModel
|
||||
{
|
||||
public:
|
||||
|
||||
virtual
|
||||
~DivisionModel() {}
|
||||
|
||||
public:
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("除法");
|
||||
}
|
||||
|
||||
bool
|
||||
portCaptionVisible(PortType portType, PortIndex portIndex) const override
|
||||
{
|
||||
Q_UNUSED(portType); Q_UNUSED(portIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
QString
|
||||
portCaption(PortType portType, PortIndex portIndex) const override
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
if (portIndex == 0)
|
||||
return QStringLiteral("除数");
|
||||
else if (portIndex == 1)
|
||||
return QStringLiteral("被除数");
|
||||
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
return QStringLiteral("结果");
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("除法");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
compute() override
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
|
||||
auto n1 = _number1.lock();
|
||||
auto n2 = _number2.lock();
|
||||
|
||||
if (n2 && (n2->number() == 0.0))
|
||||
{
|
||||
modelValidationState = NodeValidationState::Error;
|
||||
modelValidationError = QStringLiteral("被除数无法为0!");
|
||||
_result.reset();
|
||||
}
|
||||
else if (n1 && n2)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
_result = std::make_shared<DecimalData>(n1->number() /
|
||||
n2->number());
|
||||
}
|
||||
else
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("未连接或运行失败!");
|
||||
_result.reset();
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
}
|
||||
};
|
41
NodeEditorPro/examples/calculator/IntegerData.hpp
Normal file
41
NodeEditorPro/examples/calculator/IntegerData.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeData;
|
||||
|
||||
/// The class can potentially incapsulate any user data which
|
||||
/// need to be transferred within the Node Editor graph
|
||||
class IntegerData : public NodeData
|
||||
{
|
||||
public:
|
||||
|
||||
IntegerData()
|
||||
: _number(0.0)
|
||||
{}
|
||||
|
||||
IntegerData(int const number)
|
||||
: _number(number)
|
||||
{}
|
||||
|
||||
NodeDataType type() const override
|
||||
{
|
||||
return NodeDataType{ "integer",
|
||||
QStringLiteral("整数") };
|
||||
}
|
||||
|
||||
int number() const
|
||||
{
|
||||
return _number;
|
||||
}
|
||||
|
||||
QString numberAsText() const
|
||||
{
|
||||
return QString::number(_number);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int _number;
|
||||
};
|
10
NodeEditorPro/examples/calculator/MathNodes.hpp
Normal file
10
NodeEditorPro/examples/calculator/MathNodes.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
//math nodes
|
||||
#include "calculator/AdditionModel.hpp"
|
||||
#include "calculator/DivisionModel.hpp"
|
||||
#include "calculator/MultiplicationModel.hpp"
|
||||
#include "calculator/SubtractionModel.hpp"
|
||||
#include "calculator/NumberSourceDataModel.hpp"
|
||||
#include "calculator/NumberDisplayDataModel.hpp"
|
||||
|
67
NodeEditorPro/examples/calculator/MathOperationDataModel.cpp
Normal file
67
NodeEditorPro/examples/calculator/MathOperationDataModel.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include "MathOperationDataModel.hpp"
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
|
||||
unsigned int
|
||||
MathOperationDataModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result;
|
||||
|
||||
if (portType == PortType::In)
|
||||
result = 2;
|
||||
else
|
||||
result = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
NodeDataType
|
||||
MathOperationDataModel::
|
||||
dataType(PortType, PortIndex) const
|
||||
{
|
||||
return DecimalData().type();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
MathOperationDataModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::static_pointer_cast<NodeData>(_result);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MathOperationDataModel::
|
||||
setInData(std::shared_ptr<NodeData> data, PortIndex portIndex)
|
||||
{
|
||||
auto numberData =
|
||||
std::dynamic_pointer_cast<DecimalData>(data);
|
||||
|
||||
if (portIndex == 0)
|
||||
{
|
||||
_number1 = numberData;
|
||||
}
|
||||
else
|
||||
{
|
||||
_number2 = numberData;
|
||||
}
|
||||
compute();
|
||||
}
|
||||
|
||||
NodeValidationState
|
||||
MathOperationDataModel::
|
||||
validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
MathOperationDataModel::
|
||||
validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
69
NodeEditorPro/examples/calculator/MathOperationDataModel.hpp
Normal file
69
NodeEditorPro/examples/calculator/MathOperationDataModel.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class DecimalData;
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class MathOperationDataModel : public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
virtual
|
||||
~MathOperationDataModel() {}
|
||||
|
||||
public:
|
||||
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType,
|
||||
PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData> data, PortIndex portIndex) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return nullptr; }
|
||||
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void
|
||||
compute() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
std::weak_ptr<DecimalData> _number1;
|
||||
std::weak_ptr<DecimalData> _number2;
|
||||
|
||||
std::shared_ptr<DecimalData> _result;
|
||||
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("未连接或运行失败!");
|
||||
};
|
118
NodeEditorPro/examples/calculator/ModuloModel.cpp
Normal file
118
NodeEditorPro/examples/calculator/ModuloModel.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include "ModuloModel.hpp"
|
||||
|
||||
#include <QtGui/QDoubleValidator>
|
||||
|
||||
#include "IntegerData.hpp"
|
||||
|
||||
QJsonObject
|
||||
ModuloModel::
|
||||
save() const
|
||||
{
|
||||
QJsonObject modelJson;
|
||||
|
||||
modelJson["name"] = name();
|
||||
|
||||
return modelJson;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
ModuloModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 2;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
NodeDataType
|
||||
ModuloModel::
|
||||
dataType(PortType, PortIndex) const
|
||||
{
|
||||
return IntegerData().type();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
ModuloModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModuloModel::
|
||||
setInData(std::shared_ptr<NodeData> data, PortIndex portIndex)
|
||||
{
|
||||
auto numberData =
|
||||
std::dynamic_pointer_cast<IntegerData>(data);
|
||||
|
||||
if (portIndex == 0)
|
||||
{
|
||||
_number1 = numberData;
|
||||
}
|
||||
else
|
||||
{
|
||||
_number2 = numberData;
|
||||
}
|
||||
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
|
||||
auto n1 = _number1.lock();
|
||||
auto n2 = _number2.lock();
|
||||
|
||||
if (n2 && (n2->number() == 0.0))
|
||||
{
|
||||
modelValidationState = NodeValidationState::Error;
|
||||
modelValidationError = QStringLiteral("Division by zero error");
|
||||
_result.reset();
|
||||
}
|
||||
else if (n1 && n2)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
_result = std::make_shared<IntegerData>(n1->number() %
|
||||
n2->number());
|
||||
}
|
||||
else
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("Missing or incorrect inputs");
|
||||
_result.reset();
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NodeValidationState
|
||||
ModuloModel::
|
||||
validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
ModuloModel::
|
||||
validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
115
NodeEditorPro/examples/calculator/ModuloModel.hpp
Normal file
115
NodeEditorPro/examples/calculator/ModuloModel.hpp
Normal file
@ -0,0 +1,115 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
class IntegerData;
|
||||
|
||||
class ModuloModel
|
||||
: public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ModuloModel() = default;
|
||||
|
||||
virtual
|
||||
~ModuloModel() = default;
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("求模");
|
||||
}
|
||||
|
||||
bool
|
||||
captionVisible() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
portCaptionVisible(PortType, PortIndex) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QString
|
||||
portCaption(PortType portType, PortIndex portIndex) const override
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
if (portIndex == 0)
|
||||
return QStringLiteral("求模数");
|
||||
else if (portIndex == 1)
|
||||
return QStringLiteral("被模数");
|
||||
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
return QStringLiteral("结果");
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("求模");
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
QJsonObject
|
||||
save() const override;
|
||||
|
||||
public:
|
||||
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return nullptr; }
|
||||
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
private:
|
||||
|
||||
std::weak_ptr<IntegerData> _number1;
|
||||
std::weak_ptr<IntegerData> _number2;
|
||||
|
||||
std::shared_ptr<IntegerData> _result;
|
||||
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("未连接或运行失败!");
|
||||
};
|
61
NodeEditorPro/examples/calculator/MultiplicationModel.hpp
Normal file
61
NodeEditorPro/examples/calculator/MultiplicationModel.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "MathOperationDataModel.hpp"
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class MultiplicationModel : public MathOperationDataModel
|
||||
{
|
||||
public:
|
||||
|
||||
virtual
|
||||
~MultiplicationModel() {}
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("乘法");
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("乘法");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
compute() override
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
|
||||
auto n1 = _number1.lock();
|
||||
auto n2 = _number2.lock();
|
||||
|
||||
if (n1 && n2)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
_result = std::make_shared<DecimalData>(n1->number() *
|
||||
n2->number());
|
||||
}
|
||||
else
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("未连接或输入错误!");
|
||||
_result.reset();
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
}
|
||||
};
|
102
NodeEditorPro/examples/calculator/NumberDisplayDataModel.cpp
Normal file
102
NodeEditorPro/examples/calculator/NumberDisplayDataModel.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "NumberDisplayDataModel.hpp"
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
NumberDisplayDataModel::
|
||||
NumberDisplayDataModel()
|
||||
: _label{nullptr}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
NumberDisplayDataModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
NodeDataType
|
||||
NumberDisplayDataModel::
|
||||
dataType(PortType, PortIndex) const
|
||||
{
|
||||
return DecimalData().type();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
NumberDisplayDataModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
std::shared_ptr<NodeData> ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NumberDisplayDataModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int)
|
||||
{
|
||||
auto numberData = std::dynamic_pointer_cast<DecimalData>(data);
|
||||
|
||||
if (numberData)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
_label->setText(numberData->numberAsText());
|
||||
}
|
||||
else
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("Missing or incorrect inputs");
|
||||
_label->clear();
|
||||
}
|
||||
|
||||
_label->adjustSize();
|
||||
}
|
||||
|
||||
QWidget*
|
||||
NumberDisplayDataModel::
|
||||
embeddedWidget()
|
||||
{
|
||||
if (!_label)
|
||||
{
|
||||
_label = new QLabel();
|
||||
_label->setMargin(3);
|
||||
}
|
||||
|
||||
return _label;
|
||||
}
|
||||
|
||||
NodeValidationState
|
||||
NumberDisplayDataModel::
|
||||
validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
NumberDisplayDataModel::
|
||||
validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
80
NodeEditorPro/examples/calculator/NumberDisplayDataModel.hpp
Normal file
80
NodeEditorPro/examples/calculator/NumberDisplayDataModel.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
class QLabel;
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class NumberDisplayDataModel : public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NumberDisplayDataModel();
|
||||
|
||||
virtual
|
||||
~NumberDisplayDataModel() {}
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("数字显示");
|
||||
}
|
||||
|
||||
bool
|
||||
captionVisible() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("数字显示");
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType,
|
||||
PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData> data, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override;
|
||||
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
private:
|
||||
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("未连接或运算失败!");
|
||||
|
||||
QLabel* _label;
|
||||
};
|
129
NodeEditorPro/examples/calculator/NumberSourceDataModel.cpp
Normal file
129
NodeEditorPro/examples/calculator/NumberSourceDataModel.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
#include "NumberSourceDataModel.hpp"
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
|
||||
#include <QtCore/QJsonValue>
|
||||
#include <QtGui/QDoubleValidator>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
|
||||
NumberSourceDataModel::
|
||||
NumberSourceDataModel()
|
||||
: _lineEdit{ nullptr }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QJsonObject
|
||||
NumberSourceDataModel::
|
||||
save() const
|
||||
{
|
||||
QJsonObject modelJson = NodeDataModel::save();
|
||||
|
||||
if (_number)
|
||||
modelJson["number"] = QString::number(_number->number());
|
||||
|
||||
return modelJson;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NumberSourceDataModel::
|
||||
restore(QJsonObject const& p)
|
||||
{
|
||||
QJsonValue v = p["number"];
|
||||
|
||||
if (!v.isUndefined())
|
||||
{
|
||||
QString strNum = v.toString();
|
||||
|
||||
bool ok;
|
||||
double d = strNum.toDouble(&ok);
|
||||
if (ok)
|
||||
{
|
||||
_number = std::make_shared<DecimalData>(d);
|
||||
_lineEdit->setText(strNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
NumberSourceDataModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NumberSourceDataModel::
|
||||
onTextEdited(QString const& string)
|
||||
{
|
||||
Q_UNUSED(string);
|
||||
|
||||
bool ok = false;
|
||||
|
||||
double number = _lineEdit->text().toDouble(&ok);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
_number = std::make_shared<DecimalData>(number);
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT dataInvalidated(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NodeDataType
|
||||
NumberSourceDataModel::
|
||||
dataType(PortType, PortIndex) const
|
||||
{
|
||||
return DecimalData().type();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
NumberSourceDataModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return _number;
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
NumberSourceDataModel::
|
||||
embeddedWidget()
|
||||
{
|
||||
if (!_lineEdit)
|
||||
{
|
||||
_lineEdit = new QLineEdit();
|
||||
|
||||
_lineEdit->setValidator(new QDoubleValidator());
|
||||
_lineEdit->setMaximumSize(_lineEdit->sizeHint());
|
||||
|
||||
connect(_lineEdit, &QLineEdit::textChanged,
|
||||
this, &NumberSourceDataModel::onTextEdited);
|
||||
|
||||
_lineEdit->setText("0.0");
|
||||
}
|
||||
|
||||
return _lineEdit;
|
||||
}
|
89
NodeEditorPro/examples/calculator/NumberSourceDataModel.hpp
Normal file
89
NodeEditorPro/examples/calculator/NumberSourceDataModel.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class DecimalData;
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class NumberSourceDataModel
|
||||
: public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NumberSourceDataModel();
|
||||
|
||||
virtual
|
||||
~NumberSourceDataModel() {}
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("数字输入");
|
||||
}
|
||||
|
||||
bool
|
||||
captionVisible() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("数字输入");
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
QJsonObject
|
||||
save() const override;
|
||||
|
||||
void
|
||||
restore(QJsonObject const& p) override;
|
||||
|
||||
public:
|
||||
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override
|
||||
{ }
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
void
|
||||
onTextEdited(QString const& string);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<DecimalData> _number;
|
||||
|
||||
QLineEdit* _lineEdit;
|
||||
};
|
90
NodeEditorPro/examples/calculator/SubtractionModel.hpp
Normal file
90
NodeEditorPro/examples/calculator/SubtractionModel.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "MathOperationDataModel.hpp"
|
||||
|
||||
#include "DecimalData.hpp"
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class SubtractionModel : public MathOperationDataModel
|
||||
{
|
||||
public:
|
||||
|
||||
virtual
|
||||
~SubtractionModel() {}
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("减法节点");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
portCaptionVisible(PortType portType, PortIndex portIndex) const override
|
||||
{
|
||||
Q_UNUSED(portType); Q_UNUSED(portIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual QString
|
||||
portCaption(PortType portType, PortIndex portIndex) const override
|
||||
{
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
if (portIndex == 0)
|
||||
return QStringLiteral("减数");
|
||||
else if (portIndex == 1)
|
||||
return QStringLiteral("被减数");
|
||||
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
return QStringLiteral("结果");
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("减法");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
compute() override
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
|
||||
auto n1 = _number1.lock();
|
||||
auto n2 = _number2.lock();
|
||||
|
||||
if (n1 && n2)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
_result = std::make_shared<DecimalData>(n1->number() -
|
||||
n2->number());
|
||||
}
|
||||
else
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失节点或运行失败!");
|
||||
_result.reset();
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
}
|
||||
};
|
166
NodeEditorPro/examples/halcon/HImageDLSegmentModel.cpp
Normal file
166
NodeEditorPro/examples/halcon/HImageDLSegmentModel.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
#include "HImageDLSegmentModel.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "HRegionData.hpp"
|
||||
#include "DrawShapeView.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "QJsonParser.hpp"
|
||||
using namespace HalconCpp;
|
||||
|
||||
|
||||
HImageDLSegmentModel::HImageDLSegmentModel()
|
||||
{
|
||||
m_hImage = std::make_shared<HImageData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
btn_select_model = new QPushButton(QStringLiteral("选择模型"));
|
||||
|
||||
connect(DrawShapeView::getInst(), SIGNAL(RegionFinished(RegionPixmapData)),
|
||||
this, SLOT(OnNewRegionData(RegionPixmapData)));
|
||||
|
||||
connect(btn_select_model, &QPushButton::clicked, [=]()
|
||||
{
|
||||
dl_path.clear();
|
||||
dl_path =
|
||||
QFileDialog::getOpenFileName(nullptr,
|
||||
tr("Select Dl Model"),
|
||||
QDir::homePath(),
|
||||
tr("File (*.hdl)"));
|
||||
if (dl_path == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
readDlModel(dl_path);
|
||||
});
|
||||
}
|
||||
|
||||
bool HImageDLSegmentModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
try
|
||||
{
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HImageDLSegmentModel::OnNewRegionData(ShapeDataStruct _data)
|
||||
{
|
||||
//if (!DrawShapeView::getInst()->getDrawFlag())
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
unsigned int HImageDLSegmentModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HImageDLSegmentModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HImageDLSegmentModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HImageDLSegmentModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
result.insert("dl_path", dl_path);
|
||||
return result;
|
||||
}
|
||||
|
||||
void HImageDLSegmentModel::restore(QJsonObject const& _json)
|
||||
{
|
||||
dl_path = _json.value("dl_path").toString();
|
||||
}
|
||||
|
||||
void HImageDLSegmentModel::readDlModel(QString modelFileName)
|
||||
{
|
||||
m_dl_model = new HDlModel();
|
||||
m_dl_model->ReadDlModel(modelFileName.toStdString().c_str());
|
||||
image_dimensions = m_dl_model->GetDlModelParam("image_dimensions");
|
||||
class_ids = m_dl_model->GetDlModelParam("class_ids");
|
||||
m_dl_model->SetDlModelParam("batch_size", 1);
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageDLSegmentModel::dataType(PortType port_type, PortIndex port_index) const
|
||||
{
|
||||
if (port_type == PortType::In)
|
||||
{
|
||||
switch (port_index)
|
||||
{
|
||||
case 0:
|
||||
return HImageData().type();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (port_index)
|
||||
{
|
||||
case 0:
|
||||
return HRegionData().type();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return HImageData().type();
|
||||
}
|
||||
|
||||
void HImageDLSegmentModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HImageData>(data);
|
||||
if (hImageData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_hImage->setHImage(*hImageData->hImage());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HImageDLSegmentModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
}
|
87
NodeEditorPro/examples/halcon/HImageDLSegmentModel.hpp
Normal file
87
NodeEditorPro/examples/halcon/HImageDLSegmentModel.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
#include "DrawShapeView.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HImageDLSegmentModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageDLSegmentModel();
|
||||
virtual ~HImageDLSegmentModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("语义分割");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("语义分割");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("语义分割");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return btn_select_model; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
QJsonObject save() const override;
|
||||
void restore(QJsonObject const&) override;
|
||||
void readDlModel(QString modelFileName);
|
||||
protected:
|
||||
bool RunTask();
|
||||
|
||||
public slots:
|
||||
void OnNewRegionData(ShapeDataStruct _data);
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
QString dl_path;
|
||||
QPushButton* btn_select_model;
|
||||
HDlModel* m_dl_model;
|
||||
HTuple image_dimensions;
|
||||
HTuple class_ids;
|
||||
HTuple valid_thres = 0.7;
|
||||
std::shared_ptr<HImageData> m_hImage;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
};
|
45
NodeEditorPro/examples/halcon/HImageData.hpp
Normal file
45
NodeEditorPro/examples/halcon/HImageData.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using namespace HalconCpp;
|
||||
|
||||
class HImageData :public NodeData
|
||||
{
|
||||
public:
|
||||
HImageData()
|
||||
{
|
||||
m_himage = HImage();
|
||||
}
|
||||
HImageData(HImage& h_image)
|
||||
{
|
||||
if (h_image.IsInitialized())
|
||||
{
|
||||
m_himage = h_image;
|
||||
}
|
||||
}
|
||||
virtual ~HImageData()
|
||||
{
|
||||
|
||||
}
|
||||
NodeDataType type() const override
|
||||
{
|
||||
return { "HImage","Img" };
|
||||
}
|
||||
HImage* hImage() { return &m_himage; }
|
||||
void setHImage(HImage const& _img)
|
||||
{
|
||||
if (!_img.IsInitialized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_himage = _img;
|
||||
}
|
||||
private:
|
||||
HImage m_himage;
|
||||
};
|
171
NodeEditorPro/examples/halcon/HImageFolderModel.cpp
Normal file
171
NodeEditorPro/examples/halcon/HImageFolderModel.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include "HImageFolderModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QDebug>
|
||||
HImageFolderModel::HImageFolderModel()
|
||||
{
|
||||
m_image_view = new HImageViewWidget();
|
||||
m_image_view->resize(200, 200);
|
||||
m_paraWidget = new QWidget();
|
||||
m_paraWidget->resize(200, 250);
|
||||
m_host = new QVBoxLayout();
|
||||
m_h_host = new QHBoxLayout();
|
||||
m_paraWidget->setLayout(m_host);
|
||||
btn_selectFolder = new QPushButton(QStringLiteral("选择目录"));
|
||||
btn_last = new QPushButton(QStringLiteral("上一张"));
|
||||
btn_next = new QPushButton(QStringLiteral("下一张"));
|
||||
|
||||
btn_selectFolder->setFixedHeight(25);
|
||||
btn_last->setFixedHeight(25);
|
||||
btn_next->setFixedHeight(25);
|
||||
m_h_host->addWidget(btn_last);
|
||||
m_h_host->addWidget(btn_next);
|
||||
|
||||
m_host->addWidget(btn_selectFolder);
|
||||
m_host->addLayout(m_h_host);
|
||||
m_host->addWidget(m_image_view);
|
||||
m_host->setSpacing(1);
|
||||
m_h_host->setSpacing(1);
|
||||
m_host->setContentsMargins(0, 0, 0, 0);
|
||||
m_paraWidget->setContentsMargins(1, 1, 1, 1);
|
||||
btn_last->installEventFilter(this);
|
||||
btn_next->installEventFilter(this);
|
||||
btn_selectFolder->installEventFilter(this);
|
||||
|
||||
m_hImageData = std::make_shared<HImageData>();
|
||||
}
|
||||
|
||||
unsigned int HImageFolderModel::nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QJsonObject HImageFolderModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
result.insert("folderPath", folderPath);
|
||||
result.insert("curIndex", curIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
void HImageFolderModel::restore(QJsonObject const& json_values)
|
||||
{
|
||||
//NodeDataModel::restore(json_values);
|
||||
folderPath = json_values["folderPath"].toString();
|
||||
curIndex = json_values["curIndex"].toInt(0);
|
||||
loadImageFolder(folderPath, curIndex);
|
||||
}
|
||||
|
||||
void HImageFolderModel::loadImageFolder(QString path, int index)
|
||||
{
|
||||
QDir dir(folderPath);
|
||||
if (folderPath == "" || !dir.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
HalconCpp::ListFiles(path.toStdString().c_str(), "files", &fileListStr);
|
||||
TupleRegexpSelect(fileListStr, "\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$", &imgListStr);
|
||||
imageCounst = imgListStr.Length();
|
||||
if (imageCounst == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (index >= imageCounst)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
curIndex = index;
|
||||
tmpImg.ReadImage(imgListStr[curIndex].ToTuple());
|
||||
m_hImageData->setHImage(tmpImg);
|
||||
m_image_view->showImage(*m_hImageData->hImage());
|
||||
}
|
||||
|
||||
bool HImageFolderModel::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (object == btn_selectFolder)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
folderPath = QFileDialog::getExistingDirectory(nullptr,tr("Select Folder"),QDir::homePath());
|
||||
if (folderPath == "")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
loadImageFolder(folderPath);
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (event->type() == QEvent::Resize)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
else if (object == btn_last)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
if (curIndex - 1 >= 0)
|
||||
{
|
||||
curIndex--;
|
||||
tmpImg.ReadImage(imgListStr[curIndex].ToTuple());
|
||||
m_hImageData->setHImage(tmpImg);
|
||||
m_image_view->showImage(*m_hImageData->hImage());
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
curIndex = imageCounst - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (object == btn_next)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
if (curIndex + 1 < imageCounst)
|
||||
{
|
||||
curIndex++;
|
||||
tmpImg.ReadImage(imgListStr[curIndex].ToTuple());
|
||||
m_hImageData->setHImage(tmpImg);
|
||||
m_image_view->showImage(*m_hImageData->hImage());
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
curIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageFolderModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HImageData().type();
|
||||
}
|
||||
std::shared_ptr<NodeData>
|
||||
HImageFolderModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::dynamic_pointer_cast<HImageData>(m_hImageData);
|
||||
}
|
83
NodeEditorPro/examples/halcon/HImageFolderModel.hpp
Normal file
83
NodeEditorPro/examples/halcon/HImageFolderModel.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像输入节点
|
||||
*/
|
||||
class HImageFolderModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageFolderModel();
|
||||
virtual ~HImageFolderModel() {}
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("图像目录输入");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("图像目录输入");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("图像目录输入");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override
|
||||
{ }
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_paraWidget; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
QJsonObject save() const override;
|
||||
void restore(QJsonObject const&) override;
|
||||
void loadImageFolder(QString path, int index = 0);
|
||||
protected:
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
private:
|
||||
QString folderPath;
|
||||
std::shared_ptr< HImageData> m_hImageData;
|
||||
QWidget* m_paraWidget;
|
||||
QVBoxLayout* m_host;
|
||||
QHBoxLayout* m_h_host;
|
||||
QPushButton* btn_selectFolder;
|
||||
QPushButton* btn_last;
|
||||
QPushButton* btn_next;
|
||||
HImageViewWidget* m_image_view;
|
||||
HTuple fileListStr;
|
||||
HTuple imgListStr;
|
||||
HImage tmpImg;
|
||||
int curIndex = 0;
|
||||
int imageCounst = 0;
|
||||
};
|
112
NodeEditorPro/examples/halcon/HImageLoaderModel.cpp
Normal file
112
NodeEditorPro/examples/halcon/HImageLoaderModel.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "HImageLoaderModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
HImageLoaderModel::HImageLoaderModel()
|
||||
{
|
||||
m_image_view = new HImageViewWidget();
|
||||
m_image_view->installEventFilter(this);
|
||||
m_image_view->resize(200, 200);
|
||||
m_hImageData = std::make_shared<HImageData>();
|
||||
}
|
||||
|
||||
unsigned int HImageLoaderModel::nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QJsonObject HImageLoaderModel::save() const
|
||||
{
|
||||
QJsonObject modelJson = NodeDataModel::save();
|
||||
if (m_hImageData)
|
||||
{
|
||||
HTuple* R, * G, * B;
|
||||
HTuple width, height;
|
||||
int chanels = m_hImageData->hImage()->CountChannels();
|
||||
m_hImageData->hImage()->GetImageSize(&width, &height);
|
||||
modelJson.insert("width", width.D());
|
||||
modelJson.insert("height", height.D());
|
||||
modelJson.insert("chanels", chanels);
|
||||
modelJson.insert("imageName", imageName);
|
||||
}
|
||||
|
||||
return modelJson;
|
||||
}
|
||||
|
||||
void HImageLoaderModel::restore(QJsonObject const& p)
|
||||
{
|
||||
imageName = p["imageName"].toString();
|
||||
loadImage(imageName);
|
||||
}
|
||||
|
||||
void HImageLoaderModel::loadImage(QString fileName)
|
||||
{
|
||||
if (fileName == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
HImage tmpImg;
|
||||
tmpImg.ReadImage(fileName.toStdString().c_str());
|
||||
m_hImageData->setHImage(tmpImg);
|
||||
m_image_view->showImage(*m_hImageData->hImage());
|
||||
}
|
||||
|
||||
bool HImageLoaderModel::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (object == m_image_view)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
imageName =
|
||||
QFileDialog::getOpenFileName(nullptr,
|
||||
tr("Open Image"),
|
||||
QDir::homePath(),
|
||||
tr("Image Files (*.png *.jpg *.bmp)"));
|
||||
if (imageName == "")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
loadImage(imageName);
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (event->type() == QEvent::Resize)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageLoaderModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HImageData().type();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HImageLoaderModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::dynamic_pointer_cast<HImageData>(m_hImageData);
|
||||
}
|
70
NodeEditorPro/examples/halcon/HImageLoaderModel.hpp
Normal file
70
NodeEditorPro/examples/halcon/HImageLoaderModel.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像输入节点
|
||||
*/
|
||||
class HImageLoaderModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageLoaderModel();
|
||||
virtual ~HImageLoaderModel() {}
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("图像输入");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("图像输入");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("图像输入");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override
|
||||
{ }
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_image_view; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
QJsonObject save() const override;
|
||||
void restore(QJsonObject const&) override;
|
||||
void loadImage(QString fileName);
|
||||
protected:
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
private:
|
||||
QString imageName;
|
||||
std::shared_ptr< HImageData> m_hImageData;
|
||||
HImageViewWidget* m_image_view;
|
||||
|
||||
};
|
102
NodeEditorPro/examples/halcon/HImageRGB2GrayModel.cpp
Normal file
102
NodeEditorPro/examples/halcon/HImageRGB2GrayModel.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "HImageRGB2GrayModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HImageRGB2GrayModel::HImageRGB2GrayModel()
|
||||
{
|
||||
m_hImage = std::make_shared<HImageData>();
|
||||
}
|
||||
|
||||
bool HImageRGB2GrayModel::RunTask()
|
||||
{
|
||||
Q_EMIT computingStarted();
|
||||
PortIndex const outPortIndex = 0;
|
||||
try
|
||||
{
|
||||
HTuple imgChanels = m_hImage->hImage()->CountChannels();
|
||||
if (imgChanels == 3)
|
||||
{
|
||||
HImage tmp_img = m_hImage->hImage()->Rgb3ToGray(*m_hImage->hImage(), *m_hImage->hImage());
|
||||
m_hImage->setHImage(tmp_img);
|
||||
tmp_img.Clear();
|
||||
}
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
Q_EMIT computingFinished();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int HImageRGB2GrayModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HImageRGB2GrayModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HImageRGB2GrayModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageRGB2GrayModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HImageData().type();
|
||||
}
|
||||
|
||||
void HImageRGB2GrayModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HImageData>(data);
|
||||
if (hImageData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_hImage->setHImage(*hImageData->hImage());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HImageRGB2GrayModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::dynamic_pointer_cast<HImageData>(m_hImage);
|
||||
}
|
73
NodeEditorPro/examples/halcon/HImageRGB2GrayModel.hpp
Normal file
73
NodeEditorPro/examples/halcon/HImageRGB2GrayModel.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HImageRGB2GrayModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageRGB2GrayModel();
|
||||
virtual ~HImageRGB2GrayModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("图像转灰度");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("图像转灰度");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("图像转灰度");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return Q_NULLPTR; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HImageData> m_hImage;
|
||||
|
||||
};
|
142
NodeEditorPro/examples/halcon/HImageReduceDomainModel.cpp
Normal file
142
NodeEditorPro/examples/halcon/HImageReduceDomainModel.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "HImageReduceDomainModel.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QtCore/QEvent>
|
||||
#include "DrawShapeView.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "QJsonParser.hpp"
|
||||
using namespace HalconCpp;
|
||||
|
||||
|
||||
HImageReduceDomainModel::HImageReduceDomainModel()
|
||||
{
|
||||
m_hImage = std::make_shared<HImageData>();
|
||||
m_result = std::make_shared<HImageData>();
|
||||
btn_drawReg = new QPushButton(QStringLiteral("绘制区域"));
|
||||
m_region_data = std::make_shared<ShapeDataStruct>();
|
||||
m_domain.GenEmptyRegion();
|
||||
|
||||
connect(DrawShapeView::getInst(), SIGNAL(RegionComform(ShapeDataStruct)),
|
||||
this, SLOT(OnNewRegionData(ShapeDataStruct)));
|
||||
|
||||
connect(btn_drawReg, &QPushButton::clicked, [=]()
|
||||
{
|
||||
QPixmap tmpPix;
|
||||
HImageViewWidget::HImageToQPixmap(*m_hImage->hImage(), tmpPix);
|
||||
DrawShapeView::getInst()->FitShowImage(tmpPix, *m_region_data);
|
||||
});
|
||||
}
|
||||
|
||||
bool HImageReduceDomainModel::RunTask()
|
||||
{
|
||||
//Q_EMIT computingStarted();
|
||||
PortIndex const outPortIndex = 0;
|
||||
try
|
||||
{
|
||||
if ((int)m_region_data->shapePolygon.size() > 0)
|
||||
{
|
||||
HImage tmpImage;
|
||||
HalconCpp::ReduceDomain(*m_hImage->hImage(), m_domain, &tmpImage);
|
||||
m_result->setHImage(tmpImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_result->setHImage(*m_hImage->hImage());
|
||||
}
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HImageReduceDomainModel::OnNewRegionData(ShapeDataStruct _data)
|
||||
{
|
||||
*m_region_data = std::move(_data);
|
||||
m_domain = DrawShapeView::GetHRegionFromData(*m_region_data);
|
||||
|
||||
RunTask();
|
||||
}
|
||||
|
||||
unsigned int HImageReduceDomainModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HImageReduceDomainModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HImageReduceDomainModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HImageReduceDomainModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
result.insert("m_region_data", QJsonConvert::convertToJson(*m_region_data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void HImageReduceDomainModel::restore(QJsonObject const& _json)
|
||||
{
|
||||
QJsonConvert::convertFromJson(_json.value("m_region_data").toObject(), *m_region_data);
|
||||
m_domain = DrawShapeView::GetHRegionFromData(*m_region_data);
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageReduceDomainModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HImageData().type();
|
||||
}
|
||||
|
||||
void HImageReduceDomainModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HImageData>(data);
|
||||
if (hImageData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_hImage->setHImage(*hImageData->hImage());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HImageReduceDomainModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::dynamic_pointer_cast<HImageData>(m_result);
|
||||
}
|
83
NodeEditorPro/examples/halcon/HImageReduceDomainModel.hpp
Normal file
83
NodeEditorPro/examples/halcon/HImageReduceDomainModel.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
#include "DrawShapeView.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HImageReduceDomainModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageReduceDomainModel();
|
||||
virtual ~HImageReduceDomainModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("选区掩膜");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("选区掩膜");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("选区掩膜");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return btn_drawReg; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
QJsonObject save() const override;
|
||||
void restore(QJsonObject const&) override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
|
||||
public slots:
|
||||
void OnNewRegionData(ShapeDataStruct _data);
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
//HWindow* h_window;
|
||||
QPushButton* btn_drawReg;
|
||||
HRegion m_domain;
|
||||
std::shared_ptr<ShapeDataStruct> m_region_data;
|
||||
std::shared_ptr<HImageData> m_hImage;
|
||||
std::shared_ptr<HImageData> m_result;
|
||||
};
|
153
NodeEditorPro/examples/halcon/HImageShowModel.cpp
Normal file
153
NodeEditorPro/examples/halcon/HImageShowModel.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include "HImageShowModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
HImageShowModel::HImageShowModel()
|
||||
{
|
||||
m_image_view = new HImageViewWidget();
|
||||
m_image_view->installEventFilter(this);
|
||||
m_image_view->resize(200, 200);
|
||||
m_hImage = std::make_shared<HImageData>();
|
||||
m_hRegion = std::make_shared<HRegionData>();
|
||||
#ifdef SHOWHALCON_OBJ
|
||||
h_window = new HWindow(0, 0, 512, 512, nullptr, "visible", "");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool HImageShowModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
|
||||
try
|
||||
{
|
||||
m_image_view->showImage(*m_hImage->hImage());
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int HImageShowModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 2;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 2;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HImageShowModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HImageShowModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
bool HImageShowModel::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageShowModel::dataType(PortType, PortIndex index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return HImageData().type();
|
||||
break;
|
||||
case 1:
|
||||
return HRegionData().type();
|
||||
break;
|
||||
}
|
||||
return HImageData().type();
|
||||
}
|
||||
|
||||
void HImageShowModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
if (data == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (data->type() == m_hImage->type())
|
||||
{
|
||||
auto dataPtr = std::dynamic_pointer_cast<HImageData>(data);
|
||||
if (!dataPtr->hImage()->IsInitialized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_hImage->setHImage(*dataPtr->hImage());
|
||||
#ifdef SHOWHALCON_OBJ
|
||||
h_window->ClearWindow();
|
||||
h_window->SetPart(HTuple(0), HTuple(0), m_hImage->hImage()->Height(), m_hImage->hImage()->Width());
|
||||
HTuple chanels = m_hImage->hImage()->CountChannels();
|
||||
if (chanels == 1)
|
||||
{
|
||||
h_window->DispImage(*m_hImage->hImage());
|
||||
}
|
||||
else
|
||||
{
|
||||
h_window->DispColor(*m_hImage->hImage());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (data->type() == m_hRegion->type())
|
||||
{
|
||||
auto dataPtr = std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (!dataPtr->hRegion()->IsInitialized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_hRegion->setHRegion(*dataPtr->hRegion());
|
||||
m_hRegion->setSize(dataPtr->getSize());
|
||||
|
||||
HImage tmpImg = m_hRegion->hRegion()->RegionToBin(255, 0,
|
||||
m_hRegion->getSize().width(), m_hRegion->getSize().height());
|
||||
m_hImage->setHImage(tmpImg);
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HImageShowModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<HImageData>(m_hImage);
|
||||
break;
|
||||
case 1:
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_hRegion);
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<HImageData>(m_hImage);
|
||||
}
|
82
NodeEditorPro/examples/halcon/HImageShowModel.hpp
Normal file
82
NodeEditorPro/examples/halcon/HImageShowModel.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
|
||||
//#define SHOWHALCON_OBJ
|
||||
|
||||
/**
|
||||
* \brief halcon 图像输入节点
|
||||
*/
|
||||
class HImageShowModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageShowModel();
|
||||
virtual ~HImageShowModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("图像显示");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("图像显示");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("图像显示");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_image_view; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
#ifdef SHOWHALCON_OBJ
|
||||
HWindow* h_window;
|
||||
#endif
|
||||
|
||||
std::shared_ptr<HImageData> m_hImage;
|
||||
std::shared_ptr<HRegionData> m_hRegion;
|
||||
HImageViewWidget* m_image_view;
|
||||
};
|
140
NodeEditorPro/examples/halcon/HImageSplitChanelModel.cpp
Normal file
140
NodeEditorPro/examples/halcon/HImageSplitChanelModel.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include "HImageSplitChanelModel.hpp"
|
||||
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HImageSplitChanelModel::HImageSplitChanelModel()
|
||||
{
|
||||
m_hImage = std::make_shared<HImageData>();
|
||||
}
|
||||
|
||||
bool HImageSplitChanelModel::RunTask()
|
||||
{
|
||||
|
||||
auto img1 = m_hImage.lock();
|
||||
try
|
||||
{
|
||||
if (img1)
|
||||
{
|
||||
HTuple imgChanels = img1->hImage()->CountChannels();
|
||||
if (imgChanels == 3)
|
||||
{
|
||||
HImage chanR, chanG, chanB;
|
||||
Decompose3(*img1->hImage(), &chanR, &chanG, &chanB);
|
||||
if (m_resultR == nullptr)
|
||||
{
|
||||
m_resultR = std::make_shared<HImageData>(chanR);
|
||||
}
|
||||
if (m_resultG == nullptr)
|
||||
{
|
||||
m_resultG = std::make_shared<HImageData>(chanG);
|
||||
}
|
||||
if (m_resultB == nullptr)
|
||||
{
|
||||
m_resultB = std::make_shared<HImageData>(chanB);
|
||||
}
|
||||
m_resultR->setHImage(chanR);
|
||||
m_resultG->setHImage(chanG);
|
||||
m_resultB->setHImage(chanB);
|
||||
}
|
||||
else if (imgChanels == 1)
|
||||
{
|
||||
m_resultR = std::shared_ptr<HImageData>(m_hImage);
|
||||
m_resultG = std::shared_ptr<HImageData>(m_hImage);
|
||||
m_resultB = std::shared_ptr<HImageData>(m_hImage);
|
||||
}
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
m_resultR.reset();
|
||||
m_resultG.reset();
|
||||
m_resultB.reset();
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated((PortIndex)0);
|
||||
Q_EMIT dataUpdated((PortIndex)1);
|
||||
Q_EMIT dataUpdated((PortIndex)2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int HImageSplitChanelModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 3;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HImageSplitChanelModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HImageSplitChanelModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageSplitChanelModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HImageData().type();
|
||||
}
|
||||
|
||||
void HImageSplitChanelModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HImageData>(data);
|
||||
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_hImage = hImageData;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HImageSplitChanelModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
return std::static_pointer_cast<NodeData>(m_resultR);
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
return std::static_pointer_cast<NodeData>(m_resultG);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::static_pointer_cast<NodeData>(m_resultB);
|
||||
}
|
||||
}
|
75
NodeEditorPro/examples/halcon/HImageSplitChanelModel.hpp
Normal file
75
NodeEditorPro/examples/halcon/HImageSplitChanelModel.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HImageSplitChanelModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageSplitChanelModel();
|
||||
virtual ~HImageSplitChanelModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("SplitChanel");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("图像通道拆分");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("通道拆分");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return Q_NULLPTR; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
std::weak_ptr<HImageData> m_hImage;
|
||||
std::shared_ptr<HImageData> m_resultR;
|
||||
std::shared_ptr<HImageData> m_resultG;
|
||||
std::shared_ptr<HImageData> m_resultB;
|
||||
};
|
204
NodeEditorPro/examples/halcon/HImageThresholdModel.cpp
Normal file
204
NodeEditorPro/examples/halcon/HImageThresholdModel.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
#include "HImageThresholdModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HImageThresholdModel::HImageThresholdModel()
|
||||
{
|
||||
m_widget = new QWidget();
|
||||
m_widget->setAttribute(Qt::WA_NoSystemBackground);
|
||||
m_widget->setFixedSize(130, 70);
|
||||
m_minGraySlider = new QSlider(m_widget);
|
||||
m_maxGraySlider = new QSlider(m_widget);
|
||||
m_minGraySlider->setOrientation(Qt::Horizontal);
|
||||
m_maxGraySlider->setOrientation(Qt::Horizontal);
|
||||
m_minGraySlider->resize(120, 25);
|
||||
m_maxGraySlider->resize(120, 25);
|
||||
m_minGraySlider->move(0, 0);
|
||||
m_maxGraySlider->move(0, 35);
|
||||
m_minGraySlider->setMinimum(0);
|
||||
m_minGraySlider->setMaximum(255);
|
||||
m_maxGraySlider->setMinimum(0);
|
||||
m_maxGraySlider->setMaximum(255);
|
||||
|
||||
m_maxGraySlider->setValue(255);
|
||||
|
||||
m_hImage = std::make_shared<HImageData>();
|
||||
m_domain = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
connect(m_minGraySlider, &QSlider::valueChanged, [=]()
|
||||
{
|
||||
RunTask();
|
||||
});
|
||||
connect(m_maxGraySlider, &QSlider::valueChanged, [=]()
|
||||
{
|
||||
RunTask();
|
||||
});
|
||||
}
|
||||
|
||||
bool HImageThresholdModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
if (m_hImage->hImage() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (m_domain->hRegion()->IsInitialized())
|
||||
{
|
||||
m_hImage->hImage()->ReduceDomain(*m_domain->hRegion());
|
||||
}
|
||||
int imgChanels = m_hImage->hImage()->CountChannels();
|
||||
HImage tmp_img;
|
||||
if (imgChanels == 3)
|
||||
{
|
||||
tmp_img = m_hImage->hImage()->Rgb3ToGray(*m_hImage->hImage(), *m_hImage->hImage());
|
||||
}
|
||||
else if (imgChanels == 1)
|
||||
{
|
||||
tmp_img = *m_hImage->hImage();
|
||||
}
|
||||
|
||||
double minVal = m_minGraySlider->value();
|
||||
double maxVal = m_maxGraySlider->value();
|
||||
|
||||
m_result->setHRegion(m_hImage->hImage()->Threshold(minVal, maxVal));
|
||||
m_result->setSize(QSize(m_hImage->hImage()->Width().D(), m_hImage->hImage()->Height().D()));
|
||||
tmp_img.Clear();
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HImageThresholdModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int HImageThresholdModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 2;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HImageThresholdModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HImageThresholdModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HImageThresholdModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
result.insert("m_minGraySlider", m_minGraySlider->value());
|
||||
result.insert("m_maxGraySlider", m_maxGraySlider->value());
|
||||
return result;
|
||||
}
|
||||
|
||||
void HImageThresholdModel::restore(QJsonObject const& p)
|
||||
{
|
||||
m_minGraySlider->setValue(p["m_minGraySlider"].toInt(0));
|
||||
m_maxGraySlider->setValue(p["m_maxGraySlider"].toInt(255));
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HImageThresholdModel::dataType(PortType portType, PortIndex portIndex) const
|
||||
{
|
||||
if (portType == PortType::In)
|
||||
{
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
return HImageData().type();
|
||||
break;
|
||||
case 1:
|
||||
return HRegionData().type();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
return HRegionData().type();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return HImageData().type();
|
||||
}
|
||||
|
||||
void HImageThresholdModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
if (portIndex == 0)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HImageData>(data);
|
||||
if (hImageData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_hImage->setHImage(*hImageData->hImage());
|
||||
}
|
||||
else if (portIndex == 1)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hImageData != nullptr)
|
||||
{
|
||||
m_domain->setHRegion(*hImageData->hRegion());
|
||||
}
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HImageThresholdModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<NodeData>(m_result);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<NodeData>(m_result);
|
||||
}
|
83
NodeEditorPro/examples/halcon/HImageThresholdModel.hpp
Normal file
83
NodeEditorPro/examples/halcon/HImageThresholdModel.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HImageThresholdModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HImageThresholdModel();
|
||||
virtual ~HImageThresholdModel() = default;
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("二值化节点");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("二值化节点");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("二值化节点");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_widget; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
QJsonObject save() const override;
|
||||
|
||||
void restore(QJsonObject const&) override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HImageData> m_hImage;
|
||||
std::shared_ptr<HRegionData> m_domain;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
QSlider* m_minGraySlider;
|
||||
QSlider* m_maxGraySlider;
|
||||
QWidget* m_widget;
|
||||
};
|
158
NodeEditorPro/examples/halcon/HImageViewWidget.cpp
Normal file
158
NodeEditorPro/examples/halcon/HImageViewWidget.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
HImageViewWidget::HImageViewWidget(QWidget* parent)
|
||||
|
||||
{
|
||||
if (parent != Q_NULLPTR)
|
||||
{
|
||||
this->setParent(parent);
|
||||
}
|
||||
this->setStyleSheet("background-color:black;");
|
||||
cur_pixmap = new QPixmap();
|
||||
}
|
||||
|
||||
void HImageViewWidget::showImage(HImage const& _himg)
|
||||
{
|
||||
if (!_himg.IsInitialized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Hlong width;
|
||||
Hlong height;
|
||||
double zoom_ratio = 1.0;
|
||||
_himg.GetImageSize(&width, &height);
|
||||
if (width > this->width())
|
||||
{
|
||||
zoom_ratio = 1.0 * this->width() / width;
|
||||
}
|
||||
cur_image = _himg.ZoomImageSize(width * zoom_ratio, height * zoom_ratio, "bilinear");
|
||||
HImageToQPixmap(cur_image, *cur_pixmap);
|
||||
this->update();
|
||||
}
|
||||
|
||||
void HImageViewWidget::HImageToQPixmap(HImage const& _img, QPixmap& tar_pixmap)
|
||||
{
|
||||
Hlong w, h; HString hType;
|
||||
Hlong width;
|
||||
Hlong height;
|
||||
QImage tar_img;
|
||||
|
||||
_img.GetImageSize(&width, &height);
|
||||
HTuple type = _img.GetImageType();
|
||||
//获取HImage的通道数
|
||||
HTuple hChannels = _img.CountChannels();
|
||||
if (strcmp(type[0].S(), "byte")) // 如果不是 byte 类型,则失败
|
||||
{
|
||||
return;
|
||||
}
|
||||
QImage::Format format;
|
||||
switch (hChannels[0].I())
|
||||
{
|
||||
case 1:
|
||||
format = QImage::Format_Grayscale8;
|
||||
break;
|
||||
case 3:
|
||||
format = QImage::Format_RGB32;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (tar_img.width() != width || tar_img.height() != height || tar_img.format() != format)
|
||||
{
|
||||
tar_img = QImage(static_cast<int>(width),
|
||||
static_cast<int>(height),
|
||||
format);
|
||||
}
|
||||
if (hChannels == 1)
|
||||
{
|
||||
//获取HImage的数据指针
|
||||
uchar* pBuf = (uchar*)_img.GetImagePointer1(&hType, &w, &h);
|
||||
|
||||
//创建QImage图片
|
||||
tar_img = QImage(w, h, QImage::Format_Indexed8);
|
||||
|
||||
//memcpy
|
||||
for (int i = 0; i < h; i++, pBuf += w)
|
||||
{
|
||||
uchar* pDest = tar_img.scanLine(i);
|
||||
memcpy(pDest, pBuf, w);
|
||||
}
|
||||
|
||||
//tar_pixmap = QPixmap::fromImage(tar_img);
|
||||
}
|
||||
else if (hChannels == 3)
|
||||
{
|
||||
uchar* R, * G, * B;
|
||||
_img.GetImagePointer3(reinterpret_cast<void**>(&R),
|
||||
reinterpret_cast<void**>(&G),
|
||||
reinterpret_cast<void**>(&B), &hType, &width, &height);
|
||||
|
||||
for (int row = 0; row < height; row++)
|
||||
{
|
||||
QRgb* line = reinterpret_cast<QRgb*>(tar_img.scanLine(row));
|
||||
for (int col = 0; col < width; col++)
|
||||
{
|
||||
line[col] = qRgb(*R++, *G++, *B++);
|
||||
}
|
||||
}
|
||||
}
|
||||
tar_pixmap = QPixmap::fromImage(tar_img);
|
||||
}
|
||||
|
||||
void HImageViewWidget::QPixmapToHRegion(QPixmap const& _pix, HRegion& tar_reg)
|
||||
{
|
||||
HImage tmpImag;
|
||||
QImage tmpQImag = _pix.toImage();
|
||||
bool trans = HImageViewWidget::QImage2HImage(tmpQImag, tmpImag);
|
||||
if (trans)
|
||||
{
|
||||
tar_reg = tmpImag.Threshold(100, 255);
|
||||
}
|
||||
tmpImag.Clear();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QImage2HImage 将 Qt QImage 转换为 Halcon 的 HImage
|
||||
* @param from 输入的 QImage
|
||||
* @param to 输出的 HImage ,from 和 to 不共享内存数据。 每次都会为 to 重新分配内存。
|
||||
* @return true 表示转换成功,false 表示转换失败。
|
||||
*/
|
||||
bool HImageViewWidget::QImage2HImage(QImage& from, HalconCpp::HImage& to)
|
||||
{
|
||||
if (from.isNull()) return false;
|
||||
|
||||
int width = from.width(), height = from.height();
|
||||
QImage::Format format = from.format();
|
||||
|
||||
if (format == QImage::Format_RGB32 ||
|
||||
format == QImage::Format_ARGB32 ||
|
||||
format == QImage::Format_ARGB32_Premultiplied)
|
||||
{
|
||||
to.GenImageInterleaved(from.bits(), "rgbx", width, height, 0, "byte", width, height, 0, 0, 8, 0);
|
||||
return true;
|
||||
}
|
||||
else if (format == QImage::Format_RGB888)
|
||||
{
|
||||
to.GenImageInterleaved(from.bits(), "rgb", width, height, 0, "byte", width, height, 0, 0, 8, 0);
|
||||
return true;
|
||||
}
|
||||
else if (format == QImage::Format_Grayscale8 || format == QImage::Format_Indexed8)
|
||||
{
|
||||
to.GenImage1("byte", width, height, from.bits());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void HImageViewWidget::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
//QPainter painter(this);
|
||||
if (!cur_pixmap->isNull())
|
||||
{
|
||||
this->setPixmap(cur_pixmap->scaled(this->width(), this->height(), Qt::KeepAspectRatio));
|
||||
}
|
||||
QLabel::paintEvent(event);
|
||||
}
|
||||
|
30
NodeEditorPro/examples/halcon/HImageViewWidget.hpp
Normal file
30
NodeEditorPro/examples/halcon/HImageViewWidget.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QGraphicsView>
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
using namespace HalconCpp;
|
||||
|
||||
class HImageViewWidget
|
||||
:public QLabel
|
||||
{
|
||||
public:
|
||||
HImageViewWidget(QWidget* parent = Q_NULLPTR);
|
||||
virtual ~HImageViewWidget() {}
|
||||
void showImage(HImage const& _himg);
|
||||
public:
|
||||
static void HImageToQPixmap(HImage const& _img, QPixmap& tar_img);
|
||||
static bool QImage2HImage(QImage& from, HImage& to);
|
||||
static void QPixmapToHRegion(QPixmap const& _pix, HRegion& tar_img);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
private:
|
||||
HImage cur_image;
|
||||
QPixmap* cur_pixmap;
|
||||
// 实例化画家对象,this指定的是绘图设备
|
||||
QPainter painter;
|
||||
};
|
||||
|
47
NodeEditorPro/examples/halcon/HObjectData.hpp
Normal file
47
NodeEditorPro/examples/halcon/HObjectData.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using namespace HalconCpp;
|
||||
|
||||
class HObjecData :public NodeData
|
||||
{
|
||||
public:
|
||||
HObjecData()
|
||||
{
|
||||
m_hObject = HObject();
|
||||
}
|
||||
HObjecData(HObject& _obj)
|
||||
{
|
||||
if (_obj.IsInitialized())
|
||||
{
|
||||
m_hObject = _obj;
|
||||
}
|
||||
}
|
||||
virtual ~HObjecData()
|
||||
{
|
||||
|
||||
}
|
||||
NodeDataType type() const override
|
||||
{
|
||||
return { "HObject","data" };
|
||||
}
|
||||
|
||||
HObject* hObject() { return &m_hObject; }
|
||||
|
||||
void setObject(HObject const& _obj)
|
||||
{
|
||||
if (!_obj.IsInitialized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_hObject = _obj;
|
||||
}
|
||||
private:
|
||||
HObject m_hObject;
|
||||
};
|
121
NodeEditorPro/examples/halcon/HRegionConnectModel.cpp
Normal file
121
NodeEditorPro/examples/halcon/HRegionConnectModel.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include "HRegionConnectModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionConnectModel::HRegionConnectModel()
|
||||
{
|
||||
m_InRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
}
|
||||
|
||||
bool HRegionConnectModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
if (m_InRegion->hRegion() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
m_result->setHRegion(m_InRegion->hRegion()->Connection());
|
||||
|
||||
m_result->setSize(m_InRegion->getSize());
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HRegionConnectModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int HRegionConnectModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionConnectModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionConnectModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionConnectModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionConnectModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hRegionData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hRegionData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_InRegion->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegion->setSize(hRegionData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionConnectModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
}
|
76
NodeEditorPro/examples/halcon/HRegionConnectModel.hpp
Normal file
76
NodeEditorPro/examples/halcon/HRegionConnectModel.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HRegionConnectModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionConnectModel();
|
||||
virtual ~HRegionConnectModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("非联通区域");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("非联通区域");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("非联通区域");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return nullptr; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("区域输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HRegionData> m_InRegion;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
};
|
54
NodeEditorPro/examples/halcon/HRegionData.hpp
Normal file
54
NodeEditorPro/examples/halcon/HRegionData.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using namespace HalconCpp;
|
||||
|
||||
class HRegionData :public NodeData
|
||||
{
|
||||
public:
|
||||
HRegionData()
|
||||
{
|
||||
m_hRegion = HRegion();
|
||||
}
|
||||
HRegionData(HRegion& _hregion)
|
||||
{
|
||||
if (_hregion.IsInitialized())
|
||||
{
|
||||
m_hRegion = _hregion;
|
||||
}
|
||||
}
|
||||
virtual ~HRegionData()
|
||||
{
|
||||
|
||||
}
|
||||
NodeDataType type() const override
|
||||
{
|
||||
return { "HRegion","Region" };
|
||||
}
|
||||
HRegion* hRegion() { return &m_hRegion; }
|
||||
void setHRegion(HRegion const& _hregion)
|
||||
{
|
||||
if (!_hregion.IsInitialized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_hRegion = _hregion;
|
||||
}
|
||||
QSize getSize()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
void setSize(QSize const& _size)
|
||||
{
|
||||
m_size = _size;
|
||||
}
|
||||
private:
|
||||
HRegion m_hRegion;
|
||||
QSize m_size;
|
||||
};
|
153
NodeEditorPro/examples/halcon/HRegionDifferenceModel.cpp
Normal file
153
NodeEditorPro/examples/halcon/HRegionDifferenceModel.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include "HRegionDifferenceModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionDifferenceModel::HRegionDifferenceModel()
|
||||
{
|
||||
m_InRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
m_InRegionDiv = std::make_shared<HRegionData>();
|
||||
|
||||
}
|
||||
|
||||
QString HRegionDifferenceModel::portCaption(PortType port, PortIndex port_index) const
|
||||
{
|
||||
if (port == PortType::In)
|
||||
{
|
||||
switch (port_index)
|
||||
{
|
||||
case 0:
|
||||
return "Ori";
|
||||
break;
|
||||
case 1:
|
||||
return "Div";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (port == PortType::Out)
|
||||
{
|
||||
switch (port_index)
|
||||
{
|
||||
case 0:
|
||||
return "Res";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return HRegionDifferenceModel::portCaption(port, port_index);
|
||||
}
|
||||
|
||||
bool HRegionDifferenceModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
if (m_InRegion->hRegion() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
HalconCpp::Difference(*m_InRegion->hRegion(), *m_InRegionDiv->hRegion(), m_result->hRegion());
|
||||
|
||||
m_result->setSize(m_InRegion->getSize());
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HRegionDifferenceModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int HRegionDifferenceModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 2;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionDifferenceModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionDifferenceModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionDifferenceModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionDifferenceModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hRegionData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hRegionData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_InRegion->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegion->setSize(hRegionData->getSize());
|
||||
break;
|
||||
case 1:
|
||||
m_InRegionDiv->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegionDiv->setSize(hRegionData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionDifferenceModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
}
|
78
NodeEditorPro/examples/halcon/HRegionDifferenceModel.hpp
Normal file
78
NodeEditorPro/examples/halcon/HRegionDifferenceModel.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HRegionDifferenceModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionDifferenceModel();
|
||||
virtual ~HRegionDifferenceModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("相减区域");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("相减区域");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("相减区域");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return nullptr; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
bool portCaptionVisible(PortType, PortIndex) const override { return true; }
|
||||
QString portCaption(PortType, PortIndex) const override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("区域输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HRegionData> m_InRegion;
|
||||
std::shared_ptr<HRegionData> m_InRegionDiv;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
};
|
160
NodeEditorPro/examples/halcon/HRegionFillUpShapeModel.cpp
Normal file
160
NodeEditorPro/examples/halcon/HRegionFillUpShapeModel.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "HRegionFillUpShapeModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionFillUpShapeModel::HRegionFillUpShapeModel()
|
||||
{
|
||||
m_hRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
m_widget = new QWidget();
|
||||
m_host = new QVBoxLayout();
|
||||
m_combo_feature = new QComboBox();
|
||||
|
||||
m_minvalEdit = new QLineEdit();
|
||||
m_maxvalEdit = new QLineEdit();
|
||||
m_widget->setContentsMargins(0, 0, 0, 0);
|
||||
m_host->setSpacing(1);
|
||||
m_widget->setLayout(m_host);
|
||||
m_host->addWidget(m_combo_feature);
|
||||
m_host->addWidget(m_minvalEdit);
|
||||
m_host->addWidget(m_maxvalEdit);
|
||||
m_widget->setFixedHeight(90);
|
||||
m_widget->setFixedWidth(100);
|
||||
m_combo_feature->addItem("area");
|
||||
m_combo_feature->addItem("compactness");
|
||||
m_combo_feature->addItem("convexity");
|
||||
m_combo_feature->addItem("anisometry");
|
||||
m_minvalEdit->setText("0.0");
|
||||
m_maxvalEdit->setText("100.0");
|
||||
|
||||
connect(m_minvalEdit, &QLineEdit::textChanged, [=]()
|
||||
{
|
||||
m_minval = m_minvalEdit->text().toDouble();
|
||||
RunTask();
|
||||
});
|
||||
connect(m_maxvalEdit, &QLineEdit::textChanged, [=]()
|
||||
{
|
||||
m_maxval = m_maxvalEdit->text().toDouble();
|
||||
RunTask();
|
||||
});
|
||||
connect(m_combo_feature, &QComboBox::currentTextChanged, [=]()
|
||||
{
|
||||
m_feature = m_combo_feature->currentText();
|
||||
RunTask();
|
||||
});
|
||||
}
|
||||
|
||||
bool HRegionFillUpShapeModel::RunTask()
|
||||
{
|
||||
Q_EMIT computingStarted();
|
||||
PortIndex const outPortIndex = 0;
|
||||
try
|
||||
{
|
||||
HalconCpp::FillUpShape(*m_hRegion->hRegion(), m_result->hRegion(),
|
||||
m_feature.toStdString().c_str(),
|
||||
m_minval,
|
||||
m_maxval);
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
Q_EMIT computingFinished();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int HRegionFillUpShapeModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionFillUpShapeModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionFillUpShapeModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HRegionFillUpShapeModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
|
||||
result.insert("m_minval", m_minval);
|
||||
result.insert("m_maxval", m_maxval);
|
||||
result.insert("m_feature", m_feature);
|
||||
return result;
|
||||
}
|
||||
|
||||
void HRegionFillUpShapeModel::restore(QJsonObject const& json_values)
|
||||
{
|
||||
NodeDataModel::restore(json_values);
|
||||
m_minval = json_values.value("m_minval").toDouble();
|
||||
m_maxval = json_values.value("m_maxval").toDouble();
|
||||
m_feature = json_values.value("m_feature").toString();
|
||||
|
||||
m_combo_feature->setCurrentText(m_feature);
|
||||
m_minvalEdit->setText(QString::number(m_minval));
|
||||
m_maxvalEdit->setText(QString::number(m_maxval));
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionFillUpShapeModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionFillUpShapeModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hImageData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_hRegion->setHRegion(*hImageData->hRegion());
|
||||
m_result->setSize(hImageData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionFillUpShapeModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::static_pointer_cast<HRegionData>(m_result);
|
||||
}
|
88
NodeEditorPro/examples/halcon/HRegionFillUpShapeModel.hpp
Normal file
88
NodeEditorPro/examples/halcon/HRegionFillUpShapeModel.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HRegionFillUpShapeModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionFillUpShapeModel();
|
||||
virtual ~HRegionFillUpShapeModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("填充区域");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("填充区域");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("填充区域");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_widget; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
QJsonObject save() const override;
|
||||
|
||||
void restore(QJsonObject const&) override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
QString m_feature;
|
||||
double m_minval = 0.0;
|
||||
double m_maxval = 100.0;
|
||||
std::shared_ptr<HRegionData> m_hRegion;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
QWidget* m_widget;
|
||||
QVBoxLayout* m_host;
|
||||
QComboBox* m_combo_feature;
|
||||
QLineEdit* m_minvalEdit;
|
||||
QLineEdit* m_maxvalEdit;
|
||||
};
|
126
NodeEditorPro/examples/halcon/HRegionOpenCircleModel.cpp
Normal file
126
NodeEditorPro/examples/halcon/HRegionOpenCircleModel.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "HRegionOpenCircleModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionOpenCircleModel::HRegionOpenCircleModel()
|
||||
{
|
||||
m_hRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
m_maxvalEdit = new QLineEdit();
|
||||
m_maxvalEdit->setFixedWidth(80);
|
||||
m_maxvalEdit->setText("9.0");
|
||||
|
||||
connect(m_maxvalEdit, &QLineEdit::textChanged, [=]()
|
||||
{
|
||||
m_maxval = m_maxvalEdit->text().toDouble();
|
||||
RunTask();
|
||||
});
|
||||
}
|
||||
|
||||
bool HRegionOpenCircleModel::RunTask()
|
||||
{
|
||||
Q_EMIT computingStarted();
|
||||
PortIndex const outPortIndex = 0;
|
||||
try
|
||||
{
|
||||
HalconCpp::OpeningCircle(
|
||||
*m_hRegion->hRegion(),
|
||||
m_result->hRegion(),
|
||||
m_maxval);
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
Q_EMIT computingFinished();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int HRegionOpenCircleModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionOpenCircleModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionOpenCircleModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HRegionOpenCircleModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
|
||||
result.insert("m_maxval", m_maxval);
|
||||
return result;
|
||||
}
|
||||
|
||||
void HRegionOpenCircleModel::restore(QJsonObject const& json_values)
|
||||
{
|
||||
NodeDataModel::restore(json_values);
|
||||
m_maxval = json_values.value("m_maxval").toDouble();
|
||||
m_maxvalEdit->setText(QString::number(m_maxval));
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionOpenCircleModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionOpenCircleModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hImageData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hImageData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_hRegion->setHRegion(*hImageData->hRegion());
|
||||
m_result->setSize(hImageData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionOpenCircleModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::static_pointer_cast<HRegionData>(m_result);
|
||||
}
|
82
NodeEditorPro/examples/halcon/HRegionOpenCircleModel.hpp
Normal file
82
NodeEditorPro/examples/halcon/HRegionOpenCircleModel.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HRegionOpenCircleModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionOpenCircleModel();
|
||||
virtual ~HRegionOpenCircleModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("开放圆");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("开放圆");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("开放圆");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_maxvalEdit; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
QJsonObject save() const override;
|
||||
|
||||
void restore(QJsonObject const&) override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("图片输入未连接!");
|
||||
private:
|
||||
double m_maxval = 100.0;
|
||||
std::shared_ptr<HRegionData> m_hRegion;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
QLineEdit* m_maxvalEdit;
|
||||
};
|
192
NodeEditorPro/examples/halcon/HRegionSelectModel.cpp
Normal file
192
NodeEditorPro/examples/halcon/HRegionSelectModel.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
#include "HRegionSelectModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionSelectModel::HRegionSelectModel()
|
||||
{
|
||||
m_widget = new QWidget();
|
||||
m_widget->setAttribute(Qt::WA_NoSystemBackground);
|
||||
m_widget->setFixedSize(150, 140);
|
||||
m_minValue = new QLineEdit(m_widget);
|
||||
m_maxValue = new QLineEdit(m_widget);
|
||||
combo_feature = new QComboBox(m_widget);
|
||||
combo_operation = new QComboBox(m_widget);
|
||||
m_minValue->resize(120, 25);
|
||||
m_maxValue->resize(120, 25);
|
||||
combo_feature->move(0, 0);
|
||||
combo_operation->move(0, 35);
|
||||
m_minValue->move(0, 70);
|
||||
m_maxValue->move(0, 105);
|
||||
|
||||
m_minValue->setText("0");
|
||||
m_maxValue->setText("99999");
|
||||
|
||||
combo_feature->addItem("area");
|
||||
combo_feature->addItem("row");
|
||||
combo_feature->addItem("column");
|
||||
combo_feature->addItem("width");
|
||||
combo_feature->addItem("height");
|
||||
combo_feature->addItem("circularity");
|
||||
combo_feature->addItem("compactness");
|
||||
combo_feature->addItem("contlength");
|
||||
combo_feature->addItem("convexity");
|
||||
combo_feature->addItem("rectangularity");
|
||||
combo_feature->addItem("inner_width");
|
||||
combo_feature->addItem("inner_height");
|
||||
combo_feature->addItem("roundness");
|
||||
|
||||
combo_operation->addItem("and");
|
||||
combo_operation->addItem("or");
|
||||
|
||||
m_InRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
connect(m_minValue, &QLineEdit::textEdited, [=]()
|
||||
{
|
||||
RunTask();
|
||||
});
|
||||
connect(m_maxValue, &QLineEdit::textEdited, [=]()
|
||||
{
|
||||
RunTask();
|
||||
});
|
||||
connect(combo_feature, &QComboBox::currentTextChanged, [=]()
|
||||
{
|
||||
RunTask();
|
||||
});
|
||||
connect(combo_operation, &QComboBox::currentTextChanged, [=]()
|
||||
{
|
||||
RunTask();
|
||||
});
|
||||
}
|
||||
|
||||
bool HRegionSelectModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
if (m_InRegion->hRegion() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
minVal = m_minValue->text().toDouble();
|
||||
maxVal = m_maxValue->text().toDouble();
|
||||
m_cur_feature = combo_feature->currentText();
|
||||
m_cur_operation = combo_operation->currentText();
|
||||
m_result->setHRegion(m_InRegion->hRegion()->SelectShape(
|
||||
combo_feature->currentText().toStdString().c_str(),
|
||||
combo_operation->currentText().toStdString().c_str(),
|
||||
minVal, maxVal
|
||||
));
|
||||
m_result->setSize(m_InRegion->getSize());
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HRegionSelectModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int HRegionSelectModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionSelectModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionSelectModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HRegionSelectModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
result.insert("m_minValue", m_minValue->text());
|
||||
result.insert("m_maxValue", m_maxValue->text());
|
||||
return result;
|
||||
}
|
||||
|
||||
void HRegionSelectModel::restore(QJsonObject const& p)
|
||||
{
|
||||
m_minValue->setText(p["m_minValue"].toString("0"));
|
||||
m_maxValue->setText(p["m_maxValue"].toString("99999"));
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionSelectModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionSelectModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hRegionData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hRegionData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_InRegion->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegion->setSize(hRegionData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionSelectModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
}
|
90
NodeEditorPro/examples/halcon/HRegionSelectModel.hpp
Normal file
90
NodeEditorPro/examples/halcon/HRegionSelectModel.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HRegionSelectModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionSelectModel();
|
||||
virtual ~HRegionSelectModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("选择区域");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("选择区域");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("选择区域");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_widget; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
QJsonObject save() const override;
|
||||
|
||||
void restore(QJsonObject const&) override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("区域输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HRegionData> m_InRegion;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
QComboBox* combo_feature;
|
||||
QComboBox* combo_operation;
|
||||
QLineEdit* m_minValue;
|
||||
QLineEdit* m_maxValue;
|
||||
QWidget* m_widget;
|
||||
QString m_cur_feature;
|
||||
QString m_cur_operation;
|
||||
int minVal;
|
||||
int maxVal;
|
||||
};
|
161
NodeEditorPro/examples/halcon/HRegionSelectShapeStdModel.cpp
Normal file
161
NodeEditorPro/examples/halcon/HRegionSelectShapeStdModel.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#include "HRegionSelectShapeStdModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionSelectShapeStdModel::HRegionSelectShapeStdModel()
|
||||
{
|
||||
m_widget = new QWidget();
|
||||
m_widget->setAttribute(Qt::WA_NoSystemBackground);
|
||||
m_widget->setFixedSize(120, 80);
|
||||
m_cur_feature = "rectangle1";
|
||||
m_percent = 90;
|
||||
combo_feature = new QComboBox(m_widget);
|
||||
m_percentEdit = new QLineEdit(m_widget);
|
||||
combo_feature->move(0, 10);
|
||||
m_percentEdit->move(0, 60);
|
||||
combo_feature->addItem("max_area");
|
||||
combo_feature->addItem("rectangle1");
|
||||
combo_feature->addItem("rectangle2");
|
||||
m_percentEdit->setText("90.0");
|
||||
m_InRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
connect(combo_feature, &QComboBox::currentTextChanged, [=]()
|
||||
{
|
||||
m_cur_feature = combo_feature->currentText();
|
||||
RunTask();
|
||||
});
|
||||
connect(m_percentEdit, &QLineEdit::textEdited, this, [=]()
|
||||
{
|
||||
m_percent = m_percentEdit->text().toDouble();
|
||||
RunTask();
|
||||
});
|
||||
}
|
||||
|
||||
bool HRegionSelectShapeStdModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
if (m_InRegion->hRegion() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
HalconCpp::SelectShapeStd(
|
||||
*m_InRegion->hRegion(),
|
||||
m_result->hRegion(),
|
||||
m_cur_feature.toStdString().c_str(),
|
||||
m_percent);
|
||||
|
||||
m_result->setSize(m_InRegion->getSize());
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HRegionSelectShapeStdModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int HRegionSelectShapeStdModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionSelectShapeStdModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionSelectShapeStdModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HRegionSelectShapeStdModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
result.insert("m_cur_feature", combo_feature->currentText());
|
||||
result.insert("m_percent", m_percent);
|
||||
return result;
|
||||
}
|
||||
|
||||
void HRegionSelectShapeStdModel::restore(QJsonObject const& p)
|
||||
{
|
||||
combo_feature->setCurrentText(p["m_cur_feature"].toString("rectangle1"));
|
||||
m_percent = p.value("m_percent").toDouble(90);
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionSelectShapeStdModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionSelectShapeStdModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hRegionData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hRegionData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_InRegion->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegion->setSize(hRegionData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionSelectShapeStdModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
}
|
86
NodeEditorPro/examples/halcon/HRegionSelectShapeStdModel.hpp
Normal file
86
NodeEditorPro/examples/halcon/HRegionSelectShapeStdModel.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon shapeTrans节点
|
||||
*/
|
||||
class HRegionSelectShapeStdModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionSelectShapeStdModel();
|
||||
virtual ~HRegionSelectShapeStdModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("选择形状");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("选择形状");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("选择形状");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_widget; }
|
||||
|
||||
bool
|
||||
resizable() const override { return false; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
QJsonObject save() const override;
|
||||
|
||||
void restore(QJsonObject const&) override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("区域输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HRegionData> m_InRegion;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
QLineEdit* m_percentEdit;
|
||||
QComboBox* combo_feature;
|
||||
QWidget* m_widget;
|
||||
QString m_cur_feature;
|
||||
double m_percent;
|
||||
};
|
154
NodeEditorPro/examples/halcon/HRegionShapeTransModel.cpp
Normal file
154
NodeEditorPro/examples/halcon/HRegionShapeTransModel.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
#include "HRegionShapeTransModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionShapeTransModel::HRegionShapeTransModel()
|
||||
{
|
||||
m_widget = new QWidget();
|
||||
m_widget->setAttribute(Qt::WA_NoSystemBackground);
|
||||
m_widget->setFixedSize(150, 50);
|
||||
combo_feature = new QComboBox(m_widget);
|
||||
|
||||
combo_feature->move(0, 10);
|
||||
|
||||
combo_feature->addItem("convex");
|
||||
combo_feature->addItem("ellipse");
|
||||
combo_feature->addItem("outer_circle");
|
||||
combo_feature->addItem("inner_circle");
|
||||
combo_feature->addItem("rectangle1");
|
||||
combo_feature->addItem("rectangle2");
|
||||
combo_feature->addItem("inner_rectangle1");
|
||||
combo_feature->addItem("inner_rectangle2");
|
||||
|
||||
m_InRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
connect(combo_feature, &QComboBox::currentTextChanged, [=]()
|
||||
{
|
||||
RunTask();
|
||||
});
|
||||
}
|
||||
|
||||
bool HRegionShapeTransModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
if (m_InRegion->hRegion() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
m_cur_feature = combo_feature->currentText();
|
||||
m_result->setHRegion(m_InRegion->hRegion()->ShapeTrans(
|
||||
combo_feature->currentText().toStdString().c_str()
|
||||
));
|
||||
m_result->setSize(m_InRegion->getSize());
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HRegionShapeTransModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int HRegionShapeTransModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionShapeTransModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionShapeTransModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
QJsonObject HRegionShapeTransModel::save() const
|
||||
{
|
||||
QJsonObject result = NodeDataModel::save();
|
||||
result.insert("m_cur_feature", combo_feature->currentText());
|
||||
return result;
|
||||
}
|
||||
|
||||
void HRegionShapeTransModel::restore(QJsonObject const& p)
|
||||
{
|
||||
combo_feature->setCurrentText(p["m_cur_feature"].toString("rectangle1"));
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionShapeTransModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionShapeTransModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hRegionData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hRegionData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_InRegion->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegion->setSize(hRegionData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionShapeTransModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
}
|
85
NodeEditorPro/examples/halcon/HRegionShapeTransModel.hpp
Normal file
85
NodeEditorPro/examples/halcon/HRegionShapeTransModel.hpp
Normal file
@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon shapeTrans节点
|
||||
*/
|
||||
class HRegionShapeTransModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionShapeTransModel();
|
||||
virtual ~HRegionShapeTransModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("仿形变换");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("仿形变换");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("仿形变换");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return m_widget; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
|
||||
QJsonObject save() const override;
|
||||
|
||||
void restore(QJsonObject const&) override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("区域输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HRegionData> m_InRegion;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
QComboBox* combo_feature;
|
||||
QWidget* m_widget;
|
||||
QString m_cur_feature;
|
||||
|
||||
};
|
152
NodeEditorPro/examples/halcon/HRegionUnionModel.cpp
Normal file
152
NodeEditorPro/examples/halcon/HRegionUnionModel.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
#include "HRegionUnionModel.hpp"
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
|
||||
using namespace HalconCpp;
|
||||
|
||||
HRegionUnionModel::HRegionUnionModel()
|
||||
{
|
||||
m_InRegion = std::make_shared<HRegionData>();
|
||||
m_result = std::make_shared<HRegionData>();
|
||||
|
||||
}
|
||||
|
||||
QString HRegionUnionModel::portCaption(PortType port, PortIndex port_index) const
|
||||
{
|
||||
if (port == PortType::In)
|
||||
{
|
||||
switch (port_index)
|
||||
{
|
||||
case 0:
|
||||
return "Ori";
|
||||
break;
|
||||
case 1:
|
||||
return "Add";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (port == PortType::Out)
|
||||
{
|
||||
switch (port_index)
|
||||
{
|
||||
case 0:
|
||||
return "Res";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NodeDataModel::portCaption(port, port_index);
|
||||
}
|
||||
|
||||
bool HRegionUnionModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
if (m_InRegion->hRegion() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
HalconCpp::Union2(*m_InRegion->hRegion(), *m_InRegionAdd->hRegion(), m_result->hRegion());
|
||||
|
||||
m_result->setSize(m_InRegion->getSize());
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("缺失或运行失败!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HRegionUnionModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int HRegionUnionModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 2;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeValidationState HRegionUnionModel::validationState() const
|
||||
{
|
||||
return modelValidationState;
|
||||
}
|
||||
|
||||
QString HRegionUnionModel::validationMessage() const
|
||||
{
|
||||
return modelValidationError;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
HRegionUnionModel::dataType(PortType, PortIndex) const
|
||||
{
|
||||
return HRegionData().type();
|
||||
}
|
||||
|
||||
void HRegionUnionModel::
|
||||
setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
auto hRegionData =
|
||||
std::dynamic_pointer_cast<HRegionData>(data);
|
||||
if (hRegionData == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
m_InRegion->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegion->setSize(hRegionData->getSize());
|
||||
break;
|
||||
case 1:
|
||||
m_InRegionAdd->setHRegion(*hRegionData->hRegion());
|
||||
m_InRegionAdd->setSize(hRegionData->getSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
HRegionUnionModel::
|
||||
outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<HRegionData>(m_result);
|
||||
}
|
78
NodeEditorPro/examples/halcon/HRegionUnionModel.hpp
Normal file
78
NodeEditorPro/examples/halcon/HRegionUnionModel.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include <QLineEdit>
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "halconcpp/HalconCpp.h"
|
||||
#include "HImageData.hpp"
|
||||
#include "HRegionData.hpp"
|
||||
#include "HImageViewWidget.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using namespace HalconCpp;
|
||||
/**
|
||||
* \brief halcon 图像rgb2gray节点
|
||||
*/
|
||||
class HRegionUnionModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HRegionUnionModel();
|
||||
virtual ~HRegionUnionModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override
|
||||
{
|
||||
return QStringLiteral("联合区域");
|
||||
}
|
||||
QString name() const override
|
||||
{
|
||||
return QStringLiteral("联合区域");
|
||||
}
|
||||
virtual QString modelName() const
|
||||
{
|
||||
return QStringLiteral("联合区域");
|
||||
}
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return nullptr; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
NodeValidationState
|
||||
validationState() const override;
|
||||
QString
|
||||
validationMessage() const override;
|
||||
bool portCaptionVisible(PortType, PortIndex) const override { return true; }
|
||||
QString portCaption(PortType, PortIndex) const override;
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("区域输入未连接!");
|
||||
private:
|
||||
std::shared_ptr<HRegionData> m_InRegion;
|
||||
std::shared_ptr<HRegionData> m_InRegionAdd;
|
||||
std::shared_ptr<HRegionData> m_result;
|
||||
};
|
19
NodeEditorPro/examples/halcon/HalconNodes.hpp
Normal file
19
NodeEditorPro/examples/halcon/HalconNodes.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
//halcon nodes
|
||||
#include "halcon/HImageLoaderModel.hpp"
|
||||
#include "halcon/HImageFolderModel.hpp"
|
||||
#include "halcon/HImageShowModel.hpp"
|
||||
#include "halcon/HImageRGB2GrayModel.hpp"
|
||||
#include "halcon/HImageThresholdModel.hpp"
|
||||
#include "halcon/HImageSplitChanelModel.hpp"
|
||||
#include "halcon/HRegionSelectModel.hpp"
|
||||
#include "halcon/HRegionConnectModel.hpp"
|
||||
#include "halcon/HRegionShapeTransModel.hpp"
|
||||
#include "halcon/HImageReduceDomainModel.hpp"
|
||||
#include "halcon/HRegionFillUpShapeModel.hpp"
|
||||
#include "halcon/HRegionOpenCircleModel.hpp"
|
||||
#include "halcon/HRegionUnionModel.hpp"
|
||||
#include "halcon/HRegionDifferenceModel.hpp"
|
||||
#include "halcon/HRegionSelectShapeStdModel.hpp"
|
||||
#include "halcon/HImageDLSegmentModel.hpp"
|
97
NodeEditorPro/examples/images/ImageLoaderModel.cpp
Normal file
97
NodeEditorPro/examples/images/ImageLoaderModel.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include "ImageLoaderModel.hpp"
|
||||
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
ImageLoaderModel::
|
||||
ImageLoaderModel()
|
||||
: _label(new QLabel(QStringLiteral("点击加载图片!")))
|
||||
{
|
||||
//_label->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
QFont f = _label->font();
|
||||
f.setBold(true);
|
||||
f.setItalic(true);
|
||||
|
||||
_label->setFont(f);
|
||||
|
||||
_label->setFixedSize(200, 200);
|
||||
|
||||
_label->installEventFilter(this);
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
ImageLoaderModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
ImageLoaderModel::
|
||||
eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (object == _label)
|
||||
{
|
||||
int w = _label->width();
|
||||
int h = _label->height();
|
||||
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
|
||||
QString fileName =
|
||||
QFileDialog::getOpenFileName(nullptr,
|
||||
tr("Open Image"),
|
||||
QDir::homePath(),
|
||||
tr("Image Files (*.png *.jpg *.bmp)"));
|
||||
|
||||
_pixmap = QPixmap(fileName);
|
||||
|
||||
_label->setPixmap(_pixmap.scaled(w, h, Qt::KeepAspectRatio));
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (event->type() == QEvent::Resize)
|
||||
{
|
||||
if (!_pixmap.isNull())
|
||||
_label->setPixmap(_pixmap.scaled(w, h, Qt::KeepAspectRatio));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
NodeDataType
|
||||
ImageLoaderModel::
|
||||
dataType(PortType, PortIndex) const
|
||||
{
|
||||
return PixmapData().type();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
ImageLoaderModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return std::make_shared<PixmapData>(_pixmap);
|
||||
}
|
80
NodeEditorPro/examples/images/ImageLoaderModel.hpp
Normal file
80
NodeEditorPro/examples/images/ImageLoaderModel.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "PixmapData.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class ImageLoaderModel : public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ImageLoaderModel();
|
||||
|
||||
virtual
|
||||
~ImageLoaderModel() {}
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("QPixmap输入");
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override { return QStringLiteral("QPixmap输入"); }
|
||||
|
||||
public:
|
||||
|
||||
virtual QString
|
||||
modelName() const
|
||||
{
|
||||
return QStringLiteral("QPixmap输入");
|
||||
}
|
||||
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData>, int) override
|
||||
{ }
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return _label; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
|
||||
protected:
|
||||
|
||||
bool
|
||||
eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
private:
|
||||
|
||||
QLabel* _label;
|
||||
|
||||
QPixmap _pixmap;
|
||||
};
|
110
NodeEditorPro/examples/images/ImageShowModel.cpp
Normal file
110
NodeEditorPro/examples/images/ImageShowModel.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "ImageShowModel.hpp"
|
||||
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
#include "DataModelRegistry.hpp"
|
||||
|
||||
#include "PixmapData.hpp"
|
||||
|
||||
ImageShowModel::
|
||||
ImageShowModel()
|
||||
: _label(new QLabel("Image will appear here"))
|
||||
{
|
||||
_label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
|
||||
|
||||
QFont f = _label->font();
|
||||
f.setBold(true);
|
||||
f.setItalic(true);
|
||||
|
||||
_label->setFont(f);
|
||||
|
||||
_label->setFixedSize(200, 200);
|
||||
|
||||
_label->installEventFilter(this);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ImageShowModel::
|
||||
nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ImageShowModel::
|
||||
eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (object == _label)
|
||||
{
|
||||
int w = _label->width();
|
||||
int h = _label->height();
|
||||
|
||||
if (event->type() == QEvent::Resize)
|
||||
{
|
||||
auto d = std::dynamic_pointer_cast<PixmapData>(_nodeData);
|
||||
if (d)
|
||||
{
|
||||
_label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NodeDataType
|
||||
ImageShowModel::
|
||||
dataType(PortType, PortIndex) const
|
||||
{
|
||||
return PixmapData().type();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
ImageShowModel::
|
||||
outData(PortIndex)
|
||||
{
|
||||
return _nodeData;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ImageShowModel::
|
||||
setInData(std::shared_ptr<NodeData> nodeData, PortIndex)
|
||||
{
|
||||
_nodeData = nodeData;
|
||||
|
||||
if (_nodeData)
|
||||
{
|
||||
auto d = std::dynamic_pointer_cast<PixmapData>(_nodeData);
|
||||
|
||||
int w = _label->width();
|
||||
int h = _label->height();
|
||||
|
||||
_label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio));
|
||||
}
|
||||
else
|
||||
{
|
||||
_label->setPixmap(QPixmap());
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
}
|
80
NodeEditorPro/examples/images/ImageShowModel.hpp
Normal file
80
NodeEditorPro/examples/images/ImageShowModel.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
/// The model dictates the number of inputs and outputs for the Node.
|
||||
/// In this example it has no logic.
|
||||
class ImageShowModel : public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ImageShowModel();
|
||||
|
||||
virtual
|
||||
~ImageShowModel() {}
|
||||
|
||||
public:
|
||||
|
||||
QString
|
||||
caption() const override
|
||||
{
|
||||
return QStringLiteral("QPixmap 显示");
|
||||
}
|
||||
|
||||
QString
|
||||
name() const override
|
||||
{
|
||||
return QStringLiteral("QPixmap显示节点");
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual QString
|
||||
modelName() const
|
||||
{
|
||||
return QStringLiteral("QPixmap显示");
|
||||
}
|
||||
|
||||
unsigned int
|
||||
nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType
|
||||
dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
std::shared_ptr<NodeData>
|
||||
outData(PortIndex port) override;
|
||||
|
||||
void
|
||||
setInData(std::shared_ptr<NodeData> nodeData, PortIndex port) override;
|
||||
|
||||
QWidget*
|
||||
embeddedWidget() override { return _label; }
|
||||
|
||||
bool
|
||||
resizable() const override { return true; }
|
||||
|
||||
protected:
|
||||
|
||||
bool
|
||||
eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
private:
|
||||
|
||||
QLabel* _label;
|
||||
|
||||
std::shared_ptr<NodeData> _nodeData;
|
||||
};
|
35
NodeEditorPro/examples/images/PixmapData.hpp
Normal file
35
NodeEditorPro/examples/images/PixmapData.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
|
||||
/// The class can potentially incapsulate any user data which
|
||||
/// need to be transferred within the Node Editor graph
|
||||
class PixmapData : public NodeData
|
||||
{
|
||||
public:
|
||||
|
||||
PixmapData() {}
|
||||
|
||||
PixmapData(QPixmap const& pixmap)
|
||||
: _pixmap(pixmap)
|
||||
{}
|
||||
|
||||
NodeDataType
|
||||
type() const override
|
||||
{
|
||||
// id name
|
||||
return { "pixmap", "QPixmap" };
|
||||
}
|
||||
|
||||
QPixmap
|
||||
pixmap() const { return _pixmap; }
|
||||
|
||||
private:
|
||||
|
||||
QPixmap _pixmap{};
|
||||
};
|
55
NodeEditorPro/examples/images/VisionFlowWidget.cpp
Normal file
55
NodeEditorPro/examples/images/VisionFlowWidget.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "VisionFlowWidget.hpp"
|
||||
|
||||
VisionFlowWidget::VisionFlowWidget(QWidget* parent)
|
||||
{
|
||||
main_layout = new QVBoxLayout();
|
||||
header_layout = new QHBoxLayout();
|
||||
btn_load_scheme = new QPushButton("Load");
|
||||
btn_save_scheme = new QPushButton("Save");
|
||||
btn_clear_scene = new QPushButton("Clear");
|
||||
btn_test = new QPushButton("test");
|
||||
header_layout->setAlignment(Qt::AlignLeft);
|
||||
btn_load_scheme->setFixedWidth(120);
|
||||
btn_save_scheme->setFixedWidth(120);
|
||||
btn_clear_scene->setFixedWidth(120);
|
||||
this->setLayout(main_layout);
|
||||
main_layout->addLayout(header_layout);
|
||||
header_layout->addWidget(btn_load_scheme);
|
||||
header_layout->addWidget(btn_save_scheme);
|
||||
header_layout->addWidget(btn_clear_scene);
|
||||
header_layout->addWidget(btn_test);
|
||||
header_layout->setContentsMargins(0, 0, 0, 0);
|
||||
main_layout->setContentsMargins(1, 1, 1, 1);
|
||||
main_layout->setSpacing(1);
|
||||
m_scene = new FlowScene(registerDataModels());
|
||||
m_view = new FlowView(m_scene);
|
||||
main_layout->addWidget(m_view);
|
||||
this->setWindowTitle(QStringLiteral("节点编辑器"));
|
||||
this->resize(1280, 720);
|
||||
setConnection();
|
||||
}
|
||||
|
||||
VisionFlowWidget::~VisionFlowWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void VisionFlowWidget::setConnection()
|
||||
{
|
||||
connect(btn_load_scheme, &QPushButton::clicked, [=]()
|
||||
{
|
||||
m_scene->load();
|
||||
});
|
||||
connect(btn_save_scheme, &QPushButton::clicked, [=]()
|
||||
{
|
||||
m_scene->save();
|
||||
});
|
||||
connect(btn_clear_scene, &QPushButton::clicked, [=]()
|
||||
{
|
||||
m_scene->clearScene();
|
||||
});
|
||||
connect(btn_test, &QPushButton::clicked, [=]()
|
||||
{
|
||||
DrawShapeView::getInst()->show();
|
||||
});
|
||||
}
|
95
NodeEditorPro/examples/images/VisionFlowWidget.hpp
Normal file
95
NodeEditorPro/examples/images/VisionFlowWidget.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include "NodeData.hpp"
|
||||
#include "FlowScene.hpp"
|
||||
#include "FlowView.hpp"
|
||||
#include <QString>
|
||||
#include <QStringLiteral>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QIcon>
|
||||
#include <QImage>
|
||||
|
||||
#include "ImageShowModel.hpp"
|
||||
#include "ImageLoaderModel.hpp"
|
||||
#include "DrawShapeView.hpp"
|
||||
#include "halcon/HalconNodes.hpp"
|
||||
#include "calculator/MathNodes.hpp"
|
||||
|
||||
//#include "opcv/CvImageLoaderModel.h"
|
||||
//#include "opcv/CvImageShowModel.h"
|
||||
#include "opcv/MoudleOpencvNodes.h"
|
||||
|
||||
using QtNodes::DataModelRegistry;
|
||||
using QtNodes::FlowScene;
|
||||
using QtNodes::FlowView;
|
||||
|
||||
|
||||
class VisionFlowWidget :public QWidget
|
||||
{
|
||||
public:
|
||||
VisionFlowWidget(QWidget* parent = Q_NULLPTR);
|
||||
virtual ~VisionFlowWidget();
|
||||
private:
|
||||
QVBoxLayout* main_layout;
|
||||
QHBoxLayout* header_layout;
|
||||
QPushButton* btn_load_scheme;
|
||||
QPushButton* btn_save_scheme;
|
||||
QPushButton* btn_clear_scene;
|
||||
QPushButton* btn_test;
|
||||
FlowScene* m_scene;
|
||||
FlowView* m_view;
|
||||
//DrawShapeView* m_draw_shape_view;
|
||||
private:
|
||||
void setConnection();
|
||||
};
|
||||
|
||||
static std::shared_ptr<DataModelRegistry> registerDataModels()
|
||||
{
|
||||
QString numberNodeType = QStringLiteral("数学操作");
|
||||
QString halconImageNodeType = QStringLiteral("Halcon图像操作");
|
||||
QString getHalconImageNodeType = QStringLiteral("获取Halcon图像");
|
||||
QString dlNodeType = QStringLiteral("深度学习");
|
||||
QString matchNodeType = QStringLiteral("模板匹配");
|
||||
|
||||
QString getOpencvImageNodeType = QStringLiteral("00.获取OpenCV图像");
|
||||
QString opencvImageNodeType = QStringLiteral("01.OpenCV图像操作");
|
||||
|
||||
auto ret = std::make_shared<DataModelRegistry>();
|
||||
|
||||
//opencv图像获取
|
||||
ret->registerModel<CvImageLoaderModel>(getOpencvImageNodeType);
|
||||
|
||||
//opencv图像操作
|
||||
ret->registerModel<CvImageShowModel>(opencvImageNodeType);
|
||||
ret->registerModel<CvGraphicsShowModel>(opencvImageNodeType);
|
||||
ret->registerModel<CvImageRGB2GrayModel>(opencvImageNodeType);
|
||||
|
||||
//数学节点
|
||||
ret->registerModel<AdditionModel>(numberNodeType);
|
||||
ret->registerModel<DivisionModel>(numberNodeType);
|
||||
ret->registerModel<MultiplicationModel>(numberNodeType);
|
||||
ret->registerModel<SubtractionModel>(numberNodeType);
|
||||
ret->registerModel<NumberSourceDataModel>(numberNodeType);
|
||||
ret->registerModel<NumberDisplayDataModel>(numberNodeType);
|
||||
|
||||
//图像获取
|
||||
ret->registerModel<HImageLoaderModel>(getHalconImageNodeType);
|
||||
//ret->registerModel<HImageFolderModel>(getHalconImageNodeType);
|
||||
//图像操作
|
||||
ret->registerModel<HImageShowModel>(halconImageNodeType);
|
||||
ret->registerModel<HImageRGB2GrayModel>(halconImageNodeType);
|
||||
ret->registerModel<HImageSplitChanelModel>(halconImageNodeType);
|
||||
ret->registerModel<HImageThresholdModel>(halconImageNodeType);
|
||||
//ret->registerModel<HRegionSelectModel>(halconImageNodeType);
|
||||
ret->registerModel<HRegionConnectModel>(halconImageNodeType);
|
||||
ret->registerModel<HRegionShapeTransModel>(halconImageNodeType);
|
||||
ret->registerModel<HImageReduceDomainModel>(halconImageNodeType);
|
||||
ret->registerModel<HRegionFillUpShapeModel>(halconImageNodeType);
|
||||
ret->registerModel<HRegionOpenCircleModel>(halconImageNodeType);
|
||||
ret->registerModel<HRegionUnionModel>(halconImageNodeType);
|
||||
ret->registerModel<HRegionDifferenceModel>(halconImageNodeType);
|
||||
ret->registerModel<HRegionSelectShapeStdModel>(halconImageNodeType);
|
||||
ret->registerModel<HImageDLSegmentModel>(halconImageNodeType);
|
||||
|
||||
return ret;
|
||||
}
|
22
NodeEditorPro/examples/images/main.cpp
Normal file
22
NodeEditorPro/examples/images/main.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QStyleFactory>
|
||||
#include "VisionFlowWidget.hpp"
|
||||
|
||||
#include "QBreakpadHandler.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
app.setWindowIcon(QIcon(":/logo.png"));
|
||||
QStyle* style = QStyleFactory::create("Fusion");
|
||||
app.setStyle(style);
|
||||
|
||||
VisionFlowWidget* mainWidget = new VisionFlowWidget();
|
||||
mainWidget->show();
|
||||
|
||||
QBreakpadInstance.setDumpPath("crash");
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
27
NodeEditorPro/examples/opcv/CvAlgorithmTools.cpp
Normal file
27
NodeEditorPro/examples/opcv/CvAlgorithmTools.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "opcv/CvAlgorithmTools.h"
|
||||
|
||||
CvAlgorithmTools::CvAlgorithmTools(QObject* parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CvAlgorithmTools::~CvAlgorithmTools() {}
|
||||
|
||||
void CvAlgorithmTools::CvImageRgb2Gray(cv::Mat rgbImg)
|
||||
{
|
||||
if (rgbImg.empty())
|
||||
return;
|
||||
cv::Mat src, dst;
|
||||
rgbImg.copyTo(src);
|
||||
if (src.channels() == 3)
|
||||
cv::cvtColor(src, dst, CV_BGR2GRAY);
|
||||
else if (src.channels() == 1)
|
||||
dst = src;
|
||||
//qDebug() << "";
|
||||
QThread::sleep(2);
|
||||
qDebug() << "CvAlgorithmTools::CvImageRgb2Gray thread:" << QThread::currentThreadId();
|
||||
|
||||
emit sendCvImageRgb2GrayResult(dst);
|
||||
}
|
||||
|
28
NodeEditorPro/examples/opcv/CvAlgorithmTools.h
Normal file
28
NodeEditorPro/examples/opcv/CvAlgorithmTools.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/imgproc/types_c.h>
|
||||
|
||||
class CvAlgorithmTools : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvAlgorithmTools(QObject* parent = Q_NULLPTR);
|
||||
~CvAlgorithmTools();
|
||||
|
||||
public:
|
||||
void CvImageRgb2Gray(cv::Mat rgbImg);
|
||||
|
||||
|
||||
|
||||
signals:
|
||||
//CvImageRgb2Gray<61><79><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>
|
||||
void sendCvImageRgb2GrayResult(cv::Mat grayImg);
|
||||
|
||||
|
||||
|
||||
};
|
222
NodeEditorPro/examples/opcv/CvGraphicsShowModel.cpp
Normal file
222
NodeEditorPro/examples/opcv/CvGraphicsShowModel.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
#include "opcv/CvGraphicsShowModel.h"
|
||||
|
||||
|
||||
CvGraphicsShowModel::CvGraphicsShowModel()
|
||||
{
|
||||
//mCvImageView = new CvImageViewWidget();
|
||||
//mCvImageView->installEventFilter(this);
|
||||
//mCvImageView->resize(600, 450);
|
||||
//moveToThread(this);
|
||||
|
||||
mCvGraphicsView = new CvGraphicsViewWidget();
|
||||
mCvGraphicsView->setObjectName(QStringLiteral("graphicsView"));
|
||||
mCvGraphicsView->setStyleSheet(
|
||||
"QGraphicsView#graphicsView{ "
|
||||
"background-color:transparent; "
|
||||
"border: 1px solid #F0F2F4; "
|
||||
"border-radius: 4px; }");
|
||||
|
||||
widget = new QWidget();
|
||||
widget->resize(600, 450);
|
||||
widget->setObjectName(QStringLiteral("widget"));
|
||||
widget->setStyleSheet("QWidget#widget { background-color:transparent; }");
|
||||
|
||||
QGridLayout* gridLayout = new QGridLayout(widget);
|
||||
QVBoxLayout* verticalLayout = new QVBoxLayout();
|
||||
QHBoxLayout* horizontalLayout = new QHBoxLayout();
|
||||
horizontalLayout->setDirection(QHBoxLayout::LeftToRight);
|
||||
|
||||
QLabel* label = new QLabel();
|
||||
label->setObjectName(QStringLiteral("label"));
|
||||
label->setText(QStringLiteral("ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:"));
|
||||
label->setStyleSheet("QLabel#label { color:#FFFFFF; }");
|
||||
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
|
||||
label->setSizePolicy(sizePolicy);
|
||||
label->setMaximumSize(QSize(60, 16777215));
|
||||
|
||||
horizontalSlider = new QSlider();
|
||||
horizontalSlider->setObjectName(QString::fromUtf8("horizontalSlider"));
|
||||
horizontalSlider->setMinimum(-14);
|
||||
horizontalSlider->setMaximum(14);
|
||||
horizontalSlider->setPageStep(2);
|
||||
horizontalSlider->setOrientation(Qt::Horizontal);
|
||||
horizontalSlider->setTickPosition(QSlider::TicksBelow);
|
||||
QObject::connect(horizontalSlider, &QSlider::valueChanged, this, &CvGraphicsShowModel::onQSliderValueChanged);
|
||||
|
||||
QSpacerItem* horizontalSpacer = new QSpacerItem(15, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
|
||||
horizontalLayout->addItem(horizontalSpacer);
|
||||
|
||||
horizontalLayout->addWidget(label);
|
||||
horizontalLayout->addWidget(horizontalSlider);
|
||||
|
||||
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
horizontalLayout->addItem(horizontalSpacer);
|
||||
|
||||
verticalLayout->addLayout(horizontalLayout);
|
||||
verticalLayout->addWidget(mCvGraphicsView);
|
||||
|
||||
gridLayout->addLayout(verticalLayout, 0, 0, 1, 1);
|
||||
|
||||
mCvImageData = std::make_shared<CvImageData>();
|
||||
}
|
||||
|
||||
void CvGraphicsShowModel::onQSliderValueChanged(int val)
|
||||
{
|
||||
qDebug() << "onQSliderValueChanged:" << val;
|
||||
qreal scale = 1.0;
|
||||
if (val > 0)
|
||||
{
|
||||
scale = qPow(1.2, val);
|
||||
qreal temp = scale;
|
||||
scale = scale / mScaledNum;
|
||||
mScaledNum = temp;//<2F><><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
|
||||
}
|
||||
else if (val < 0)
|
||||
{
|
||||
scale = qPow(1.2, val);
|
||||
qreal temp = scale;
|
||||
scale = scale / mScaledNum;
|
||||
mScaledNum = temp;//<2F><><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
|
||||
}
|
||||
else if (val == 0)
|
||||
{
|
||||
qreal temp = scale;
|
||||
scale = scale / mScaledNum;
|
||||
mScaledNum = temp;//<2F><><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
|
||||
}
|
||||
mCvGraphicsView->scale(scale, scale);
|
||||
}
|
||||
|
||||
void CvGraphicsShowModel::inputConnectionDeleted(QtNodes::Connection const&)
|
||||
{
|
||||
mCvGraphicsView->setScene(new QGraphicsScene());
|
||||
|
||||
mCvImageData = std::make_shared<CvImageData>();
|
||||
|
||||
PortIndex const outPortIndex = 0;
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>!");
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
}
|
||||
|
||||
unsigned int CvGraphicsShowModel::nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeDataType CvGraphicsShowModel::dataType(PortType portType, PortIndex portIndex) const
|
||||
{
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
return CvImageData().type();
|
||||
break;
|
||||
case 1:
|
||||
return CvImageData().type();
|
||||
break;
|
||||
}
|
||||
return CvImageData().type();
|
||||
}
|
||||
|
||||
bool CvGraphicsShowModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
try
|
||||
{
|
||||
//qDebug() << "11show";
|
||||
//QThread::sleep(3);
|
||||
//QThread* thread = new QThread();
|
||||
//qDebug() << "CvGraphicsShowModel::RunTask thread:" << thread->currentThreadId();
|
||||
|
||||
mCvGraphicsView->showImage(*mCvImageData->CvImage());
|
||||
mCvGraphicsView->scale(0.85, 0.85);
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("ȱʧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CvGraphicsShowModel::setInData(std::shared_ptr<NodeData>data, int)
|
||||
{
|
||||
if (data == nullptr)
|
||||
return;
|
||||
if (data->type() == mCvImageData->type())
|
||||
{
|
||||
auto dataPtr = std::dynamic_pointer_cast<CvImageData>(data);
|
||||
if (dataPtr->CvImage()->empty())
|
||||
return;
|
||||
mCvImageData->setCvImage(*dataPtr->CvImage());
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
bool CvGraphicsShowModel::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::Wheel)
|
||||
{
|
||||
|
||||
}
|
||||
//if (object == mCvGraphicsView->viewport())
|
||||
//{
|
||||
// qDebug() << event->type();
|
||||
// if (event->type() == QEvent::Wheel || event->type() == QEvent::GraphicsSceneWheel)
|
||||
// {
|
||||
// QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
|
||||
// qreal qrTmp = 1.0;
|
||||
// if (mScaledFactor < 0.01 || mScaledFactor > 2000)
|
||||
// return false;
|
||||
// if (wheelEvent->delta() > 0)
|
||||
// {
|
||||
// qrTmp = 1.2;
|
||||
// mCvGraphicsView->scale(qrTmp, qrTmp);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// qrTmp = 1.0 / 1.2;
|
||||
// mCvGraphicsView->scale(qrTmp, qrTmp);
|
||||
// }
|
||||
// mScaledFactor = mScaledFactor * qrTmp; //<2F><><EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD>
|
||||
// qDebug() << "GraphicsSceneWheel";
|
||||
// return true;
|
||||
// }
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData> CvGraphicsShowModel::outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<CvImageData>(mCvImageData);
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<CvImageData>(mCvImageData);
|
||||
}
|
||||
|
86
NodeEditorPro/examples/opcv/CvGraphicsShowModel.h
Normal file
86
NodeEditorPro/examples/opcv/CvGraphicsShowModel.h
Normal file
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include <QtWidgets/QGraphicsView>
|
||||
//#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QSlider>
|
||||
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
#include "Connection.hpp"
|
||||
|
||||
#include "opcv/CvImageData.h"
|
||||
#include "opcv/CvGraphicsViewWidget.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
using QtNodes::Connection;
|
||||
|
||||
class CvGraphicsShowModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CvGraphicsShowModel();
|
||||
virtual ~CvGraphicsShowModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override { return QStringLiteral("cvͼ<EFBFBD><EFBFBD>Graphics<EFBFBD><EFBFBD>ʾ"); }
|
||||
QString name() const override { return QStringLiteral("cvͼ<EFBFBD><EFBFBD>Graphics<EFBFBD><EFBFBD>ʾ"); }
|
||||
virtual QString modelName() const { return QStringLiteral("cvͼ<EFBFBD><EFBFBD>Graphics<EFBFBD><EFBFBD>ʾ"); }
|
||||
|
||||
QWidget* embeddedWidget() override { return widget; }
|
||||
//bool resizable() const override { return true; }
|
||||
bool resizable() const override { return false; }
|
||||
|
||||
NodeValidationState validationState() const override { return modelValidationState; }
|
||||
QString validationMessage() const override { return modelValidationError; }
|
||||
|
||||
unsigned int nPorts(PortType portType) const override;
|
||||
NodeDataType dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
|
||||
public Q_SLOTS:
|
||||
void onQSliderValueChanged(int val);
|
||||
|
||||
//void onInputConnectionDeleted();
|
||||
|
||||
void inputConnectionDeleted(QtNodes::Connection const&) override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>!");
|
||||
|
||||
private:
|
||||
qreal mScaledNum = 1.0; //<2F>ӿ<EFBFBD><D3BF><EFBFBD><EFBFBD>ű<EFBFBD><C5B1><EFBFBD>
|
||||
|
||||
QSlider* horizontalSlider;
|
||||
QWidget* widget;
|
||||
CvGraphicsViewWidget* mCvGraphicsView;
|
||||
std::shared_ptr<CvImageData> mCvImageData;
|
||||
|
||||
public:
|
||||
void setInData(std::shared_ptr<NodeData>, int) override;
|
||||
std::shared_ptr<NodeData> outData(PortIndex port) override;
|
||||
|
||||
};
|
94
NodeEditorPro/examples/opcv/CvGraphicsViewWidget.cpp
Normal file
94
NodeEditorPro/examples/opcv/CvGraphicsViewWidget.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "opcv/CvGraphicsViewWidget.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
CvGraphicsViewWidget::CvGraphicsViewWidget(QWidget* parent)
|
||||
:QGraphicsView(parent)
|
||||
{
|
||||
if (parent != Q_NULLPTR)
|
||||
this->setParent(parent);
|
||||
this->setStyleSheet("QGraphicsView{"
|
||||
"background-color:transparent;"
|
||||
"border:none;"
|
||||
"}");
|
||||
mGraphicsScene = new QGraphicsScene();
|
||||
|
||||
setMouseTracking(true);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
setDragMode(QGraphicsView::NoDrag);
|
||||
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
|
||||
}
|
||||
|
||||
void CvGraphicsViewWidget::showImage(cv::Mat const& _cvimg)
|
||||
{
|
||||
QThread* thread =new QThread();
|
||||
qDebug() << "CvGraphicsViewWidget::showImage thread:"<<thread->currentThreadId();
|
||||
|
||||
if (_cvimg.empty())
|
||||
return;
|
||||
//QImage toShow;
|
||||
QPixmap pixmap;
|
||||
|
||||
CvImage2QPixmap(_cvimg, pixmap);
|
||||
|
||||
//QPixmap pixmap = QPixmap::fromImage(toShow);
|
||||
mGraphicsScene->clear();
|
||||
mGraphicsScene->addPixmap(pixmap);
|
||||
|
||||
setScene(mGraphicsScene);
|
||||
}
|
||||
|
||||
//void CvGraphicsViewWidget::paintEvent(QPaintEvent* event)
|
||||
//{
|
||||
// QGraphicsView::paintEvent(event);
|
||||
//}
|
||||
|
||||
void CvGraphicsViewWidget::CvImage2QPixmap(cv::Mat const& fromCv, QPixmap& toPix)
|
||||
{
|
||||
const uchar* pSrc = (const uchar*)fromCv.data;
|
||||
QImage image;
|
||||
if (fromCv.type() == CV_8UC1)
|
||||
{
|
||||
qDebug() << "CV_8UC1";
|
||||
image = QImage(pSrc, fromCv.cols, fromCv.rows, fromCv.step, QImage::Format_Grayscale8);
|
||||
}
|
||||
else if (fromCv.type() == CV_8UC3)
|
||||
{
|
||||
qDebug() << "CV_8UC3";
|
||||
image = QImage(pSrc, fromCv.cols, fromCv.rows, fromCv.step, QImage::Format_RGB888);
|
||||
}
|
||||
else if (fromCv.type() == CV_8UC4)
|
||||
{
|
||||
qDebug() << "CV_8UC4";
|
||||
image = QImage(pSrc, fromCv.cols, fromCv.rows, fromCv.step, QImage::Format_ARGB32);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "ERROR: Mat could not be converted to QImage.";
|
||||
return;
|
||||
}
|
||||
toPix = QPixmap::fromImage(image);
|
||||
}
|
||||
|
||||
bool CvGraphicsViewWidget::QImage2CvImage(QImage& fromQ, cv::Mat& toCv)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//void CvGraphicsViewWidget::wheelEvent(QWheelEvent* ev)
|
||||
//{
|
||||
// qreal qrTmp = 1.0;
|
||||
// if (ev->delta() > 0)
|
||||
// {
|
||||
// qrTmp = 1.2;
|
||||
// this->scale(qrTmp, qrTmp);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// qrTmp = 1.0 / 1.2;
|
||||
// this->scale(qrTmp, qrTmp);
|
||||
// }
|
||||
// mScaledFactor *= qrTmp; //<2F><><EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD>
|
||||
//}
|
43
NodeEditorPro/examples/opcv/CvGraphicsViewWidget.h
Normal file
43
NodeEditorPro/examples/opcv/CvGraphicsViewWidget.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QEvent>
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
//#include <QGraphicsItem>
|
||||
//#include <QPainter>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
class CvGraphicsViewWidget :public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CvGraphicsViewWidget(QWidget* parent = Q_NULLPTR);
|
||||
virtual ~CvGraphicsViewWidget() {}
|
||||
|
||||
public:
|
||||
void showImage(cv::Mat const& _himg);
|
||||
|
||||
static void CvImage2QPixmap(cv::Mat const& fromCv, QPixmap& toPix);
|
||||
static bool QImage2CvImage(QImage& fromQ, cv::Mat& toCv);
|
||||
//static void QPixmapToCvRegion(QPixmap const& _pix, cv::Rect2d& tarImg);
|
||||
|
||||
protected:
|
||||
//void paintEvent(QPaintEvent* event) override;
|
||||
//void wheelEvent(QWheelEvent* ev);
|
||||
|
||||
private:
|
||||
QGraphicsScene* mGraphicsScene;
|
||||
//QGraphicsRectItem* item;
|
||||
|
||||
//QColor penColor = QColor(0, 180, 255);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
||||
//int penWidth = 2;//<2F><><EFBFBD>ʿ<EFBFBD><CABF><EFBFBD>
|
||||
qreal mScaledFactor; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD><C5B1><EFBFBD>
|
||||
|
||||
};
|
40
NodeEditorPro/examples/opcv/CvImageData.h
Normal file
40
NodeEditorPro/examples/opcv/CvImageData.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
|
||||
class CvImageData :public NodeData
|
||||
{
|
||||
public:
|
||||
CvImageData() { mCvImage = cv::Mat(); }
|
||||
CvImageData(cv::Mat inImg)
|
||||
{
|
||||
if (!inImg.empty())
|
||||
mCvImage = inImg;
|
||||
else
|
||||
mCvImage = cv::Mat();
|
||||
}
|
||||
virtual ~CvImageData() {}
|
||||
|
||||
NodeDataType type() const override { return { "CvImage","CvImg" }; }
|
||||
|
||||
bool empty() { return mCvImage.empty(); }
|
||||
|
||||
cv::Mat* CvImage() { return &mCvImage; }
|
||||
|
||||
void setCvImage(cv::Mat const& _img)
|
||||
{
|
||||
if (!_img.empty())
|
||||
mCvImage = _img;
|
||||
else
|
||||
return;
|
||||
}
|
||||
private:
|
||||
cv::Mat mCvImage;
|
||||
|
||||
};
|
94
NodeEditorPro/examples/opcv/CvImageLoaderModel.cpp
Normal file
94
NodeEditorPro/examples/opcv/CvImageLoaderModel.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "opcv/CvImageLoaderModel.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QEvent>
|
||||
#include <QFileDialog>
|
||||
|
||||
CvImageLoaderModel::CvImageLoaderModel()
|
||||
{
|
||||
mCvImageView = new CvImageViewWidget();
|
||||
mCvImageView->installEventFilter(this);
|
||||
mCvImageView->resize(200, 200);
|
||||
mCvImageData = std::make_shared<CvImageData>();
|
||||
}
|
||||
|
||||
unsigned int CvImageLoaderModel::nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeDataType CvImageLoaderModel::dataType(PortType portType, PortIndex portIndex) const
|
||||
{
|
||||
return CvImageData().type();
|
||||
}
|
||||
|
||||
QJsonObject CvImageLoaderModel::save() const
|
||||
{
|
||||
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
void CvImageLoaderModel::restore(QJsonObject const&)
|
||||
{
|
||||
QJsonObject modelJson = NodeDataModel::save();
|
||||
|
||||
}
|
||||
|
||||
void CvImageLoaderModel::loadImage(QString fileName)
|
||||
{
|
||||
if (fileName == "")
|
||||
return;
|
||||
|
||||
cv::Mat tempImg = cv::imread(fileName.toStdString().c_str());
|
||||
mCvImageData->setCvImage(tempImg);
|
||||
mCvImageView->showImage(*mCvImageData->CvImage());
|
||||
}
|
||||
|
||||
bool CvImageLoaderModel::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (object == mCvImageView)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
imageName = QFileDialog::getOpenFileName(nullptr,
|
||||
tr("Open Image"),
|
||||
QDir::homePath(),
|
||||
tr("Image Files(*.png *.jpg *.jpeg *.bmp)"));
|
||||
if (imageName == "")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
loadImage(imageName);
|
||||
|
||||
Q_EMIT dataUpdated(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (event->type() == QEvent::Resize)
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData> CvImageLoaderModel::outData(PortIndex port)
|
||||
{
|
||||
return std::dynamic_pointer_cast<CvImageData>(mCvImageData);
|
||||
}
|
||||
|
59
NodeEditorPro/examples/opcv/CvImageLoaderModel.h
Normal file
59
NodeEditorPro/examples/opcv/CvImageLoaderModel.h
Normal file
@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "opcv/CvImageViewWidget.h"
|
||||
#include "opcv/CvImageData.h"
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
//class CvImageData;
|
||||
//class CvImageViewWidget;
|
||||
|
||||
class CvImageLoaderModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CvImageLoaderModel();
|
||||
virtual ~CvImageLoaderModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override { return QStringLiteral("cv图像输入"); }
|
||||
QString name() const override { return QStringLiteral("cv图像输入"); }
|
||||
virtual QString modelName() const { return QStringLiteral("cv图像输入"); }
|
||||
|
||||
void setInData(std::shared_ptr<NodeData>, int) override { }
|
||||
QWidget* embeddedWidget() override { return mCvImageView; }
|
||||
bool resizable() const override { return false; }
|
||||
|
||||
unsigned int nPorts(PortType portType) const override;
|
||||
NodeDataType dataType(PortType portType, PortIndex portIndex) const override;
|
||||
std::shared_ptr<NodeData> outData(PortIndex port) override;
|
||||
|
||||
QJsonObject save() const override;
|
||||
void restore(QJsonObject const&) override;
|
||||
void loadImage(QString fileName);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
private:
|
||||
QString imageName;
|
||||
CvImageViewWidget* mCvImageView;
|
||||
|
||||
std::shared_ptr<CvImageData> mCvImageData;
|
||||
|
||||
};
|
104
NodeEditorPro/examples/opcv/CvImageRGB2GrayModel.cpp
Normal file
104
NodeEditorPro/examples/opcv/CvImageRGB2GrayModel.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include "opcv/CvImageRGB2GrayModel.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTime>
|
||||
|
||||
CvImageRGB2GrayModel::CvImageRGB2GrayModel()
|
||||
{
|
||||
qRegisterMetaType<cv::Mat>("cv::Mat");
|
||||
mCvImage = std::make_shared<CvImageData>();
|
||||
}
|
||||
|
||||
unsigned int CvImageRGB2GrayModel::nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CvImageRGB2GrayModel::RunTask()
|
||||
{
|
||||
Q_EMIT computingStarted();
|
||||
PortIndex const outPortIndex = 0;
|
||||
|
||||
try
|
||||
{
|
||||
qDebug() << "CvImageRGB2GrayModel::RunTask thread:" << QThread::currentThreadId();
|
||||
|
||||
mAlgoTool = new CvAlgorithmTools();
|
||||
mChildThread = new QThread();
|
||||
mAlgoTool->moveToThread(mChildThread);
|
||||
|
||||
QObject::connect(mChildThread, &QThread::finished, mChildThread, &QObject::deleteLater);
|
||||
QObject::connect(mChildThread, &QThread::finished, mAlgoTool, &QObject::deleteLater);
|
||||
|
||||
QObject::connect(this, &CvImageRGB2GrayModel::SignalCvImageRgb2Gray, mAlgoTool, &CvAlgorithmTools::CvImageRgb2Gray);
|
||||
QObject::connect(mAlgoTool, &CvAlgorithmTools::sendCvImageRgb2GrayResult, this, &CvImageRGB2GrayModel::GetRgb2GrayResult);
|
||||
|
||||
mChildThread->start();
|
||||
|
||||
cv::Mat src;
|
||||
mCvImage->CvImage()->copyTo(src);
|
||||
if (!src.empty())
|
||||
{
|
||||
emit computingStarted();
|
||||
emit SignalCvImageRgb2Gray(src);
|
||||
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("ȱʧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>!");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CvImageRGB2GrayModel::GetRgb2GrayResult(cv::Mat grayImg)
|
||||
{
|
||||
mCvImage->setCvImage(grayImg);
|
||||
|
||||
if (mAlgoTool)
|
||||
{
|
||||
mChildThread->quit();
|
||||
mChildThread->wait();
|
||||
mAlgoTool = Q_NULLPTR;
|
||||
mChildThread = Q_NULLPTR;
|
||||
}
|
||||
|
||||
PortIndex const outPortIndex = 0;
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
Q_EMIT computingFinished();
|
||||
}
|
||||
|
||||
void CvImageRGB2GrayModel::setInData(std::shared_ptr<NodeData>data , int)
|
||||
{
|
||||
if (data == nullptr)
|
||||
return;
|
||||
if (data->type() == mCvImage->type())
|
||||
{
|
||||
auto dataPtr = std::dynamic_pointer_cast<CvImageData>(data);
|
||||
if (dataPtr->CvImage()->empty())
|
||||
return;
|
||||
mCvImage->setCvImage(*dataPtr->CvImage());
|
||||
}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeData> CvImageRGB2GrayModel::outData(PortIndex port)
|
||||
{
|
||||
return std::dynamic_pointer_cast<CvImageData>(mCvImage);
|
||||
}
|
69
NodeEditorPro/examples/opcv/CvImageRGB2GrayModel.h
Normal file
69
NodeEditorPro/examples/opcv/CvImageRGB2GrayModel.h
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QThread>
|
||||
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "opcv/CvImageData.h"
|
||||
#include "opcv/CvAlgorithmTools.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/imgproc/types_c.h>
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
class CvImageRGB2GrayModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvImageRGB2GrayModel();
|
||||
virtual ~CvImageRGB2GrayModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override { return QStringLiteral("cvͼ<EFBFBD><EFBFBD>ת<EFBFBD>Ҷ<EFBFBD>"); }
|
||||
QString name() const override { return QStringLiteral("cvͼ<EFBFBD><EFBFBD>ת<EFBFBD>Ҷ<EFBFBD>"); }
|
||||
virtual QString modelName() const { return QStringLiteral("cvͼ<EFBFBD><EFBFBD>ת<EFBFBD>Ҷ<EFBFBD>"); }
|
||||
|
||||
QWidget* embeddedWidget() override { return Q_NULLPTR; }
|
||||
|
||||
bool resizable() const override { return false; }
|
||||
|
||||
NodeValidationState validationState() const override { return modelValidationState; }
|
||||
QString validationMessage() const override { return modelValidationError; }
|
||||
|
||||
unsigned int nPorts(PortType portType) const override;
|
||||
|
||||
NodeDataType dataType(PortType portType, PortIndex portIndex) const override { return CvImageData().type(); };
|
||||
|
||||
void setInData(std::shared_ptr<NodeData>, int) override;
|
||||
std::shared_ptr<NodeData> outData(PortIndex port) override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
|
||||
signals:
|
||||
void SignalCvImageRgb2Gray(cv::Mat rgbImg);
|
||||
|
||||
public slots:
|
||||
void GetRgb2GrayResult(cv::Mat grayImg);
|
||||
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>!");
|
||||
|
||||
private:
|
||||
CvAlgorithmTools* mAlgoTool = Q_NULLPTR;
|
||||
QThread* mChildThread = Q_NULLPTR;
|
||||
|
||||
std::shared_ptr<CvImageData> mCvImage;
|
||||
};
|
||||
|
128
NodeEditorPro/examples/opcv/CvImageShowModel.cpp
Normal file
128
NodeEditorPro/examples/opcv/CvImageShowModel.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "opcv/CvImageShowModel.h"
|
||||
|
||||
CvImageShowModel::CvImageShowModel()
|
||||
{
|
||||
//moveToThread(this);
|
||||
|
||||
mCvImageView = new CvImageViewWidget();
|
||||
mCvImageView->installEventFilter(this);
|
||||
mCvImageView->resize(200, 200);
|
||||
mCvImageData = std::make_shared<CvImageData>();
|
||||
//m_hRegion = std::make_shared<HRegionData>();
|
||||
}
|
||||
|
||||
void CvImageShowModel::inputConnectionDeleted(QtNodes::Connection const&)
|
||||
{
|
||||
mCvImageView->showImage(cv::Mat());
|
||||
|
||||
mCvImageData = std::make_shared<CvImageData>();
|
||||
|
||||
PortIndex const outPortIndex = 0;
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>!");
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
}
|
||||
|
||||
bool CvImageShowModel::RunTask()
|
||||
{
|
||||
PortIndex const outPortIndex = 0;
|
||||
try
|
||||
{
|
||||
//qDebug() << "22show";
|
||||
//QThread::sleep(3);
|
||||
|
||||
mCvImageView->showImage(*mCvImageData->CvImage());
|
||||
modelValidationState = NodeValidationState::Valid;
|
||||
modelValidationError = QString();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
modelValidationState = NodeValidationState::Warning;
|
||||
modelValidationError = QStringLiteral("ȱʧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>!");
|
||||
}
|
||||
|
||||
Q_EMIT dataUpdated(outPortIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvImageShowModel::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int CvImageShowModel::nPorts(PortType portType) const
|
||||
{
|
||||
unsigned int result = 1;
|
||||
|
||||
switch (portType)
|
||||
{
|
||||
case PortType::In:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case PortType::Out:
|
||||
result = 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeDataType CvImageShowModel::dataType(PortType portType, PortIndex portIndex) const
|
||||
{
|
||||
switch (portIndex)
|
||||
{
|
||||
case 0:
|
||||
return CvImageData().type();
|
||||
break;
|
||||
case 1:
|
||||
return CvImageData().type();
|
||||
break;
|
||||
}
|
||||
return CvImageData().type();
|
||||
}
|
||||
|
||||
void CvImageShowModel::setInData(std::shared_ptr<NodeData> data, int portIndex)
|
||||
{
|
||||
if (data == nullptr)
|
||||
return;
|
||||
if (data->type() == mCvImageData->type())
|
||||
{
|
||||
auto dataPtr = std::dynamic_pointer_cast<CvImageData>(data);
|
||||
if (dataPtr->CvImage()->empty())
|
||||
return;
|
||||
mCvImageData->setCvImage(*dataPtr->CvImage());
|
||||
}
|
||||
//else if (data->type() == m_hRegion->type())
|
||||
//{
|
||||
// auto dataPtr = std::dynamic_pointer_cast<HRegionData>(data);
|
||||
// if (!dataPtr->hRegion()->IsInitialized())
|
||||
// return;
|
||||
// m_hRegion->setHRegion(*dataPtr->hRegion());
|
||||
// m_hRegion->setSize(dataPtr->getSize());
|
||||
// HImage tmpImg = m_hRegion->hRegion()->RegionToBin(255, 0,
|
||||
// m_hRegion->getSize().width(), m_hRegion->getSize().height());
|
||||
// m_hImage->setHImage(tmpImg);
|
||||
//}
|
||||
RunTask();
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<NodeData> CvImageShowModel::outData(PortIndex index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return std::dynamic_pointer_cast<CvImageData>(mCvImageData);
|
||||
break;
|
||||
case 1:
|
||||
return std::dynamic_pointer_cast<CvImageData>(mCvImageData);
|
||||
break;
|
||||
}
|
||||
return std::dynamic_pointer_cast<CvImageData>(mCvImageData);
|
||||
}
|
68
NodeEditorPro/examples/opcv/CvImageShowModel.h
Normal file
68
NodeEditorPro/examples/opcv/CvImageShowModel.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QThread>
|
||||
|
||||
#include "DataModelRegistry.hpp"
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include "opcv/CvImageViewWidget.h"
|
||||
#include "opcv/CvImageData.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
using QtNodes::PortType;
|
||||
using QtNodes::PortIndex;
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
using QtNodes::NodeDataModel;
|
||||
using QtNodes::NodeValidationState;
|
||||
|
||||
class CvImageShowModel :public NodeDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CvImageShowModel();
|
||||
virtual ~CvImageShowModel() {}
|
||||
|
||||
public:
|
||||
QString caption() const override { return QStringLiteral("cvͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ"); }
|
||||
QString name() const override { return QStringLiteral("cvͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ"); }
|
||||
virtual QString modelName() const { return QStringLiteral("cvͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ"); }
|
||||
|
||||
QWidget* embeddedWidget() override { return mCvImageView; }
|
||||
bool resizable() const override { return false; }
|
||||
|
||||
unsigned int nPorts(PortType portType) const override;
|
||||
NodeDataType dataType(PortType portType, PortIndex portIndex) const override;
|
||||
|
||||
NodeValidationState validationState() const override { return modelValidationState; }
|
||||
QString validationMessage() const override { return modelValidationError; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void inputConnectionDeleted(QtNodes::Connection const&) override;
|
||||
|
||||
protected:
|
||||
bool RunTask();
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
|
||||
public:
|
||||
NodeValidationState modelValidationState = NodeValidationState::Warning;
|
||||
QString modelValidationError = QStringLiteral("ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>!");
|
||||
|
||||
private:
|
||||
CvImageViewWidget* mCvImageView;
|
||||
|
||||
std::shared_ptr<CvImageData> mCvImageData;
|
||||
//std::shared_ptr<HRegionData> mCvRect;
|
||||
|
||||
public:
|
||||
std::shared_ptr<NodeData> outData(PortIndex port) override;
|
||||
void setInData(std::shared_ptr<NodeData>, int) override;
|
||||
|
||||
};
|
85
NodeEditorPro/examples/opcv/CvImageViewWidget.cpp
Normal file
85
NodeEditorPro/examples/opcv/CvImageViewWidget.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include "opcv/CvImageViewWidget.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
CvImageViewWidget::CvImageViewWidget(QWidget* parent)
|
||||
{
|
||||
if (parent != Q_NULLPTR)
|
||||
this->setParent(parent);
|
||||
this->setStyleSheet("background-color:black;");
|
||||
curPixmap = new QPixmap();
|
||||
}
|
||||
|
||||
void CvImageViewWidget::showImage(cv::Mat const& _cvimg)
|
||||
{
|
||||
if (_cvimg.empty())
|
||||
{
|
||||
curPixmap = new QPixmap();
|
||||
this->setPixmap(*curPixmap);
|
||||
this->update();
|
||||
return;
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
double zoomRatio = 1.0;
|
||||
|
||||
width = _cvimg.cols;
|
||||
height = _cvimg.rows;
|
||||
|
||||
if (width > this->width())
|
||||
zoomRatio = 1.0 * this->width() / width;
|
||||
|
||||
cv::resize(_cvimg, curImage, cv::Size(width * zoomRatio, height * zoomRatio));
|
||||
CvImageToQPixmap(curImage, *curPixmap);
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
void CvImageViewWidget::CvImageToQPixmap(cv::Mat const& _img, QPixmap& tarImg)
|
||||
{
|
||||
const uchar* pSrc = (const uchar*)_img.data;
|
||||
QImage image;
|
||||
if (_img.type() == CV_8UC1)
|
||||
{
|
||||
qDebug() << "CV_8UC1";
|
||||
image = QImage(pSrc, _img.cols, _img.rows, _img.step, QImage::Format_Grayscale8);
|
||||
}
|
||||
else if (_img.type() == CV_8UC3)
|
||||
{
|
||||
qDebug() << "CV_8UC3";
|
||||
image = QImage(pSrc, _img.cols, _img.rows, _img.step, QImage::Format_RGB888);
|
||||
}
|
||||
else if (_img.type() == CV_8UC4)
|
||||
{
|
||||
qDebug() << "CV_8UC4";
|
||||
image = QImage(pSrc, _img.cols, _img.rows, _img.step, QImage::Format_ARGB32);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "ERROR: Mat could not be converted to QImage.";
|
||||
return;
|
||||
}
|
||||
tarImg = QPixmap::fromImage(image);
|
||||
}
|
||||
|
||||
bool CvImageViewWidget::QImage2CvImage(QImage& from, cv::Mat& to)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CvImageViewWidget::QPixmapToCvRegion(QPixmap const& _pix, cv::Rect2d& tarImg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CvImageViewWidget::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
//QPainter painter(this);
|
||||
if (!curPixmap->isNull())
|
||||
{
|
||||
this->setPixmap(curPixmap->scaled(this->width(), this->height(), Qt::KeepAspectRatio));
|
||||
}
|
||||
QLabel::paintEvent(event);
|
||||
}
|
34
NodeEditorPro/examples/opcv/CvImageViewWidget.h
Normal file
34
NodeEditorPro/examples/opcv/CvImageViewWidget.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QGraphicsView>
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
class CvImageViewWidget :public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CvImageViewWidget(QWidget* parent = Q_NULLPTR);
|
||||
virtual ~CvImageViewWidget() {}
|
||||
|
||||
public:
|
||||
void showImage(cv::Mat const& _himg);
|
||||
|
||||
static void CvImageToQPixmap(cv::Mat const& _img, QPixmap& tarImg);
|
||||
static bool QImage2CvImage(QImage& from, cv::Mat& to);
|
||||
static void QPixmapToCvRegion(QPixmap const& _pix, cv::Rect2d& tarImg);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
private:
|
||||
cv::Mat curImage;
|
||||
QPixmap* curPixmap;
|
||||
// 实例化画家对象,this指定的是绘图设备
|
||||
QPainter painter;
|
||||
};
|
37
NodeEditorPro/examples/opcv/CvRectData.h
Normal file
37
NodeEditorPro/examples/opcv/CvRectData.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include "NodeDataModel.hpp"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
using QtNodes::NodeData;
|
||||
using QtNodes::NodeDataType;
|
||||
|
||||
class CvRectData :public NodeData
|
||||
{
|
||||
public:
|
||||
CvRectData() { mCvRect = cv::Rect(); }
|
||||
CvRectData(cv::Rect& _rect)
|
||||
{
|
||||
if (!_rect.empty())
|
||||
mCvRect = _rect;
|
||||
}
|
||||
|
||||
NodeDataType type() const override { return { "CvRect","Rect" }; }
|
||||
|
||||
cv::Rect* CvRect() { return &mCvRect; }
|
||||
void setCvRect(cv::Rect const& _rect)
|
||||
{
|
||||
if (_rect.empty())
|
||||
return;
|
||||
mCvRect = _rect;
|
||||
}
|
||||
void setSize(QSize const& _size) { mSize = _size; }
|
||||
QSize getSize() { return mSize; }
|
||||
|
||||
private:
|
||||
cv::Rect mCvRect;
|
||||
QSize mSize;
|
||||
};
|
7
NodeEditorPro/examples/opcv/MoudleOpencvNodes.h
Normal file
7
NodeEditorPro/examples/opcv/MoudleOpencvNodes.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "opcv/CvImageLoaderModel.h"
|
||||
#include "opcv/CvImageShowModel.h"
|
||||
#include "opcv/CvImageRGB2GrayModel.h"
|
||||
|
||||
#include "opcv/CvGraphicsShowModel.h"
|
83
NodeEditorPro/examples/opcv/Widget.ui
Normal file
83
NodeEditorPro/examples/opcv/Widget.ui
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>391</width>
|
||||
<height>293</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>图片缩放</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="horizontalSlider">
|
||||
<property name="minimum">
|
||||
<number>-20</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="graphicsView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Reference in New Issue
Block a user