This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,36 @@
PROJECT(openvibe-plugins-sdk-feature-extraction)
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.inl)
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC_FILES})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
FOLDER ${PLUGINS_FOLDER}
COMPILE_FLAGS "-DOVP_Exports -DOVP_Shared")
# ---------------------------------
INCLUDE("FindOpenViBE")
INCLUDE("FindOpenViBECommon")
INCLUDE("FindOpenViBEToolkit")
INCLUDE("FindOpenViBEModuleEBML")
# ---------------------------------
# Target macros
# Defines target operating system, architecture and compiler
# ---------------------------------
SET_BUILD_PLATFORM()
# -----------------------------
# Install files
# -----------------------------
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
INSTALL(DIRECTORY box-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/box-tutorials)
@@ -0,0 +1,360 @@
<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>2.2.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x000001b3, 0x00001dd9)</Identifier>
<Name>Feature aggregator</Name>
<AlgorithmClassIdentifier>(0x00682417, 0x453635f9)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Input stream 1</Name>
</Input>
<Input>
<Identifier>(0x004294b2, 0xfe7e8a08)</Identifier>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Input stream 2</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x17341935, 0x152ff448)</TypeIdentifier>
<Name>Feature vector stream</Name>
</Output>
</Outputs>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>384</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>736</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xb5d15cc9, 0x6c8c28fb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x004b1b63)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003622, 0x0000376c)</Identifier>
<Name>Matrix Display</Name>
<AlgorithmClassIdentifier>(0x54f0796d, 0x3ede2cc0)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Matrix</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x3d3c7c7f, 0xef0e7129)</TypeIdentifier>
<Name>Color gradient</Name>
<DefaultValue>0:2,36,58; 50:100,100,100; 100:83,17,20</DefaultValue>
<Value>0:2,36,58; 50:100,100,100; 100:83,17,20</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Steps</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Symetric min/max</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Real time min/max</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>432</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>736</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x4ff49bdb, 0x9dcf6788)</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>4</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003ad0, 0x00003967)</Identifier>
<Name>Simple DSP</Name>
<AlgorithmClassIdentifier>(0x00e26fa1, 0x1dbab1b2)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input - A</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Equation</Name>
<DefaultValue>x</DefaultValue>
<Value>x+10</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>784</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x21889dc4, 0x1126497e)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003dc7, 0x0000468d)</Identifier>
<Name>Time signal</Name>
<AlgorithmClassIdentifier>(0x28a5e7ff, 0x530095de)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Generated signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sampling frequency</Name>
<DefaultValue>512</DefaultValue>
<Value>256</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Generated epoch sample count</Name>
<DefaultValue>32</DefaultValue>
<Value>4</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>272</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>688</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x9e5ca01e, 0x30a4d8c3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003dc7, 0x0000468e)</Identifier>
<Name>Time signal</Name>
<AlgorithmClassIdentifier>(0x28a5e7ff, 0x530095de)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Generated signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sampling frequency</Name>
<DefaultValue>512</DefaultValue>
<Value>256</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Generated epoch sample count</Name>
<DefaultValue>32</DefaultValue>
<Value>4</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>272</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>784</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x9e5ca01e, 0x30a4d8c3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00000587, 0x00007793)</Identifier>
<Source>
<BoxIdentifier>(0x000001b3, 0x00001dd9)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003622, 0x0000376c)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000016f7, 0x00005cd1)</Identifier>
<Source>
<BoxIdentifier>(0x00003ad0, 0x00003967)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000001b3, 0x00001dd9)</BoxIdentifier>
<BoxInputIdentifier>(0x004294b2, 0xfe7e8a08)</BoxInputIdentifier>
</Target>
</Link>
<Link>
<Identifier>(0x00004b52, 0x00001eef)</Identifier>
<Source>
<BoxIdentifier>(0x00003dc7, 0x0000468d)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000001b3, 0x00001dd9)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0000778e, 0x00002620)</Identifier>
<Source>
<BoxIdentifier>(0x00003dc7, 0x0000468e)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003ad0, 0x00003967)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x0000019a, 0x000047dc)</Identifier>
<Text>You can browse each box' documentation by selecting the box and pressing &lt;b&gt;F1&lt;/b&gt;</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>736</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>160</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x00004cc5, 0x0000007c)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x000050a5, 0x00005401)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0x00003622, 0x0000376c)","childCount":0,"identifier":"(0x00006730, 0x000037b5)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00006ebd, 0x00002449)","index":0,"name":"Default tab","parentIdentifier":"(0x000050a5, 0x00005401)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x000055d0, 0x0000606d)","index":0,"name":"Empty","parentIdentifier":"(0x00006ebd, 0x00002449)","type":0}]</Data>
</Entry>
</Metadata>
</OpenViBE-Scenario>
@@ -0,0 +1,52 @@
/**
* \page BoxAlgorithm_FeatureAggregator Feature aggregator
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Description|
* This plugins aggregates the features it receives on its inputs
* into a feature vector that can be used for classification.
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Inputs|
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Inputs|
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Input1|
* A stream of matrices containing features.
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Input1|
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Input2|
* A stream of matrices containing features.
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Input2|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Outputs|
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Outputs|
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Output1|
* A stream of feature vectors made by aggregating incoming features.
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Output1|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Examples|
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_FeatureAggregator_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_FeatureAggregator_Miscellaneous|
*/
@@ -0,0 +1,45 @@
.. _Doc_BoxAlgorithm_FeatureAggregator:
Feature aggregator
==================
.. container:: attribution
:Author:
Bruno Renier
:Company:
INRIA/IRISA
.. image:: images/Doc_BoxAlgorithm_FeatureAggregator.png
Each chunk of input will be catenated into one feature vector.
This plugins aggregates the features it receives on its inputs
into a feature vector that can be used for classification.
Inputs
------
.. csv-table::
:header: "Input Name", "Stream Type"
"Input stream 1", "Streamed matrix"
Input stream 1
~~~~~~~~~~~~~~
A stream of matrices containing features.
Outputs
-------
.. csv-table::
:header: "Output Name", "Stream Type"
"Feature vector stream", "Feature vector"
Feature vector stream
~~~~~~~~~~~~~~~~~~~~~
A stream of feature vectors made by aggregating incoming features.
@@ -0,0 +1,154 @@
#include "ovpCBoxAlgorithmFeatureAggregator.h"
#include <iostream>
namespace OpenViBE {
namespace Plugins {
namespace FeatureExtraction {
bool CBoxAlgorithmFeatureAggregator::initialize()
{
m_nInput = getBoxAlgorithmContext()->getStaticBoxContext()->getInputCount();
// Prepares decoders
for (size_t i = 0; i < m_nInput; ++i)
{
Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmFeatureAggregator>* streamedMatrixDecoder = new Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmFeatureAggregator>();
m_decoder.push_back(streamedMatrixDecoder);
m_decoder.back()->initialize(*this, i);
}
m_encoder = new Toolkit::TFeatureVectorEncoder<CBoxAlgorithmFeatureAggregator>;
m_encoder->initialize(*this, 0);
//resizes everything as needed
m_iBufferSizes.resize(m_nInput);
m_dimSize.resize(m_nInput);
m_featureNames.resize(m_nInput);
m_headerSent = false;
return true;
}
bool CBoxAlgorithmFeatureAggregator::uninitialize()
{
for (size_t i = 0; i < m_nInput; ++i)
{
if (m_decoder.back())
{
m_decoder.back()->uninitialize();
delete m_decoder.back();
m_decoder.pop_back();
}
}
if (m_encoder)
{
m_encoder->uninitialize();
delete m_encoder;
}
return true;
}
bool CBoxAlgorithmFeatureAggregator::processInput(const size_t index)
{
Kernel::IBoxIO* boxIO = getBoxAlgorithmContext()->getDynamicBoxContext();
size_t lastBufferChunkSize;
const uint8_t* lastBuffer;
size_t bufferChunkSize;
const uint8_t* buffer;
//gets the first buffer from the concerned input
boxIO->getInputChunk(index, 0, m_lastChunkStartTime, m_lastChunkEndTime, lastBufferChunkSize, lastBuffer);
uint64_t tStart = 0, tEnd = 0;
bool readyToProcess = true;
//checks every input's first chunk's dates
for (size_t i = 0; i < m_nInput && readyToProcess; ++i)
{
if (boxIO->getInputChunkCount(i) != 0)
{
boxIO->getInputChunk(i, 0, tStart, tEnd, bufferChunkSize, buffer);
//if the first buffers don't have the same starting/ending dates, stop
if (tStart != m_lastChunkStartTime || tEnd != m_lastChunkEndTime) { readyToProcess = false; }
//checks for problems, buffer lengths differents...
if (tEnd - tStart != m_lastChunkEndTime - m_lastChunkStartTime)
{
//marks everything as deprecated and sends a error
for (size_t input = 0; input < m_nInput; ++input)
{
for (size_t chunk = 0; chunk < boxIO->getInputChunkCount(input); ++chunk) { boxIO->markInputAsDeprecated(input, chunk); }
}
//readyToProcess = false;
OV_ERROR_KRF("Invalid incoming input chunks: duration differs between chunks", Kernel::ErrorType::BadInput);
}
}
else { readyToProcess = false; }
}
//If there is one buffer of the same time period per input, process
if (readyToProcess) { getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess(); }
return true;
}
bool CBoxAlgorithmFeatureAggregator::process()
{
const Kernel::IBox* boxContext = getBoxAlgorithmContext()->getStaticBoxContext();
Kernel::IBoxIO* boxIO = getBoxAlgorithmContext()->getDynamicBoxContext();
CMatrix* oMatrix = m_encoder->getInputMatrix();
std::vector<double> bufferElements;
size_t totalBufferSize = 0;
bool bufferReceived = false;
for (size_t input = 0; input < boxContext->getInputCount(); ++input)
{
m_decoder[input]->decode(0);
//*
if ((m_decoder[input]->isHeaderReceived()) && !m_headerSent)
{
//getBoxAlgorithmContext()->getPlayerContext()->getLogManager() << Kernel::LogLevel_Warning << "header " << input << "\n";
CMatrix* iMatrix = m_decoder[input]->getOutputMatrix();
totalBufferSize += iMatrix->getBufferElementCount();
if (input == boxContext->getInputCount() - 1)
{
oMatrix->resize(totalBufferSize);
for (size_t i = 0; i < totalBufferSize; ++i) { oMatrix->setDimensionLabel(0, i, ("Feature " + std::to_string(i + 1)).c_str()); }
m_encoder->encodeHeader();
boxIO->markOutputAsReadyToSend(0, m_lastChunkStartTime, m_lastChunkEndTime);
m_headerSent = true;
}
}
//*/
if (m_decoder[input]->isBufferReceived())
{
bufferReceived = true;
CMatrix* iMatrix = m_decoder[input]->getOutputMatrix();
const size_t size = iMatrix->getBufferElementCount();
double* buffer = iMatrix->getBuffer();
for (size_t i = 0; i < size; ++i) { bufferElements.push_back(buffer[i]); }
}
}
if (m_headerSent && bufferReceived)
{
double* oBuffer = oMatrix->getBuffer();
for (size_t i = 0; i < bufferElements.size(); ++i) { oBuffer[i] = bufferElements[i]; }
m_encoder->encodeBuffer();
boxIO->markOutputAsReadyToSend(0, m_lastChunkStartTime, m_lastChunkEndTime);
}
return true;
}
} // namespace FeatureExtraction
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,115 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <string>
#include <vector>
#include <queue>
namespace OpenViBE {
namespace Plugins {
namespace FeatureExtraction {
/**
* Main plugin class of the feature aggregator plugins.
* Aggregates the features received in a feature vector then outputs it.
* */
class CBoxAlgorithmFeatureAggregator final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
CBoxAlgorithmFeatureAggregator() { }
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
bool processInput(const size_t index) override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_FeatureAggregator)
protected:
//codecs
Toolkit::TFeatureVectorEncoder<CBoxAlgorithmFeatureAggregator>* m_encoder = nullptr;
std::vector<Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmFeatureAggregator>*> m_decoder;
// contains the labels for each dimension for each input
std::vector<std::vector<std::vector<std::string>>> m_featureNames;
// contains the dimension size for each dimension of each input
std::vector<std::vector<size_t>> m_dimSize;
// contains the input buffer's total size for each input
std::vector<size_t> m_iBufferSizes;
//start time and end time of the last arrived chunk
uint64_t m_lastChunkStartTime = 0;
uint64_t m_lastChunkEndTime = 0;
// number of inputs
size_t m_nInput = 0;
bool m_headerSent = false;
};
class CBoxAlgorithmFeatureAggregatorListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
bool check(Kernel::IBox& box) const
{
for (size_t i = 0; i < box.getInputCount(); ++i)
{
box.setInputName(i, ("Input stream " + std::to_string(i + 1)).c_str());
box.setInputType(i, OV_TypeId_StreamedMatrix);
}
return true;
}
bool onInputRemoved(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
bool onInputAdded(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
};
/**
* Plugin's description
*/
class CBoxAlgorithmFeatureAggregatorDesc final : public IBoxAlgorithmDesc
{
public:
CString getName() const override { return CString("Feature aggregator"); }
CString getAuthorName() const override { return CString("Bruno Renier"); }
CString getAuthorCompanyName() const override { return CString("INRIA/IRISA"); }
CString getShortDescription() const override { return CString("Aggregates input to feature vectors"); }
CString getDetailedDescription() const override { return CString("Each chunk of input will be catenated into one feature vector."); }
CString getCategory() const override { return CString("Feature extraction"); }
CString getVersion() const override { return CString("1.0"); }
CString getSoftwareComponent() const override { return CString("openvibe-sdk"); }
CString getAddedSoftwareVersion() const override { return CString("0.0.0"); }
CString getUpdatedSoftwareVersion() const override { return CString("0.0.0"); }
void release() override { }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_FeatureAggregator; }
IPluginObject* create() override { return new CBoxAlgorithmFeatureAggregator(); }
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmFeatureAggregatorListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input stream 1", OV_TypeId_StreamedMatrix);
// prototype.addInput("Input stream 2", OV_TypeId_StreamedMatrix);
prototype.addOutput("Feature vector stream", OV_TypeId_FeatureVector);
prototype.addFlag(Kernel::BoxFlag_CanAddInput);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_FeatureAggregatorDesc)
};
} // namespace FeatureExtraction
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,6 @@
#pragma once
// Boxes
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_BoxAlgorithm_FeatureAggregator OpenViBE::CIdentifier(0x00682417, 0x453635F9)
#define OVP_ClassId_BoxAlgorithm_FeatureAggregatorDesc OpenViBE::CIdentifier(0x00B5B638, 0x25821BAF)
@@ -0,0 +1,15 @@
#include "ovp_defines.h"
#include "box-algorithms/ovpCBoxAlgorithmFeatureAggregator.h"
namespace OpenViBE {
namespace Plugins {
namespace FeatureExtraction {
OVP_Declare_Begin()
OVP_Declare_New(CBoxAlgorithmFeatureAggregatorDesc);
OVP_Declare_End()
} // namespace FeatureExtraction
} // namespace Plugins
} // namespace OpenViBE