diff --git a/Grinder/Version.h b/Grinder/Version.h index 9bc3062c581b981e052313e4fa9db36f7469fd81..68fff9b32e62ee66725ff9b519466e529eb77d6e 100644 --- a/Grinder/Version.h +++ b/Grinder/Version.h @@ -10,14 +10,14 @@ #define GRNDR_INFO_TITLE "Grinder" #define GRNDR_INFO_COPYRIGHT "Copyright (c) WWU Muenster" -#define GRNDR_INFO_DATE "08.10.2019" +#define GRNDR_INFO_DATE "10.10.2019" #define GRNDR_INFO_COMPANY "WWU Muenster" #define GRNDR_INFO_WEBSITE "http://www.uni-muenster.de" #define GRNDR_VERSION_MAJOR 0 #define GRNDR_VERSION_MINOR 15 #define GRNDR_VERSION_REVISION 0 -#define GRNDR_VERSION_BUILD 400 +#define GRNDR_VERSION_BUILD 401 namespace grndr { diff --git a/Grinder/engine/data/DataType.cpp b/Grinder/engine/data/DataType.cpp index 29a4fff16ede2ac8f7cb5c409763698e4dff59ad..d033251bd2a8c040562a96a76296755deb20e630 100644 --- a/Grinder/engine/data/DataType.cpp +++ b/Grinder/engine/data/DataType.cpp @@ -12,5 +12,4 @@ const char* DataType::Data = "Data"; const char* DataType::ImageTags = "ImageTags"; const char* DataType::GrabCutModels = "GrabCutModels"; -const char* DataType::MachineLearningMethod = "MachineLearningMethod"; -const char* DataType::MachineLearningState = "MachineLearningState"; +const char* DataType::MachineLearningModel = "MachineLearningModel"; diff --git a/Grinder/engine/data/DataType.h b/Grinder/engine/data/DataType.h index eaae7a172839a3d920f533ec06a34169c23d8d89..1d0db3a50c83ec562fdf62efd3d72c720efa0f17 100644 --- a/Grinder/engine/data/DataType.h +++ b/Grinder/engine/data/DataType.h @@ -19,8 +19,7 @@ namespace grndr static const char* ImageTags; static const char* GrabCutModels; - static const char* MachineLearningMethod; - static const char* MachineLearningState; + static const char* MachineLearningModel; public: using QString::QString; diff --git a/Grinder/ml/blocks/MachineLearningBlock.cpp b/Grinder/ml/blocks/MachineLearningBlock.cpp index a7033a9c408df2d4aac9079f6d6ca689c13d8f8e..51a7802f6bdc4e730a8752fa1dad06576489b508 100644 --- a/Grinder/ml/blocks/MachineLearningBlock.cpp +++ b/Grinder/ml/blocks/MachineLearningBlock.cpp @@ -41,17 +41,14 @@ bool MachineLearningBlock::updateProperties(PropertyBase* updatedProp) void MachineLearningBlock::createPorts() { - DataDescriptors methodPortDataDescs = {DataDescriptor::customDescriptor("Machine learning method", DataType::MachineLearningMethod)}; - _methodPort = createPort(PortType::Method, Port::Direction::In, methodPortDataDescs, "Method"); - - DataDescriptors statePortDataDescs = {DataDescriptor::customDescriptor("Model state", DataType::MachineLearningState)}; - _statePort = createPort(PortType::State, Port::Direction::In, statePortDataDescs, "State"); + DataDescriptors inPortDataDescs = {DataDescriptor::imageDescriptor(true, DataDescriptor::ValueType::Any), DataDescriptor::imageDescriptor(false, DataDescriptor::ValueType::Any)}; + _inPort = createPort(PortType::ImageIn, Port::Direction::In, inPortDataDescs, "In"); DataDescriptors imageTagsPortDataDescs = {DataDescriptor::customDescriptor("Image tags", DataType::ImageTags)}; _imageTagsPort = createPort(PortType::ImageTagsIn, Port::Direction::In, imageTagsPortDataDescs, "Tags"); - DataDescriptors inPortDataDescs = {DataDescriptor::imageDescriptor(true, DataDescriptor::ValueType::Any), DataDescriptor::imageDescriptor(false, DataDescriptor::ValueType::Any)}; - _inPort = createPort(PortType::ImageIn, Port::Direction::In, inPortDataDescs, "In"); + DataDescriptors modelPortDataDescs = {DataDescriptor::customDescriptor("Machine learning model", DataType::MachineLearningModel)}; + _modelPort = createPort(PortType::Model, Port::Direction::In, modelPortDataDescs, "Model"); } void MachineLearningBlock::updateTileSizeProperty() diff --git a/Grinder/ml/blocks/MachineLearningBlock.h b/Grinder/ml/blocks/MachineLearningBlock.h index 6ffad1732b09dfb54510568386a6f5894601d94d..edf65b2dd2eacad17d80553e0dd122d716553e53 100644 --- a/Grinder/ml/blocks/MachineLearningBlock.h +++ b/Grinder/ml/blocks/MachineLearningBlock.h @@ -26,10 +26,8 @@ namespace grndr auto tilingOverlap() { return dynamic_cast<UIntProperty*>(_tilingOverlap.get()); } auto tilingOverlap() const { return dynamic_cast<const UIntProperty*>(_tilingOverlap.get()); } - Port* methodPort() { return _methodPort.get(); } - const Port* methodPort() const { return _methodPort.get(); } - Port* statePort() { return _statePort.get(); } - const Port* statePort() const { return _statePort.get(); } + Port* modelPort() { return _modelPort.get(); } + const Port* modelPort() const { return _modelPort.get(); } Port* imageTagsPort() { return _imageTagsPort.get(); } const Port* imageTagsPort() const { return _imageTagsPort.get(); } Port* inPort() { return _inPort.get(); } @@ -48,8 +46,7 @@ namespace grndr std::shared_ptr<PropertyBase> _tilingSize; std::shared_ptr<PropertyBase> _tilingOverlap; - std::shared_ptr<Port> _methodPort; - std::shared_ptr<Port> _statePort; + std::shared_ptr<Port> _modelPort; std::shared_ptr<Port> _imageTagsPort; std::shared_ptr<Port> _inPort; }; diff --git a/Grinder/ml/blocks/MachineLearningMethodBlock.h b/Grinder/ml/blocks/MachineLearningMethodBlock.h index b910de4b8cc895e04eda78f1655f7e2bf6515203..e166840a4979242ac59f7e37c051370f4e6727fb 100644 --- a/Grinder/ml/blocks/MachineLearningMethodBlock.h +++ b/Grinder/ml/blocks/MachineLearningMethodBlock.h @@ -40,10 +40,8 @@ namespace grndr auto state() { return dynamic_cast<MachineLearningStateProperty*>(_state.get()); } auto state() const { return dynamic_cast<const MachineLearningStateProperty*>(_state.get()); } - Port* methodPort() { return _methodPort.get(); } - const Port* methodPort() const { return _methodPort.get(); } - Port* statePort() { return _statePort.get(); } - const Port* statePort() const { return _statePort.get(); } + Port* modelPort() { return _modelPort.get(); } + const Port* modelPort() const { return _modelPort.get(); } protected: virtual void createProperties() override; @@ -63,8 +61,7 @@ namespace grndr std::shared_ptr<PropertyBase> _outputDirectory; std::shared_ptr<PropertyBase> _state; - std::shared_ptr<Port> _methodPort; - std::shared_ptr<Port> _statePort; + std::shared_ptr<Port> _modelPort; }; } diff --git a/Grinder/ml/blocks/MachineLearningMethodBlock.impl.h b/Grinder/ml/blocks/MachineLearningMethodBlock.impl.h index caa8ecb04f020f79f39e42706d456fa4c87a3075..709a63a0ed7ce7f6ee1cffb169b17e8a374b192d 100644 --- a/Grinder/ml/blocks/MachineLearningMethodBlock.impl.h +++ b/Grinder/ml/blocks/MachineLearningMethodBlock.impl.h @@ -18,7 +18,7 @@ void MachineLearningMethodBlock<MethodType>::initBlock() { Block::initBlock(); - updateConfiguration(); + updateConfiguration(); } template<typename MethodType> @@ -52,8 +52,7 @@ bool MachineLearningMethodBlock<MethodType>::updateProperties(PropertyBase* upda updateConfiguration(); - if (updatedProp == _outputDirectory.get()) - updated |= !this->checkStateAvailability(); + updated |= !checkStateAvailability(); return updated; } @@ -61,11 +60,8 @@ bool MachineLearningMethodBlock<MethodType>::updateProperties(PropertyBase* upda template<typename MethodType> void MachineLearningMethodBlock<MethodType>::createPorts() { - DataDescriptors methodPortDataDescs = {DataDescriptor::customDescriptor("Machine learning method", DataType::MachineLearningMethod)}; - _methodPort = createPort(PortType::Method, Port::Direction::Out, methodPortDataDescs, "Method"); - - DataDescriptors statePortDataDescs = {DataDescriptor::customDescriptor("Model state", DataType::MachineLearningState)}; - _statePort = createPort(PortType::State, Port::Direction::Out, statePortDataDescs, "State"); + DataDescriptors modelPortDataDescs = {DataDescriptor::customDescriptor("Machine learning model", DataType::MachineLearningModel)}; + _modelPort = createPort(PortType::Model, Port::Direction::Out, modelPortDataDescs, "Model"); } template<typename MethodType> diff --git a/Grinder/ml/blocks/TrainingBlock.cpp b/Grinder/ml/blocks/TrainingBlock.cpp index 105aac3f8e103365a5dcc3e4d75f40b142e190c6..bf3b249510b3ef30d377ec0de3236ae90e124261 100644 --- a/Grinder/ml/blocks/TrainingBlock.cpp +++ b/Grinder/ml/blocks/TrainingBlock.cpp @@ -24,5 +24,5 @@ void TrainingBlock::createPorts() { MachineLearningBlock::createPorts(); - _tagsBitmapPort = createPort(PortType::ImageTagsBitmap, Port::Direction::In, {DataDescriptor::imageDescriptor(false, DataDescriptor::ValueType::UInt32)}, "Tags bitmap"); + _tagsBitmapPort = createPort(PortType::ImageTagsBitmap, Port::Direction::In, {DataDescriptor::imageDescriptor(false, DataDescriptor::ValueType::UInt32)}, "Tags bitmap", _modelPort); } diff --git a/Grinder/ml/processors/InferenceProcessor.cpp b/Grinder/ml/processors/InferenceProcessor.cpp index 27175a2e007b33069ebd569e32adeeb25e9b1939..9219fdd3fd75549b49a253d6ff9e205a20d3d7db 100644 --- a/Grinder/ml/processors/InferenceProcessor.cpp +++ b/Grinder/ml/processors/InferenceProcessor.cpp @@ -76,6 +76,14 @@ void InferenceProcessor::executionPass(EngineExecutionContext& ctx, const Machin } } +void InferenceProcessor::fillTaskData(EngineExecutionContext& ctx, MachineLearningTaskData& taskData) const +{ + MachineLearningProcessor::fillTaskData(ctx, taskData); + + if (taskData.state.isEmpty()) + throwProcessorException("A model state is required for performing inference"); +} + void InferenceProcessor::forwardInferenceResults(EngineExecutionContext& ctx, const DataBlob* dataBlob, const MachineLearningTask::ImageInferenceResults& results, bool useCache) const { QSize imgSize{dataBlob->getMatrix().cols, dataBlob->getMatrix().rows}; diff --git a/Grinder/ml/processors/InferenceProcessor.h b/Grinder/ml/processors/InferenceProcessor.h index d4e64ce1d2dce63084f3b3aab1a8dc2a573955f4..a3b6457edc55ffb1086545e5691734308b59a847 100644 --- a/Grinder/ml/processors/InferenceProcessor.h +++ b/Grinder/ml/processors/InferenceProcessor.h @@ -22,6 +22,8 @@ namespace grndr virtual void firstExecutionPass(EngineExecutionContext& ctx, const MachineLearningTaskData& taskData) override; virtual void executionPass(EngineExecutionContext& ctx, const MachineLearningTaskData& taskData) override; + virtual void fillTaskData(EngineExecutionContext& ctx, MachineLearningTaskData& taskData) const override; + private: void forwardInferenceResults(EngineExecutionContext& ctx, const DataBlob* dataBlob, const MachineLearningTask::ImageInferenceResults& results, bool useCache = true) const; }; diff --git a/Grinder/ml/processors/MachineLearningMethodProcessor.impl.h b/Grinder/ml/processors/MachineLearningMethodProcessor.impl.h index 67ae199d1612c0185686528ba7707af7b97dae98..93c012051f0fda2ef9804ca4012d1948bb836e21 100644 --- a/Grinder/ml/processors/MachineLearningMethodProcessor.impl.h +++ b/Grinder/ml/processors/MachineLearningMethodProcessor.impl.h @@ -29,7 +29,7 @@ void MachineLearningMethodProcessor<MethodType>::execute(EngineExecutionContext& this->_block->method().config().verifyConfiguration(); } - // Store the machine learning method and model state in the context data - ctx.data().set(this->_block->methodPort(), Data_Value_Method, static_cast<const MachineLearningMethodBase*>(&this->_block->method())); - ctx.data().set(this->_block->statePort(), Data_Value_State, this->_block->state()->getValue()); + // Store the machine learning method and state in the context data + ctx.data().set(this->_block->modelPort(), Data_Value_Method, static_cast<const MachineLearningMethodBase*>(&this->_block->method())); + ctx.data().set(this->_block->modelPort(), Data_Value_State, this->_block->state()->getValue()); } diff --git a/Grinder/ml/processors/MachineLearningProcessor.impl.h b/Grinder/ml/processors/MachineLearningProcessor.impl.h index b4ef8b122e62094302c97b70f755fe82d540f273..e75646ada8bcc5df50eddc6219e94f5303c8c957 100644 --- a/Grinder/ml/processors/MachineLearningProcessor.impl.h +++ b/Grinder/ml/processors/MachineLearningProcessor.impl.h @@ -33,7 +33,7 @@ MachineLearningProcessor<BlockType>::MachineLearningProcessor(const Block* block template<typename BlockType> void MachineLearningProcessor<BlockType>::fillTaskData(EngineExecutionContext& ctx, MachineLearningTaskData& taskData) const { - taskData.method = this->template portData<const MachineLearningMethodBase*>(ctx, this->_block->methodPort(), Data_Value_Method); + taskData.method = this->template portData<const MachineLearningMethodBase*>(ctx, this->_block->modelPort(), Data_Value_Method); taskData.imageTags = this->template portData<const ImageTags*>(ctx, this->_block->imageTagsPort(), ImageTagsProcessor::Data_Value_ImageTags); if (auto dataBlob = this->portData(ctx, this->_block->inPort())) @@ -46,7 +46,7 @@ void MachineLearningProcessor<BlockType>::fillTaskData(EngineExecutionContext& c taskData.imageTiler = std::move(imageTiler); } - taskData.state = this->template portData<QString>(ctx, this->_block->statePort(), Data_Value_State, false); + taskData.state = this->template portData<QString>(ctx, this->_block->modelPort(), Data_Value_State, false); } template<typename BlockType> diff --git a/Grinder/pipeline/Block.cpp b/Grinder/pipeline/Block.cpp index 3f31d1371a0769a19b2a3cfa5b1f1ca09520507d..0a3e3e126ab663fb876425636c18a615a6c72ac5 100644 --- a/Grinder/pipeline/Block.cpp +++ b/Grinder/pipeline/Block.cpp @@ -152,7 +152,7 @@ void Block::deserialize(DeserializationContext& ctx) deserializePorts(ctx); } -std::shared_ptr<Port> Block::createPort(PortType type, Port::Direction dir, DataDescriptors dataDescriptors, QString name) +std::shared_ptr<Port> Block::createPort(PortType type, Port::Direction dir, DataDescriptors dataDescriptors, QString name, const std::shared_ptr<Port>& insertBefore) { if (type == PortType::Undefined) throw std::invalid_argument{_EXCPT("type may not be PortType::Undefined")}; @@ -169,7 +169,22 @@ std::shared_ptr<Port> Block::createPort(PortType type, Port::Direction dir, Data throw; } - _ports.push_back(port); + bool portAdded = false; + + if (insertBefore) + { + auto it = std::find(_ports.cbegin(), _ports.cend(), insertBefore); + + if (it != _ports.cend()) + { + _ports.insert(it, port); + portAdded = true; + } + } + + if (!portAdded) + _ports.push_back(port); + emit portsModified(); return port; diff --git a/Grinder/pipeline/Block.h b/Grinder/pipeline/Block.h index 8d2612078f8e86942914d1b389fcf4e888c9cd94..f553f0f49a4a55430af4efd701c9de6d2ff1beb0 100644 --- a/Grinder/pipeline/Block.h +++ b/Grinder/pipeline/Block.h @@ -78,7 +78,7 @@ namespace grndr protected: virtual void createPorts() = 0; - std::shared_ptr<Port> createPort(PortType type, Port::Direction dir, DataDescriptors dataDescriptors, QString name = ""); + std::shared_ptr<Port> createPort(PortType type, Port::Direction dir, DataDescriptors dataDescriptors, QString name = "", const std::shared_ptr<Port>& insertBefore = nullptr); void resetPort(Port* port, PortType newType, QString newName = ""); void removePort(PortType type); void removePort(const Port* port); diff --git a/Grinder/pipeline/PortType.cpp b/Grinder/pipeline/PortType.cpp index 880a6a5e1a7b19b58b0fe406af44b3fd50eead7b..ad153cff4552318f53c343eb96b2f9c76e1e986a 100644 --- a/Grinder/pipeline/PortType.cpp +++ b/Grinder/pipeline/PortType.cpp @@ -28,6 +28,4 @@ const char* PortType::Markers = "Markers"; const char* PortType::Predecessor = "Predecessor"; const char* PortType::Successor = "Successor"; -const char* PortType::Method = "Method"; -const char* PortType::State = "State"; -const char* PortType::TrainedState = "TrainedState"; +const char* PortType::Model = "Model"; diff --git a/Grinder/pipeline/PortType.h b/Grinder/pipeline/PortType.h index 07c92f3fcbadfca8fe6df7f0a3ffd60c596b44a4..4df12deeb403470ef1a2c0ffbfd0874845a57889 100644 --- a/Grinder/pipeline/PortType.h +++ b/Grinder/pipeline/PortType.h @@ -35,9 +35,7 @@ namespace grndr static const char* Predecessor; static const char* Successor; - static const char* Method; - static const char* State; - static const char* TrainedState; + static const char* Model; public: using QString::QString;