VideoCodec/Modules/Inspection/External.cpp
#include "External.h"
#include "../../External/Octave/engine.h"
namespace VideoCodec
{
External::External() : Module(EXTERNAL_MODULE_ID)
{
#ifdef EXTERNAL_ENABLED
// Instantiate and store a Matlab instance to use.
#ifdef USE_MATLAB
this->engine = engOpen(MATLAB_RUN_COMMAND);
#endif
#ifdef USE_OCTAVE
this->engine = engOpen("\0");
#endif
if (engine == NULL)
{
Logger::LogMessage("Error instantiating external engine.");
return;
}
else
{
Logger::LogMessage("Started external engine.");
}
#endif
}
External::~External()
{
#ifdef EXTERNAL_ENABLED
// Destroy any stored engine.
if (this->engine != NULL)
engClose(this->engine);
this->engine = NULL;
Logger::LogMessage("Closed external engine.");
#endif
}
void External::Execute(std::string command)
{
#ifdef USE_MATLAB
engEvalString(this->engine, command.c_str());
#endif
#ifdef USE_OCTAVE
engEvalString(this->engine, (char*)command.c_str(), command.length() + 1);
#endif
}
void External::ShowPieChart(double* values, unsigned int count)
{
#ifdef USE_MATLAB
mxArray* mValues = NULL;
// Copy the values into a Matlab format.
mValues = mxCreateDoubleMatrix(1, count + 1, mxREAL);
memcpy((void*)mxGetPr(mValues), (void*)values, sizeof(double) * count);
engPutVariable(this->engine, "V", mValues);
engEvalString(this->engine, "figure;");
engEvalString(this->engine, "pie(V);");
engEvalString(this->engine, "title('Pie chart');");
#endif
#ifdef USE_OCTAVE
std::stringstream command;
command << "V = [";
for (UnsignedShort i = 0; i < count; i++)
command << (double)values[i] << " ";
command << "]; ";
command << "hold off; pie(V); title('Pie chart');";
engEvalString(this->engine, (char*)command.str().c_str(), count * 5 + 100);
Logger::LogMessage("Press any key to continue.");
fgetc(stdin);
#endif
}
void External::ShowPackedRGBImage(UnsignedByte* values, unsigned short pixelColumns, unsigned short pixelRows)
{
#ifdef USE_MATLAB
mxArray* pixelValues = NULL;
// Allocate the pixel array in Matlab and copy the values in.
pixelValues = mxCreateNumericMatrix(1, pixelRows * pixelColumns * 3, mxUINT8_CLASS, mxREAL);
memcpy((void*)mxGetPr(pixelValues), (void*)values, sizeof(UnsignedByte) * pixelRows * pixelColumns * 3);
// Various modifications must be made to the pixel data at this stage, within Matlab.
// First, matrices must be extracted into separate R, G, B planes.
// Then the resulting matrices must be reshaped into rectangular matrices.
// The matrices are then concatenated.
// Finally, the values must be normalized within [0 255].
engPutVariable(this->engine, "packedRGB", pixelValues);
std::stringstream command;
command << "r = packedRGB(1:3:end); g = packedRGB(2:3:end); b = packedRGB(3:3:end); r = (reshape(r, "
<< pixelColumns << ", " << pixelRows << ")'); g = (reshape(g, "
<< pixelColumns << ", " << pixelRows << ")'); b = (reshape(b, "
<< pixelColumns << ", " << pixelRows << ")'); figure; image(cat(3, r, g, b)); hold on; axis image; hold off;";
engEvalString(this->engine, command.str().c_str());
#endif
}
void External::ShowImage(UnsignedByte* values, unsigned char columns, unsigned char rows)
{
#ifdef USE_MATLAB
mxArray* mValues = NULL;
// Copy the values into the Matlab matrix.
mValues = mxCreateNumericMatrix(rows, columns, mxUINT8_CLASS, mxREAL);
memcpy((void*)mxGetPr(mValues), (void*)values, sizeof(UnsignedByte) * rows * columns);
this->showMatlabImage(mValues);
#endif
}
void External::ShowImage(SignedShort* values, unsigned char columns, unsigned char rows)
{
#ifdef USE_MATLAB
mxArray* mValues = NULL;
// Copy the values into the Matlab matrix.
mValues = mxCreateNumericMatrix(rows, columns, mxINT16_CLASS, mxREAL);
memcpy((void*)mxGetPr(mValues), (void*)values, sizeof(SignedShort) * rows * columns);
this->showMatlabImage(mValues);
#endif
}
void External::showMatlabImage(mxArray* mValues)
{
#ifdef USE_MATLAB
engPutVariable(this->engine, "img", mValues);
engEvalString(this->engine, "figure;");
engEvalString(this->engine, "imagesc(img, [0 255]), colormap(gray)");
#endif
}
void External::ShowVectorField(SignedByte* xComponents, SignedByte* yComponents, unsigned char columns, unsigned char rows, unsigned char vectorScaleFactor)
{
#ifdef USE_MATLAB
mxArray* xValues = NULL;
mxArray* yValues = NULL;
int valueCount = (int)columns * (int)rows;
xValues = mxCreateNumericMatrix(1, valueCount, mxINT8_CLASS, mxREAL);
yValues = mxCreateNumericMatrix(1, valueCount, mxINT8_CLASS, mxREAL);
memcpy((void*)mxGetPr(xValues), (void*)xComponents, valueCount * sizeof(SignedByte));
memcpy((void*)mxGetPr(yValues), (void*)yComponents, valueCount * sizeof(SignedByte));
engPutVariable(this->engine, "xValues", xValues);
engPutVariable(this->engine, "yValues", yValues);
std::stringstream command;
command << "[xStep, yStep] = meshGrid("
<< (int)rows << ":-1:1, 1:" << (int)columns
<< "); xStep = reshape(xStep, 1, " << (int)rows << " * " << (int)columns
<< "); yStep = reshape(yStep, 1, " << (int)rows << " * " << (int)columns
<< "); figure; quiver(yStep, xStep, xValues, yValues, "
<< (int)vectorScaleFactor << " / 16);";
engEvalString(this->engine, command.str().c_str());
#endif
#ifdef USE_OCTAVE
std::stringstream command;
command << "xValues = [";
for (UnsignedShort i = 0; i < columns * rows; i++)
command << ((double)xComponents[i] * vectorScaleFactor / 16.0) << " ";
command << "]; yValues = [";
for (UnsignedShort i = 0; i < columns * rows; i++)
command << ((double)yComponents[i] * vectorScaleFactor / 16.0) << " ";
command << "]; [xStep, yStep] = meshgrid("
<< (int)rows << ":-1:1, 1:" << (int)columns
<< "); xStep = reshape(xStep, 1, " << (int)rows << " * " << (int)columns
<< "); yStep = reshape(yStep, 1, " << (int)rows << " * " << (int)columns
<< "); quiver(yStep, xStep, xValues, yValues);";
engEvalString(this->engine, (char*)command.str().c_str(), rows * columns * 2 * 4 + 500);
Logger::LogMessage("Press any key to continue.");
fgetc(stdin);
#endif
}
ConfigurationStatus External::Configure(ConfigurationElement* configuration)
{
return MODULE_CONFIGURATION_OK;
}
}