添加项目文件。

This commit is contained in:
keyeslll
2023-02-28 14:50:28 +08:00
commit e20fa428dd
187 changed files with 18135 additions and 0 deletions

View 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);
}
};

View File

@ -0,0 +1,5 @@
file(GLOB_RECURSE CPPS ./*.cpp )
add_executable(calculator ${CPPS})
target_link_libraries(calculator nodes)

View 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;
}

View 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;
};

View 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;
};

View 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);
}
};

View 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;
};

View 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"

View 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;
}

View 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("未连接或运行失败!");
};

View 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;
}

View 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("未连接或运行失败!");
};

View 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);
}
};

View 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;
}

View 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;
};

View 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;
}

View 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;
};

View 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);
}
};

View 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);
}

View 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;
};

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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;
};

View 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);
}

View 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;
};

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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"

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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{};
};

View 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();
});
}

View 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;
}

View 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();
}

View 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);
}

View 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);
};

View 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);
}

View 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;
};

View 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>
//}

View 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>
};

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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);
}

View 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;
};

View 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;
};

View File

@ -0,0 +1,7 @@
#pragma once
#include "opcv/CvImageLoaderModel.h"
#include "opcv/CvImageShowModel.h"
#include "opcv/CvImageRGB2GrayModel.h"
#include "opcv/CvGraphicsShowModel.h"

View 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>