添加项目文件。

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,154 @@
{
"ConnectionStyle": {
"BackgroundColor": {
"alpha": 255,
"blue": 20,
"green": 20,
"red": 20
},
"ConstructionLineWidth": 2,
"HoveredColor": {
"alpha": 255,
"blue": 255,
"green": 255,
"red": 225
},
"LineWidth": 3,
"NormalColor": {
"alpha": 255,
"blue": 139,
"green": 139,
"red": 0
},
"PointDiameter": 10,
"SelectedColor": {
"alpha": 255,
"blue": 100,
"green": 100,
"red": 100
},
"SelectedHaloColor": {
"alpha": 255,
"blue": 0,
"green": 165,
"red": 255
},
"UseDataDefinedColors": false
},
"FlowViewStyle": {
"BackgroundColor": {
"alpha": 255,
"blue": 53,
"green": 53,
"red": 53
},
"CoarseGridColor": {
"alpha": 255,
"blue": 25,
"green": 25,
"red": 25
},
"FineGridColor": {
"alpha": 255,
"blue": 60,
"green": 60,
"red": 60
}
},
"NodeStyle": {
"BackgroundColor": {
"alpha": 255,
"blue": 34,
"green": 34,
"red": 34
},
"ConnectionPointColor": {
"alpha": 255,
"blue": 169,
"green": 169,
"red": 169
},
"ConnectionPointDiameter": 8,
"ErrorColor": {
"alpha": 255,
"blue": 0,
"green": 0,
"red": 255
},
"FilledConnectionPointColor": {
"alpha": 255,
"blue": 255,
"green": 255,
"red": 0
},
"FontColorFaded": {
"alpha": 255,
"blue": 120,
"green": 120,
"red": 120
},
"FontColor": {
"alpha": 255,
"blue": 255,
"green": 255,
"red": 255
},
"GradientColor0": {
"alpha": 255,
"blue": 60,
"green": 60,
"red": 60
},
"GradientColor1": {
"alpha": 255,
"blue": 80,
"green": 80,
"red": 80
},
"GradientColor2": {
"alpha": 255,
"blue": 64,
"green": 64,
"red": 64
},
"GradientColor3": {
"alpha": 255,
"blue": 58,
"green": 58,
"red": 58
},
"HoveredPenWidth": 1.5,
"NormalBoundaryColor": {
"alpha": 255,
"blue": 255,
"green": 255,
"red": 255
},
"Opacity": 0.800000011920929,
"PenWidth": 1,
"SelectedBoundaryColor": {
"alpha": 255,
"blue": 0,
"green": 165,
"red": 255
},
"ShadowColor": {
"alpha": 255,
"blue": 20,
"green": 20,
"red": 20
},
"TitleColor": {
"alpha": 255,
"blue": 12,
"green": 12,
"red": 12
},
"WarningColor": {
"alpha": 255,
"blue": 0,
"green": 128,
"red": 128
}
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>E:\CodeDeps\Halcon2105Cpp\include;E:\CodeDeps\Halcon2105Cpp\include\halconcpp;E:\CodeDeps\Halcon2105Cpp\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>E:\CodeDeps\Halcon2105Cpp\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>halconcpp.lib;halcon.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View File

@@ -0,0 +1,303 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4911AD57-2763-4EDF-9C7C-2E197137BE8B}</ProjectGuid>
<Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.22000.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
<QtInstall>5.14.2_msvc2017_64</QtInstall>
<QtModules>core;opengl;network;gui;widgets;</QtModules>
<QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
<QtInstall>5.15.2_msvc2019_64</QtInstall>
<QtModules>core;opengl;gui;widgets;</QtModules>
<QtBuildConfig>release</QtBuildConfig>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
<Import Project="Halcon2105.props" />
<Import Project="halcon20.11_x64_cpp.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
<Import Project="Halcon2105.props" />
<Import Project="halcon20.11_x64_cpp.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<IncludePath>$(ProjectDir)include;$(ProjectDir)examples;$(ProjectDir)src;$(ProjectDir)..\BreakPad;D:\vs_save\CODE-QT\VisionFlowPro-master\NodeEditorPro\examples\opcv;$(ProjectDir)include\nodes;$(ProjectDir)..\ShapeDrawer;..\NodeEditorPro;..\NodeEditorPro\NodeEditorPro;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<IncludePath>$(ProjectDir)include;$(ProjectDir)examples;$(ProjectDir)src;$(ProjectDir)include\nodes;$(ProjectDir)..\ShapeDrawer;..\NodeEditorPro;..\NodeEditorPro\NodeEditorPro;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>D:\programs\Halcon18\include;D:\programs\opencv4.7.0\include;D:\programs\opencv4.7.0\include\opencv2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard_C>stdc11</LanguageStandard_C>
<CompileAsWinRT>false</CompileAsWinRT>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>D:\programs\Halcon18\lib\x64-win64;D:\programs\opencv4.7.0\x64\vc16\lib;D:\programs\qBreakpad\lib\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_world470d.lib;qBreakpad.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ClCompile>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ClCompile>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>None</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\ShapeDrawer\DrawShapeView.cpp" />
<ClCompile Include="..\ShapeDrawer\ShapeControlItem.cpp" />
<ClCompile Include="..\ShapeDrawer\ShapeItemBase.cpp" />
<ClCompile Include="..\ShapeDrawer\ShapeItemLine.cpp" />
<ClCompile Include="..\ShapeDrawer\ShapeItemPolygon.cpp" />
<ClCompile Include="..\ShapeDrawer\ShapeItemRect1.cpp" />
<ClCompile Include="..\ShapeDrawer\ShapeItemRect2.cpp" />
<ClCompile Include="examples\calculator\Converters.cpp" />
<ClCompile Include="examples\calculator\MathOperationDataModel.cpp" />
<ClCompile Include="examples\calculator\ModuloModel.cpp" />
<ClCompile Include="examples\calculator\NumberDisplayDataModel.cpp" />
<ClCompile Include="examples\calculator\NumberSourceDataModel.cpp" />
<ClCompile Include="examples\halcon\HImageDLSegmentModel.cpp" />
<ClCompile Include="examples\halcon\HImageFolderModel.cpp" />
<ClCompile Include="examples\halcon\HImageLoaderModel.cpp" />
<ClCompile Include="examples\halcon\HImageReduceDomainModel.cpp" />
<ClCompile Include="examples\halcon\HImageRGB2GrayModel.cpp" />
<ClCompile Include="examples\halcon\HImageShowModel.cpp" />
<ClCompile Include="examples\halcon\HImageSplitChanelModel.cpp" />
<ClCompile Include="examples\halcon\HImageThresholdModel.cpp" />
<ClCompile Include="examples\halcon\HRegionConnectModel.cpp" />
<ClCompile Include="examples\halcon\HRegionDifferenceModel.cpp" />
<ClCompile Include="examples\halcon\HRegionFillUpShapeModel.cpp" />
<ClCompile Include="examples\halcon\HRegionOpenCircleModel.cpp" />
<ClCompile Include="examples\halcon\HRegionSelectModel.cpp" />
<ClCompile Include="examples\halcon\HImageViewWidget.cpp" />
<ClCompile Include="examples\halcon\HRegionSelectShapeStdModel.cpp" />
<ClCompile Include="examples\halcon\HRegionShapeTransModel.cpp" />
<ClCompile Include="examples\halcon\HRegionUnionModel.cpp" />
<ClCompile Include="examples\images\ImageLoaderModel.cpp" />
<ClCompile Include="examples\images\ImageShowModel.cpp" />
<ClCompile Include="examples\images\main.cpp" />
<ClCompile Include="examples\images\VisionFlowWidget.cpp" />
<ClCompile Include="examples\opcv\CvAlgorithmTools.cpp" />
<ClCompile Include="examples\opcv\CvGraphicsShowModel.cpp" />
<ClCompile Include="examples\opcv\CvGraphicsViewWidget.cpp" />
<ClCompile Include="examples\opcv\CvImageLoaderModel.cpp" />
<ClCompile Include="examples\opcv\CvImageRGB2GrayModel.cpp" />
<ClCompile Include="examples\opcv\CvImageShowModel.cpp" />
<ClCompile Include="examples\opcv\CvImageViewWidget.cpp" />
<ClCompile Include="src\Connection.cpp" />
<ClCompile Include="src\ConnectionBlurEffect.cpp" />
<ClCompile Include="src\ConnectionGeometry.cpp" />
<ClCompile Include="src\ConnectionGraphicsObject.cpp" />
<ClCompile Include="src\ConnectionPainter.cpp" />
<ClCompile Include="src\ConnectionState.cpp" />
<ClCompile Include="src\ConnectionStyle.cpp" />
<ClCompile Include="src\DataModelRegistry.cpp" />
<ClCompile Include="src\FlowScene.cpp" />
<ClCompile Include="src\FlowView.cpp" />
<ClCompile Include="src\FlowViewStyle.cpp" />
<ClCompile Include="src\Node.cpp" />
<ClCompile Include="src\NodeConnectionInteraction.cpp" />
<ClCompile Include="src\NodeDataModel.cpp" />
<ClCompile Include="src\NodeGeometry.cpp" />
<ClCompile Include="src\NodeGraphicsObject.cpp" />
<ClCompile Include="src\NodePainter.cpp" />
<ClCompile Include="src\NodeState.cpp" />
<ClCompile Include="src\NodeStyle.cpp" />
<ClCompile Include="src\Properties.cpp" />
<ClCompile Include="src\QDataStreamPhaser.cpp" />
<ClCompile Include="src\QJsonParser.cpp" />
<ClCompile Include="src\StyleCollection.cpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="examples\images\ImageLoaderModel.hpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="examples\images\ImageShowModel.hpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="examples\opcv\CvImageRGB2GrayModel.h" />
<QtMoc Include="examples\opcv\CvAlgorithmTools.h" />
<ClInclude Include="x64\Debug\uic\ui_Widget.h" />
<QtMoc Include="..\ShapeDrawer\DrawShapeView.hpp" />
<QtMoc Include="..\BreakPad\QBreakpadHandler.h" />
<QtMoc Include="..\BreakPad\QBreakpadHttpUploader.h" />
<ClInclude Include="..\BreakPad\singletone\call_once.h" />
<ClInclude Include="..\BreakPad\singletone\singleton.h" />
<ClInclude Include="..\ShapeDrawer\DrawViewParams.h" />
<QtMoc Include="..\ShapeDrawer\ShapeControlItem.h" />
<QtMoc Include="..\ShapeDrawer\ShapeItemBase.h" />
<ClInclude Include="..\ShapeDrawer\ShapeItemLine.h" />
<ClInclude Include="..\ShapeDrawer\ShapeItemPolygon.h" />
<ClInclude Include="..\ShapeDrawer\ShapeItemRect1.h" />
<ClInclude Include="..\ShapeDrawer\ShapeItemRect2.h" />
<ClInclude Include="examples\calculator\AdditionModel.hpp" />
<ClInclude Include="examples\calculator\Converters.hpp" />
<ClInclude Include="examples\calculator\DecimalData.hpp" />
<ClInclude Include="examples\calculator\DivisionModel.hpp" />
<ClInclude Include="examples\calculator\IntegerData.hpp" />
<ClInclude Include="examples\calculator\MathNodes.hpp" />
<ClInclude Include="examples\calculator\MultiplicationModel.hpp" />
<ClInclude Include="examples\calculator\SubtractionModel.hpp" />
<ClInclude Include="examples\halcon\HalconNodes.hpp" />
<ClInclude Include="examples\halcon\HImageData.hpp" />
<QtMoc Include="examples\halcon\HImageReduceDomainModel.hpp" />
<QtMoc Include="examples\halcon\HRegionSelectModel.hpp" />
<QtMoc Include="examples\halcon\HRegionConnectModel.hpp" />
<QtMoc Include="examples\halcon\HImageDLSegmentModel.hpp" />
<ClInclude Include="examples\halcon\HRegionData.hpp" />
<QtMoc Include="examples\halcon\HRegionShapeTransModel.hpp" />
<QtMoc Include="examples\halcon\HRegionFillUpShapeModel.hpp" />
<QtMoc Include="examples\halcon\HRegionOpenCircleModel.hpp" />
<QtMoc Include="examples\halcon\HRegionUnionModel.hpp" />
<QtMoc Include="examples\halcon\HRegionDifferenceModel.hpp" />
<QtMoc Include="examples\halcon\HRegionSelectShapeStdModel.hpp" />
<ClInclude Include="examples\images\VisionFlowWidget.hpp" />
<QtMoc Include="examples\opcv\CvGraphicsShowModel.h" />
<QtMoc Include="examples\opcv\CvGraphicsViewWidget.h" />
<ClInclude Include="examples\opcv\CvImageData.h" />
<QtMoc Include="examples\opcv\CvImageLoaderModel.h" />
<QtMoc Include="examples\opcv\CvImageViewWidget.h" />
<QtMoc Include="examples\opcv\CvImageShowModel.h" />
<ClInclude Include="examples\opcv\CvRectData.h" />
<ClInclude Include="examples\opcv\MoudleOpencvNodes.h" />
<ClInclude Include="src\QDataStreamPhaser.hpp" />
<ClInclude Include="src\QJsonParser.hpp" />
<QtMoc Include="examples\halcon\HImageRGB2GrayModel.hpp" />
<QtMoc Include="examples\halcon\HImageSplitChanelModel.hpp" />
<QtMoc Include="examples\halcon\HImageFolderModel.hpp" />
<QtMoc Include="examples\halcon\HImageThresholdModel.hpp" />
<ClInclude Include="examples\halcon\HImageViewWidget.hpp" />
<QtMoc Include="examples\halcon\HImageShowModel.hpp" />
<QtMoc Include="examples\halcon\HImageLoaderModel.hpp" />
<QtMoc Include="examples\calculator\NumberSourceDataModel.hpp" />
<QtMoc Include="examples\calculator\NumberDisplayDataModel.hpp" />
<QtMoc Include="examples\calculator\ModuloModel.hpp" />
<QtMoc Include="examples\calculator\MathOperationDataModel.hpp" />
<ClInclude Include="examples\halcon\HObjectData.hpp" />
<ClInclude Include="examples\images\PixmapData.hpp" />
<ClInclude Include="include\nodes\Compiler.hpp" />
<ClInclude Include="include\nodes\ConnectionGeometry.hpp" />
<ClInclude Include="include\nodes\ConnectionState.hpp" />
<ClInclude Include="include\nodes\ConnectionStyle.hpp" />
<ClInclude Include="include\nodes\DataModelRegistry.hpp" />
<ClInclude Include="include\nodes\Export.hpp" />
<ClInclude Include="include\nodes\FlowViewStyle.hpp" />
<ClInclude Include="include\nodes\memory.hpp" />
<ClInclude Include="include\nodes\NodeData.hpp" />
<ClInclude Include="include\nodes\NodeGeometry.hpp" />
<ClInclude Include="include\nodes\NodePainterDelegate.hpp" />
<ClInclude Include="include\nodes\NodeState.hpp" />
<ClInclude Include="include\nodes\NodeStyle.hpp" />
<ClInclude Include="include\nodes\OperatingSystem.hpp" />
<ClInclude Include="include\nodes\PortType.hpp" />
<ClInclude Include="include\nodes\QStringStdHash.hpp" />
<ClInclude Include="include\nodes\QUuidStdHash.hpp" />
<ClInclude Include="include\nodes\Serializable.hpp" />
<ClInclude Include="include\nodes\Style.hpp" />
<ClInclude Include="include\nodes\StyleCollection.hpp" />
<ClInclude Include="include\nodes\TypeConverter.hpp" />
<QtMoc Include="include\nodes\NodeGraphicsObject.hpp" />
<QtMoc Include="include\nodes\NodeDataModel.hpp" />
<QtMoc Include="include\nodes\Node.hpp" />
<QtMoc Include="include\nodes\FlowView.hpp" />
<QtMoc Include="include\nodes\FlowScene.hpp" />
<QtMoc Include="include\nodes\ConnectionGraphicsObject.hpp" />
<QtMoc Include="include\nodes\Connection.hpp" />
<ClInclude Include="src\ConnectionBlurEffect.hpp" />
<ClInclude Include="src\ConnectionPainter.hpp" />
<ClInclude Include="src\NodeConnectionInteraction.hpp" />
<ClInclude Include="src\NodePainter.hpp" />
<ClInclude Include="src\Properties.hpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\README.md" />
<None Include="resources\DefaultStyle.json" />
</ItemGroup>
<ItemGroup>
<QtRcc Include="resources\resources.qrc" />
</ItemGroup>
<ItemGroup>
<Image Include="showcase\showcase1.gif" />
<Image Include="showcase\showcase3.gif" />
<Image Include="showcase\showcase4.gif" />
<Image Include="showcase\showcase5.png" />
</ItemGroup>
<ItemGroup>
<Media Include="showcase\showcase2.mp4" />
<Media Include="showcase\showcase6.mp4" />
</ItemGroup>
<ItemGroup>
<QtUic Include="examples\opcv\Widget.ui" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,576 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
</Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
</Filter>
<Filter Include="src">
<UniqueIdentifier>{9a98fda8-feb3-4f88-8c2e-592a4de4472c}</UniqueIdentifier>
</Filter>
<Filter Include="include">
<UniqueIdentifier>{d24eeab8-793f-42fd-a74c-811a1f607589}</UniqueIdentifier>
</Filter>
<Filter Include="examples">
<UniqueIdentifier>{c1e4a5fa-9994-43e5-bb12-96e91cf47d5e}</UniqueIdentifier>
</Filter>
<Filter Include="examples\images">
<UniqueIdentifier>{4ebde7d5-53a9-47c7-be30-715a8a16d470}</UniqueIdentifier>
</Filter>
<Filter Include="include\nodes">
<UniqueIdentifier>{b32b7bd8-e89e-4d39-a813-904b62cf937a}</UniqueIdentifier>
</Filter>
<Filter Include="examples\calculator">
<UniqueIdentifier>{29211f79-6b95-4f3d-9689-a7725e0a9716}</UniqueIdentifier>
</Filter>
<Filter Include="examples\halcon">
<UniqueIdentifier>{d10913a6-d89c-429f-9399-8f43d3c9921e}</UniqueIdentifier>
</Filter>
<Filter Include="showcase">
<UniqueIdentifier>{e33d0eb7-423e-495d-96bb-71d4ecf57e5f}</UniqueIdentifier>
</Filter>
<Filter Include="ShapeDrawer">
<UniqueIdentifier>{678d160a-53aa-4f3b-8683-cee586ef65bb}</UniqueIdentifier>
</Filter>
<Filter Include="examples\opcv">
<UniqueIdentifier>{44ba4646-41f6-4e96-a09a-3e5175a147fa}</UniqueIdentifier>
</Filter>
<Filter Include="breakpad">
<UniqueIdentifier>{35c78b53-ce64-4c9d-ab5f-c0a80039de73}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="examples\images\ImageLoaderModel.cpp">
<Filter>examples\images</Filter>
</ClCompile>
<ClCompile Include="examples\images\ImageShowModel.cpp">
<Filter>examples\images</Filter>
</ClCompile>
<ClCompile Include="examples\images\main.cpp">
<Filter>examples\images</Filter>
</ClCompile>
<ClCompile Include="src\Connection.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ConnectionBlurEffect.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ConnectionGeometry.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ConnectionGraphicsObject.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ConnectionPainter.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ConnectionState.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ConnectionStyle.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\DataModelRegistry.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\FlowScene.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\FlowView.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\FlowViewStyle.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\Node.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\NodeConnectionInteraction.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\NodeDataModel.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\NodeGeometry.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\NodeGraphicsObject.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\NodePainter.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\NodeState.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\NodeStyle.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\Properties.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\StyleCollection.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="examples\calculator\Converters.cpp">
<Filter>examples\calculator</Filter>
</ClCompile>
<ClCompile Include="examples\calculator\MathOperationDataModel.cpp">
<Filter>examples\calculator</Filter>
</ClCompile>
<ClCompile Include="examples\calculator\ModuloModel.cpp">
<Filter>examples\calculator</Filter>
</ClCompile>
<ClCompile Include="examples\calculator\NumberDisplayDataModel.cpp">
<Filter>examples\calculator</Filter>
</ClCompile>
<ClCompile Include="examples\calculator\NumberSourceDataModel.cpp">
<Filter>examples\calculator</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageLoaderModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageShowModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageViewWidget.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageRGB2GrayModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageSplitChanelModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageFolderModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageThresholdModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="src\QJsonParser.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\QDataStreamPhaser.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="examples\images\VisionFlowWidget.cpp">
<Filter>examples\images</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionSelectModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionConnectModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionShapeTransModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageReduceDomainModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionFillUpShapeModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionOpenCircleModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionUnionModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionDifferenceModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HRegionSelectShapeStdModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="examples\halcon\HImageDLSegmentModel.cpp">
<Filter>examples\halcon</Filter>
</ClCompile>
<ClCompile Include="..\ShapeDrawer\ShapeControlItem.cpp">
<Filter>ShapeDrawer</Filter>
</ClCompile>
<ClCompile Include="..\ShapeDrawer\ShapeItemBase.cpp">
<Filter>ShapeDrawer</Filter>
</ClCompile>
<ClCompile Include="..\ShapeDrawer\DrawShapeView.cpp">
<Filter>ShapeDrawer</Filter>
</ClCompile>
<ClCompile Include="..\ShapeDrawer\ShapeItemLine.cpp">
<Filter>ShapeDrawer</Filter>
</ClCompile>
<ClCompile Include="..\ShapeDrawer\ShapeItemRect1.cpp">
<Filter>ShapeDrawer</Filter>
</ClCompile>
<ClCompile Include="..\ShapeDrawer\ShapeItemRect2.cpp">
<Filter>ShapeDrawer</Filter>
</ClCompile>
<ClCompile Include="..\ShapeDrawer\ShapeItemPolygon.cpp">
<Filter>ShapeDrawer</Filter>
</ClCompile>
<ClCompile Include="examples\opcv\CvImageLoaderModel.cpp">
<Filter>examples\opcv</Filter>
</ClCompile>
<ClCompile Include="examples\opcv\CvImageViewWidget.cpp">
<Filter>examples\opcv</Filter>
</ClCompile>
<ClCompile Include="examples\opcv\CvImageShowModel.cpp">
<Filter>examples\opcv</Filter>
</ClCompile>
<ClCompile Include="examples\opcv\CvGraphicsViewWidget.cpp">
<Filter>examples\opcv</Filter>
</ClCompile>
<ClCompile Include="examples\opcv\CvGraphicsShowModel.cpp">
<Filter>examples\opcv</Filter>
</ClCompile>
<ClCompile Include="examples\opcv\CvImageRGB2GrayModel.cpp">
<Filter>examples\opcv</Filter>
</ClCompile>
<ClCompile Include="examples\opcv\CvAlgorithmTools.cpp">
<Filter>examples\opcv</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="examples\images\ImageLoaderModel.hpp">
<Filter>examples\images</Filter>
</QtMoc>
<QtMoc Include="examples\images\ImageShowModel.hpp">
<Filter>examples\images</Filter>
</QtMoc>
<QtMoc Include="include\nodes\Connection.hpp">
<Filter>include\nodes</Filter>
</QtMoc>
<QtMoc Include="include\nodes\ConnectionGraphicsObject.hpp">
<Filter>include\nodes</Filter>
</QtMoc>
<QtMoc Include="include\nodes\FlowScene.hpp">
<Filter>include\nodes</Filter>
</QtMoc>
<QtMoc Include="include\nodes\FlowView.hpp">
<Filter>include\nodes</Filter>
</QtMoc>
<QtMoc Include="include\nodes\Node.hpp">
<Filter>include\nodes</Filter>
</QtMoc>
<QtMoc Include="include\nodes\NodeDataModel.hpp">
<Filter>include\nodes</Filter>
</QtMoc>
<QtMoc Include="include\nodes\NodeGraphicsObject.hpp">
<Filter>include\nodes</Filter>
</QtMoc>
<QtMoc Include="examples\calculator\MathOperationDataModel.hpp">
<Filter>examples\calculator</Filter>
</QtMoc>
<QtMoc Include="examples\calculator\ModuloModel.hpp">
<Filter>examples\calculator</Filter>
</QtMoc>
<QtMoc Include="examples\calculator\NumberDisplayDataModel.hpp">
<Filter>examples\calculator</Filter>
</QtMoc>
<QtMoc Include="examples\calculator\NumberSourceDataModel.hpp">
<Filter>examples\calculator</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageLoaderModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageShowModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageRGB2GrayModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageSplitChanelModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageFolderModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageThresholdModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionSelectModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionConnectModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionShapeTransModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageReduceDomainModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionFillUpShapeModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionOpenCircleModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionUnionModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionDifferenceModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HRegionSelectShapeStdModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="examples\halcon\HImageDLSegmentModel.hpp">
<Filter>examples\halcon</Filter>
</QtMoc>
<QtMoc Include="..\ShapeDrawer\ShapeItemBase.h">
<Filter>ShapeDrawer</Filter>
</QtMoc>
<QtMoc Include="..\ShapeDrawer\DrawShapeView.hpp">
<Filter>ShapeDrawer</Filter>
</QtMoc>
<QtMoc Include="..\ShapeDrawer\ShapeControlItem.h">
<Filter>ShapeDrawer</Filter>
</QtMoc>
<QtMoc Include="examples\opcv\CvImageLoaderModel.h">
<Filter>examples\opcv</Filter>
</QtMoc>
<QtMoc Include="examples\opcv\CvImageViewWidget.h">
<Filter>examples\opcv</Filter>
</QtMoc>
<QtMoc Include="examples\opcv\CvImageShowModel.h">
<Filter>examples\opcv</Filter>
</QtMoc>
<QtMoc Include="examples\opcv\CvGraphicsShowModel.h">
<Filter>examples\opcv</Filter>
</QtMoc>
<QtMoc Include="examples\opcv\CvGraphicsViewWidget.h">
<Filter>examples\opcv</Filter>
</QtMoc>
<QtMoc Include="..\BreakPad\QBreakpadHandler.h">
<Filter>breakpad</Filter>
</QtMoc>
<QtMoc Include="..\BreakPad\QBreakpadHttpUploader.h">
<Filter>breakpad</Filter>
</QtMoc>
<QtMoc Include="examples\opcv\CvImageRGB2GrayModel.h">
<Filter>examples\opcv</Filter>
</QtMoc>
<QtMoc Include="examples\opcv\CvAlgorithmTools.h">
<Filter>examples\opcv</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="examples\images\PixmapData.hpp">
<Filter>examples\images</Filter>
</ClInclude>
<ClInclude Include="src\ConnectionBlurEffect.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\ConnectionPainter.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\NodeConnectionInteraction.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\NodePainter.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\Properties.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="include\nodes\Compiler.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\ConnectionGeometry.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\ConnectionState.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\ConnectionStyle.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\DataModelRegistry.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\Export.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\FlowViewStyle.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\memory.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\NodeData.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\NodeGeometry.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\NodePainterDelegate.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\NodeState.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\NodeStyle.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\OperatingSystem.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\PortType.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\QStringStdHash.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\QUuidStdHash.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\Style.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\StyleCollection.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="include\nodes\TypeConverter.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\AdditionModel.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\Converters.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\DecimalData.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\DivisionModel.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\IntegerData.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\MultiplicationModel.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\SubtractionModel.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\halcon\HImageData.hpp">
<Filter>examples\halcon</Filter>
</ClInclude>
<ClInclude Include="examples\halcon\HImageViewWidget.hpp">
<Filter>examples\halcon</Filter>
</ClInclude>
<ClInclude Include="examples\halcon\HObjectData.hpp">
<Filter>examples\halcon</Filter>
</ClInclude>
<ClInclude Include="src\QJsonParser.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\QDataStreamPhaser.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="examples\images\VisionFlowWidget.hpp">
<Filter>examples\images</Filter>
</ClInclude>
<ClInclude Include="examples\halcon\HalconNodes.hpp">
<Filter>examples\halcon</Filter>
</ClInclude>
<ClInclude Include="examples\calculator\MathNodes.hpp">
<Filter>examples\calculator</Filter>
</ClInclude>
<ClInclude Include="examples\halcon\HRegionData.hpp">
<Filter>examples\halcon</Filter>
</ClInclude>
<ClInclude Include="..\ShapeDrawer\DrawViewParams.h">
<Filter>ShapeDrawer</Filter>
</ClInclude>
<ClInclude Include="..\ShapeDrawer\ShapeItemLine.h">
<Filter>ShapeDrawer</Filter>
</ClInclude>
<ClInclude Include="..\ShapeDrawer\ShapeItemRect1.h">
<Filter>ShapeDrawer</Filter>
</ClInclude>
<ClInclude Include="..\ShapeDrawer\ShapeItemRect2.h">
<Filter>ShapeDrawer</Filter>
</ClInclude>
<ClInclude Include="..\ShapeDrawer\ShapeItemPolygon.h">
<Filter>ShapeDrawer</Filter>
</ClInclude>
<ClInclude Include="examples\opcv\CvImageData.h">
<Filter>examples\opcv</Filter>
</ClInclude>
<ClInclude Include="examples\opcv\CvRectData.h">
<Filter>examples\opcv</Filter>
</ClInclude>
<ClInclude Include="examples\opcv\MoudleOpencvNodes.h">
<Filter>examples\opcv</Filter>
</ClInclude>
<ClInclude Include="..\BreakPad\singletone\call_once.h">
<Filter>breakpad</Filter>
</ClInclude>
<ClInclude Include="..\BreakPad\singletone\singleton.h">
<Filter>breakpad</Filter>
</ClInclude>
<ClInclude Include="x64\Debug\uic\ui_Widget.h">
<Filter>Form Files</Filter>
</ClInclude>
<ClInclude Include="include\nodes\Serializable.hpp">
<Filter>include\nodes</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="resources\DefaultStyle.json">
<Filter>Resource Files</Filter>
</None>
<None Include="..\README.md" />
</ItemGroup>
<ItemGroup>
<QtRcc Include="resources\resources.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
</ItemGroup>
<ItemGroup>
<Image Include="showcase\showcase1.gif">
<Filter>showcase</Filter>
</Image>
<Image Include="showcase\showcase3.gif">
<Filter>showcase</Filter>
</Image>
<Image Include="showcase\showcase4.gif">
<Filter>showcase</Filter>
</Image>
<Image Include="showcase\showcase5.png">
<Filter>showcase</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Media Include="showcase\showcase2.mp4">
<Filter>showcase</Filter>
</Media>
<Media Include="showcase\showcase6.mp4">
<Filter>showcase</Filter>
</Media>
</ItemGroup>
<ItemGroup>
<QtUic Include="examples\opcv\Widget.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
</Project>

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>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>B:\CodeDeps\halconlibs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>halcon.lib;halconcpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>B:\CodeDeps\halconlibs\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View File

@@ -0,0 +1,53 @@
#pragma once
#if \
defined (__MINGW32__) || \
defined (__MINGW64__)
# define NODE_EDITOR_COMPILER "MinGW"
# define NODE_EDITOR_COMPILER_MINGW
#elif \
defined (__GNUC__)
# define NODE_EDITOR_COMPILER "GNU"
# define NODE_EDITOR_COMPILER_GNU
# define NODE_EDITOR_COMPILER_GNU_VERSION_MAJOR __GNUC__
# define NODE_EDITOR_COMPILER_GNU_VERSION_MINOR __GNUC_MINOR__
# define NODE_EDITOR_COMPILER_GNU_VERSION_PATCH __GNUC_PATCHLEVEL__
#elif \
defined (__clang__)
# define NODE_EDITOR_COMPILER "Clang"
# define NODE_EDITOR_COMPILER_CLANG
#elif \
defined (_MSC_VER)
# define NODE_EDITOR_COMPILER "Microsoft Visual C++"
# define NODE_EDITOR_COMPILER_MICROSOFT
#elif \
defined (__BORLANDC__)
# define NODE_EDITOR_COMPILER "Borland C++ Builder"
# define NODE_EDITOR_COMPILER_BORLAND
#elif \
defined (__CODEGEARC__)
# define NODE_EDITOR_COMPILER "CodeGear C++ Builder"
# define NODE_EDITOR_COMPILER_CODEGEAR
#elif \
defined (__INTEL_COMPILER) || \
defined (__ICL)
# define NODE_EDITOR_COMPILER "Intel C++"
# define NODE_EDITOR_COMPILER_INTEL
#elif \
defined (__xlC__) || \
defined (__IBMCPP__)
# define NODE_EDITOR_COMPILER "IBM XL C++"
# define NODE_EDITOR_COMPILER_IBM
#elif \
defined (__HP_aCC)
# define NODE_EDITOR_COMPILER "HP aC++"
# define NODE_EDITOR_COMPILER_HP
#elif \
defined (__WATCOMC__)
# define NODE_EDITOR_COMPILER "Watcom C++"
# define NODE_EDITOR_COMPILER_WATCOM
#endif
#ifndef NODE_EDITOR_COMPILER
# error "Current compiler is not supported."
#endif

View File

@@ -0,0 +1,167 @@
#pragma once
#include <QtCore/QObject>
#include <QtCore/QUuid>
#include <QtCore/QVariant>
#include "PortType.hpp"
#include "NodeData.hpp"
#include "Serializable.hpp"
#include "ConnectionState.hpp"
#include "ConnectionGeometry.hpp"
#include "TypeConverter.hpp"
#include "QUuidStdHash.hpp"
#include "Export.hpp"
#include "memory.hpp"
class QPointF;
namespace QtNodes
{
class Node;
class NodeData;
class ConnectionGraphicsObject;
/**
* \brief 节点连接线
*/
class Connection
: public QObject
, public Serializable
{
Q_OBJECT
public:
/// 新的连接对象会连接到目标节点,连接的端口应当有 端口类型,端口序号
/// 连接对象的另一端应当是相反的端口。
Connection(PortType portType,
Node& node,
PortIndex portIndex);
Connection(Node& nodeIn,
PortIndex portIndexIn,
Node& nodeOut,
PortIndex portIndexOut,
TypeConverter converter =
TypeConverter{});
Connection(const Connection&) = delete;
Connection operator=(const Connection&) = delete;
~Connection();
public:
QJsonObject
save() const override;
public:
QUuid
id() const;
/// Remembers the end being dragged.
/// Invalidates Node address.
/// Grabs mouse.
void
setRequiredPort(PortType portType);
PortType
requiredPort() const;
void
setGraphicsObject(std::unique_ptr<ConnectionGraphicsObject>&& graphics);
/// Assigns a node to the required port.
/// It is assumed that there is a required port, no extra checks
void
setNodeToPort(Node& node,
PortType portType,
PortIndex portIndex);
void
removeFromNodes() const;
public:
ConnectionGraphicsObject&
getConnectionGraphicsObject() const;
ConnectionState const&
connectionState() const;
ConnectionState&
connectionState();
ConnectionGeometry&
connectionGeometry();
ConnectionGeometry const&
connectionGeometry() const;
Node*
getNode(PortType portType) const;
Node*&
getNode(PortType portType);
PortIndex
getPortIndex(PortType portType) const;
void
clearNode(PortType portType);
NodeDataType
dataType(PortType portType) const;
void
setTypeConverter(TypeConverter converter);
bool
complete() const;
public: // data propagation
void
propagateData(std::shared_ptr<NodeData> nodeData) const;
void
propagateEmptyData() const;
Q_SIGNALS:
void
connectionCompleted(Connection const&) const;
void
connectionMadeIncomplete(Connection const&) const;
private:
QUuid _uid;
private:
Node* _outNode = nullptr;
Node* _inNode = nullptr;
PortIndex _outPortIndex;
PortIndex _inPortIndex;
private:
ConnectionState _connectionState;
ConnectionGeometry _connectionGeometry;
std::unique_ptr<ConnectionGraphicsObject>_connectionGraphicsObject;
TypeConverter _converter;
Q_SIGNALS:
void
updated(Connection& conn) const;
};
}

View File

@@ -0,0 +1,60 @@
#pragma once
#include "PortType.hpp"
#include <QtCore/QPointF>
#include <QtCore/QRectF>
#include <iostream>
namespace QtNodes
{
class ConnectionGeometry
{
public:
ConnectionGeometry();
public:
QPointF const&
getEndPoint(PortType portType) const;
void
setEndPoint(PortType portType, QPointF const& point);
void
moveEndPoint(PortType portType, QPointF const& offset);
QRectF
boundingRect() const;
std::pair<QPointF, QPointF>
pointsC1C2() const;
QPointF
source() const { return _out; }
QPointF
sink() const { return _in; }
double
lineWidth() const { return _lineWidth; }
bool
hovered() const { return _hovered; }
void
setHovered(bool hovered) { _hovered = hovered; }
private:
// local object coordinates
QPointF _in;
QPointF _out;
//int _animationPhase;
double _lineWidth;
bool _hovered;
};
}

View File

@@ -0,0 +1,89 @@
#pragma once
#include <QtCore/QUuid>
#include <QtWidgets/QGraphicsObject>
class QGraphicsSceneMouseEvent;
namespace QtNodes
{
class FlowScene;
class Connection;
class ConnectionGeometry;
class Node;
/// Graphic Object for connection. Adds itself to scene
class ConnectionGraphicsObject
: public QGraphicsObject
{
Q_OBJECT
public:
ConnectionGraphicsObject(FlowScene& scene,
Connection& connection);
virtual
~ConnectionGraphicsObject();
enum { Type = UserType + 2 };
int
type() const override { return Type; }
public:
Connection&
connection();
QRectF
boundingRect() const override;
QPainterPath
shape() const override;
void
setGeometryChanged();
/// Updates the position of both ends
void
move();
void
lock(bool locked);
protected:
void
paint(QPainter* painter,
QStyleOptionGraphicsItem const* option,
QWidget* widget = 0) override;
void
mousePressEvent(QGraphicsSceneMouseEvent* event) override;
void
mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
void
mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
void
hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
void
hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
private:
void
addGraphicsEffect();
private:
FlowScene& _scene;
Connection& _connection;
};
}

View File

@@ -0,0 +1,71 @@
#pragma once
#include <QtCore/QUuid>
#include "PortType.hpp"
class QPointF;
namespace QtNodes
{
class Node;
/// Stores currently draggind end.
/// Remembers last hovered Node.
class ConnectionState
{
public:
ConnectionState(PortType port = PortType::None)
: _requiredPort(port)
{}
ConnectionState(const ConnectionState&) = delete;
ConnectionState operator=(const ConnectionState&) = delete;
~ConnectionState();
public:
void setRequiredPort(PortType end)
{
_requiredPort = end;
}
PortType requiredPort() const
{
return _requiredPort;
}
bool requiresPort() const
{
return _requiredPort != PortType::None;
}
void setNoRequiredPort()
{
_requiredPort = PortType::None;
}
public:
void interactWithNode(Node* node);
void setLastHoveredNode(Node* node);
Node*
lastHoveredNode() const
{
return _lastHoveredNode;
}
void resetLastHoveredNode();
private:
PortType _requiredPort;
Node* _lastHoveredNode{ nullptr };
};
}

View File

@@ -0,0 +1,58 @@
#pragma once
#include <QtGui/QColor>
#include "Export.hpp"
#include "Style.hpp"
namespace QtNodes
{
class ConnectionStyle : public Style
{
public:
ConnectionStyle();
ConnectionStyle(QString jsonText);
public:
static void setConnectionStyle(QString fileName);
private:
void loadJsonFile(QString fileName) override;
void saveJsonFile(QString fileName) override;
public:
QColor constructionColor() const;
QColor normalColor() const;
QColor normalColor(QString typeId) const;
QColor selectedColor() const;
QColor selectedHaloColor() const;
QColor hoveredColor() const;
float lineWidth() const;
float constructionLineWidth() const;
float pointDiameter() const;
bool useDataDefinedColors() const;
public:
QColor ConstructionColor;
QColor NormalColor;
QColor SelectedColor;
QColor SelectedHaloColor;
QColor HoveredColor;
float LineWidth;
float ConstructionLineWidth;
float PointDiameter;
bool UseDataDefinedColors;
};
}

View File

@@ -0,0 +1,166 @@
#pragma once
#include <functional>
#include <memory>
#include <set>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
#include <QtCore/QString>
#include "NodeDataModel.hpp"
#include "TypeConverter.hpp"
#include "Export.hpp"
#include "QStringStdHash.hpp"
#include "memory.hpp"
namespace QtNodes
{
/// Class uses map for storing models (name, model)
class DataModelRegistry
{
public:
using RegistryItemPtr = std::unique_ptr<NodeDataModel>;
using RegistryItemCreator = std::function<RegistryItemPtr()>;
using RegisteredModelCreatorsMap = std::unordered_map<QString, RegistryItemCreator>;
using RegisteredModelsCategoryMap = std::unordered_map<QString, QString>;
using CategoriesSet = std::set<QString>;
using RegisteredTypeConvertersMap = std::unordered_map<
TypeConverterId, TypeConverter, TypeConverterIdHash>;
DataModelRegistry() = default;
~DataModelRegistry() = default;
DataModelRegistry(DataModelRegistry const&) = delete;
DataModelRegistry(DataModelRegistry&&) = default;
DataModelRegistry& operator=(DataModelRegistry const&) = delete;
DataModelRegistry& operator=(DataModelRegistry&&) = default;
public:
template<typename ModelType>
void registerModel(RegistryItemCreator creator,
QString const& category = u8"默认节点")
{
const QString name = computeName<ModelType>(HasStaticMethodName<ModelType>{}, creator);
if (!_registeredItemCreators.count(name))
{
_registeredItemCreators[name] = std::move(creator);
_categories.insert(category);
_registeredModelsCategory[name] = category;
}
}
template<typename ModelType>
void registerModel(QString const& category = u8"默认节点")
{
RegistryItemCreator creator = []() { return std::make_unique<ModelType>(); };
registerModel<ModelType>(std::move(creator), category);
}
template<typename ModelType>
void registerModel(QString const& category,
RegistryItemCreator creator)
{
registerModel<ModelType>(std::move(creator), category);
}
template <typename ModelCreator>
void registerModel(ModelCreator&& creator, QString const& category = u8"默认节点")
{
using ModelType = compute_model_type_t<decltype(creator())>;
registerModel<ModelType>(std::forward<ModelCreator>(creator), category);
}
template <typename ModelCreator>
void registerModel(QString const& category, ModelCreator&& creator)
{
registerModel(std::forward<ModelCreator>(creator), category);
}
void registerTypeConverter(TypeConverterId const& id,
TypeConverter typeConverter)
{
_registeredTypeConverters[id] = std::move(typeConverter);
}
std::unique_ptr<NodeDataModel>create(QString const& modelName);
RegisteredModelCreatorsMap const& registeredModelCreators() const;
RegisteredModelsCategoryMap const& registeredModelsCategoryAssociation() const;
CategoriesSet const& categories() const;
TypeConverter getTypeConverter(NodeDataType const& d1,
NodeDataType const& d2) const;
private:
RegisteredModelsCategoryMap _registeredModelsCategory;
CategoriesSet _categories;
RegisteredModelCreatorsMap _registeredItemCreators;
RegisteredTypeConvertersMap _registeredTypeConverters;
private:
template <typename T, typename = void>
struct HasStaticMethodName
: std::false_type
{};
template <typename T>
struct HasStaticMethodName<T,
typename std::enable_if<std::is_same<decltype(T::Name()), QString>::value>::type>
: std::true_type
{};
template <typename ModelType>
static QString
computeName(std::true_type, RegistryItemCreator const&)
{
return ModelType::Name();
}
template <typename ModelType>
static QString
computeName(std::false_type, RegistryItemCreator const& creator)
{
return creator()->name();
}
template <typename T>
struct UnwrapUniquePtr
{
// Assert always fires, but the compiler doesn't know this:
static_assert(!std::is_same<T, T>::value,
"The ModelCreator must return a std::unique_ptr<T>, where T "
"inherits from NodeDataModel");
};
template <typename T>
struct UnwrapUniquePtr<std::unique_ptr<T>>
{
static_assert(std::is_base_of<NodeDataModel, T>::value,
"The ModelCreator must return a std::unique_ptr<T>, where T "
"inherits from NodeDataModel");
using type = T;
};
template <typename CreatorResult>
using compute_model_type_t = typename UnwrapUniquePtr<CreatorResult>::type;
};
}

View File

@@ -0,0 +1,51 @@
#pragma once
#include "Compiler.hpp"
#include "OperatingSystem.hpp"
#ifdef NODE_EDITOR_PLATFORM_WINDOWS
# define NODE_EDITOR_EXPORT __declspec(dllexport)
# define NODE_EDITOR_IMPORT __declspec(dllimport)
# define NODE_EDITOR_LOCAL
#elif \
NODE_EDITOR_COMPILER_GNU_VERSION_MAJOR >= 4 || \
defined (NODE_EDITOR_COMPILER_CLANG)
# define NODE_EDITOR_EXPORT __attribute__((visibility("default")))
# define NODE_EDITOR_IMPORT __attribute__((visibility("default")))
# define NODE_EDITOR_LOCAL __attribute__((visibility("hidden")))
#else
# define NODE_EDITOR_EXPORT
# define NODE_EDITOR_IMPORT
# define NODE_EDITOR_LOCAL
#endif
#ifdef __cplusplus
# define NODE_EDITOR_DEMANGLED extern "C"
#else
# define NODE_EDITOR_DEMANGLED
#endif
//#if defined (NODE_EDITOR_SHARED) && !defined (NODE_EDITOR_STATIC)
//# ifdef NODE_EDITOR_EXPORTS
//# define NODE_EDITOR_EXPORT
//# else
//# define NODE_EDITOR_IMPORT
//# endif
//# define NODE_EDITOR_PRIVATE NODE_EDITOR_LOCAL
//#elif !defined (NODE_EDITOR_SHARED) && defined (NODE_EDITOR_STATIC)
//# define
//# define NODE_EDITOR_PRIVATE
//#elif defined (NODE_EDITOR_SHARED) && defined (NODE_EDITOR_STATIC)
//# ifdef NODE_EDITOR_EXPORTS
//# error "Cannot build as shared and static simultaneously."
//# else
//# error "Cannot link against shared and static simultaneously."
//# endif
//#else
//# ifdef NODE_EDITOR_EXPORTS
//# error "Choose whether to build as shared or static."
//# else
//# error "Choose whether to link against shared or static."
//# endif
//#endif

View File

@@ -0,0 +1,168 @@
#pragma once
#include <QtCore/QUuid>
#include <QtWidgets/QGraphicsScene>
#include <QThread>
#include <unordered_map>
#include <tuple>
#include <functional>
#include "QUuidStdHash.hpp"
#include "Export.hpp"
#include "DataModelRegistry.hpp"
#include "TypeConverter.hpp"
#include "memory.hpp"
namespace QtNodes
{
class NodeDataModel;
class FlowItemInterface;
class Node;
class NodeGraphicsObject;
class Connection;
class ConnectionGraphicsObject;
class NodeStyle;
/// Scene holds connections and nodes.
class FlowScene
: public QGraphicsScene
{
Q_OBJECT
public:
FlowScene(std::shared_ptr<DataModelRegistry> registry,
QObject* parent = Q_NULLPTR);
FlowScene(QObject* parent = Q_NULLPTR);
~FlowScene();
public:
std::shared_ptr<Connection>
createConnection(PortType connectedPort,
Node& node,
PortIndex portIndex);
std::shared_ptr<Connection>
createConnection(Node& nodeIn,
PortIndex portIndexIn,
Node& nodeOut,
PortIndex portIndexOut,
TypeConverter const& converter = TypeConverter{});
std::shared_ptr<Connection> restoreConnection(QJsonObject const& connectionJson);
void deleteConnection(Connection const& connection);
Node& createNode(std::unique_ptr<NodeDataModel>&& dataModel);
Node& restoreNode(QJsonObject const& nodeJson);
void removeNode(Node& node);
DataModelRegistry& registry() const;
void setRegistry(std::shared_ptr<DataModelRegistry> registry);
void iterateOverNodes(std::function<void(Node*)> const& visitor);
void iterateOverNodeData(std::function<void(NodeDataModel*)> const& visitor);
void iterateOverNodeDataDependentOrder(std::function<void(NodeDataModel*)> const& visitor);
QPointF getNodePosition(Node const& node) const;
void setNodePosition(Node& node, QPointF const& pos) const;
QSizeF getNodeSize(Node const& node) const;
public:
std::unordered_map<QUuid, std::unique_ptr<Node> > const& nodes() const;
std::unordered_map<QUuid, std::shared_ptr<Connection> > const& connections() const;
std::vector<Node*> allNodes() const;
std::vector<Node*> selectedNodes() const;
public:
void clearScene();
void save() const;
void load();
QByteArray saveToMemory() const;
void loadFromMemory(const QByteArray& data);
Q_SIGNALS:
/**
* @brief Node has been created but not on the scene yet.
* @see nodePlaced()
*/
void nodeCreated(Node& n);
/**
* @brief Node has been added to the scene.
* @details Connect to this signal if need a correct position of node.
* @see nodeCreated()
*/
void nodePlaced(Node& n);
void nodeDeleted(Node& n);
void connectionCreated(Connection const& c);
void connectionDeleted(Connection const& c);
void nodeMoved(Node& n, const QPointF& newLocation);
void nodeDoubleClicked(Node& n);
void nodeClicked(Node& n);
void connectionHovered(Connection& c, QPoint screenPos);
void nodeHovered(Node& n, QPoint screenPos);
void connectionHoverLeft(Connection& c);
void nodeHoverLeft(Node& n);
void nodeContextMenu(Node& n, const QPointF& pos);
private:
using SharedConnection = std::shared_ptr<Connection>;
using UniqueNode = std::unique_ptr<Node>;
// DO NOT reorder this member to go after the others.
// This should outlive all the connections and nodes of
// the graph, so that nodes can potentially have pointers into it,
// which is why it comes first in the class.
std::shared_ptr<DataModelRegistry> _registry;
std::unordered_map<QUuid, SharedConnection> _connections;
std::unordered_map<QUuid, UniqueNode> _nodes;
private Q_SLOTS:
void setupConnectionSignals(Connection const& c);
void sendConnectionCreatedToNodes(Connection const& c);
void sendConnectionDeletedToNodes(Connection const& c);
};
Node*
locateNodeAt(QPointF scenePoint, FlowScene& scene,
QTransform const& viewTransform);
}

View File

@@ -0,0 +1,72 @@
#pragma once
#include <QtWidgets/QGraphicsView>
#include <QDebug>
#include "Export.hpp"
namespace QtNodes
{
class FlowScene;
class FlowView
: public QGraphicsView
{
Q_OBJECT
public:
FlowView(QWidget* parent = Q_NULLPTR);
FlowView(FlowScene* scene, QWidget* parent = Q_NULLPTR);
FlowView(const FlowView&) = delete;
FlowView operator=(const FlowView&) = delete;
QAction* clearSelectionAction() const;
QAction* deleteSelectionAction() const;
void setScene(FlowScene* scene);
public Q_SLOTS:
void scaleUp();
void scaleDown();
void deleteSelectedNodes();
protected:
void contextMenuEvent(QContextMenuEvent* event) override;
void wheelEvent(QWheelEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void drawBackground(QPainter* painter, const QRectF& r) override;
void showEvent(QShowEvent* event) override;
protected:
FlowScene* scene();
private:
QAction* _clearSelectionAction;
QAction* _deleteSelectionAction;
QPointF _clickPos;
FlowScene* _scene;
};
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <QtGui/QColor>
#include "Export.hpp"
#include "Style.hpp"
namespace QtNodes
{
class FlowViewStyle : public Style
{
public:
FlowViewStyle();
FlowViewStyle(QString jsonText);
public:
static void setStyle(QString jsonText);
private:
void loadJsonFile(QString fileName) override;
void saveJsonFile(QString fileName) override;
public:
QColor BackgroundColor;
QColor FineGridColor;
QColor CoarseGridColor;
};
}

View File

@@ -0,0 +1,133 @@
#pragma once
#include <QtCore/QObject>
#include <QtCore/QUuid>
#include <QtCore/QJsonObject>
#include "PortType.hpp"
#include "Export.hpp"
#include "NodeState.hpp"
#include "NodeGeometry.hpp"
#include "NodeData.hpp"
#include "NodeGraphicsObject.hpp"
#include "ConnectionGraphicsObject.hpp"
#include "Serializable.hpp"
#include "memory.hpp"
namespace QtNodes
{
class Connection;
class ConnectionState;
class NodeGraphicsObject;
class NodeDataModel;
class Node
: public QObject
, public Serializable
{
Q_OBJECT
public:
/// NodeDataModel should be an rvalue and is moved into the Node
Node(std::unique_ptr<NodeDataModel>&& dataModel);
virtual
~Node();
public:
/**
* \brief Json序列化
* \return json object
*/
QJsonObject
save() const override;
/**
* \brief Json反序列化
* \param json json
*/
void
restore(QJsonObject const& json) override;
public:
/**
* \brief 节点的QUuid
* \return uid
*/
QUuid
id() const;
void reactToPossibleConnection(PortType,
NodeDataType const&,
QPointF const& scenePoint);
void
resetReactionToConnection();
public:
NodeGraphicsObject const&
nodeGraphicsObject() const;
NodeGraphicsObject&
nodeGraphicsObject();
void
setGraphicsObject(std::unique_ptr<NodeGraphicsObject>&& graphics);
NodeGeometry&
nodeGeometry();
NodeGeometry const&
nodeGeometry() const;
NodeState const&
nodeState() const;
NodeState&
nodeState();
NodeDataModel*
nodeDataModel() const;
public Q_SLOTS: // data propagation
/// Propagates incoming data to the underlying model.
void
propagateData(std::shared_ptr<NodeData> nodeData,
PortIndex inPortIndex,
const QUuid& connectionId) const;
/// Fetches data from model's OUT #index port
/// and propagates it to the connection
void
onDataUpdated(PortIndex index);
/// Propagates empty data to the attached connection.
void
onDataInvalidated(PortIndex index);
/// update the graphic part if the size of the embeddedwidget changes
void
onNodeSizeUpdated();
private:
// addressing
QUuid _uid;
// data
std::unique_ptr<NodeDataModel> _nodeDataModel;
NodeState _nodeState;
// painting
NodeGeometry _nodeGeometry;
std::unique_ptr<NodeGraphicsObject> _nodeGraphicsObject;
};
}

View File

@@ -0,0 +1,52 @@
#pragma once
#include <QtCore/QString>
#include "Export.hpp"
namespace QtNodes
{
struct NodeDataType
{
QString id;
/**
* \brief 用于比较的名称
*/
QString name;
friend bool operator<(QtNodes::NodeDataType const& d1,
QtNodes::NodeDataType const& d2)
{
return d1.id < d2.id;
}
friend bool operator==(const QtNodes::NodeDataType& d1,
const QtNodes::NodeDataType& d2) noexcept
{
return d1.id == d2.id;
}
};
/// Class represents data transferred between nodes.
/// @param type is used for comparing the types
/// The actual data is stored in subtypes
class NodeData
{
public:
virtual ~NodeData() = default;
virtual bool sameType(NodeData const& nodeData) const
{
return (this->type().id == nodeData.type().id);
}
/**
* \brief 节点标签
* \return 标签名字
*/
virtual NodeDataType type() const = 0;
};
}

Some files were not shown because too many files have changed in this diff Show More