Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cefc66019 | ||
|
|
53ddd3e6bf | ||
|
|
0355c7eba7 | ||
|
|
d62d5a5c3e | ||
|
|
468449398a |
@@ -133,6 +133,14 @@ IF( USE_FFMPEG )
|
||||
ENDIF()
|
||||
SET_PACKAGE_PROPERTIES(FFmpeg PROPERTIES URL "http://ffmpeg.org/" DESCRIPTION "Libav library support in CalypStream" TYPE OPTIONAL)
|
||||
|
||||
OPTION( USE_PYTHON "Add Python support" ON )
|
||||
IF( USE_PYTHON )
|
||||
#FIND_PACKAGE(Python2 REQUIRED COMPONENTS Development NumPy)
|
||||
FIND_PACKAGE(Python3 REQUIRED COMPONENTS Development NumPy)
|
||||
LIST(APPEND PYTHON_LINKER_LIBRARIES Python3::Python Python3::NumPy )
|
||||
ENDIF()
|
||||
SET_PACKAGE_PROPERTIES(Python PROPERTIES URL "http://ffmpeg.org/" DESCRIPTION "Python support in Calyp modules" TYPE OPTIONAL)
|
||||
|
||||
IF( WIN32 )
|
||||
SET( USE_STATIC ON )
|
||||
INCLUDE( cmake/Win32.cmake )
|
||||
|
||||
@@ -21,6 +21,11 @@ MACRO(ADD_MODULE name file )
|
||||
UNSET(__modulename)
|
||||
ENDMACRO()
|
||||
|
||||
MACRO(ADD_PYTHON_MODULE name file )
|
||||
IF( ${Python3_FOUND} )
|
||||
ADD_MODULE( ${name} ${file} )
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO(ADD_MODULE_USE_OPENCV name file )
|
||||
IF( USE_OPENCV )
|
||||
|
||||
@@ -53,6 +53,12 @@ IF( USE_OPENCV )
|
||||
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS} )
|
||||
ENDIF()
|
||||
|
||||
IF( USE_PYTHON )
|
||||
LIST( APPEND Calyp_Lib_SRCS CalypPythonModuleIf.h )
|
||||
LIST( APPEND Calyp_Lib_SRCS CalypPythonModuleIf.cpp )
|
||||
LIST(APPEND CMAKE_CFG_LINKER_LIBSS ${PYTHON_LINKER_LIBRARIES} )
|
||||
ENDIF()
|
||||
|
||||
set(Calyp_Lib_HEADERS
|
||||
CalypDefs.h
|
||||
CalypFrame.h
|
||||
@@ -76,6 +82,7 @@ ENDIF()
|
||||
TARGET_LINK_LIBRARIES( ${PROJECT_LIBRARY}
|
||||
${FFMPEG_LIBRARIES}
|
||||
${OpenCV_LIBRARIES}
|
||||
${PYTHON_LINKER_LIBRARIES}
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(${PROJECT_LIBRARY}
|
||||
|
||||
+15
-30
@@ -102,7 +102,6 @@ public:
|
||||
int m_iPixelFormat; //!< Pixel format number (it follows the list of supported pixel formats)
|
||||
unsigned int m_uiBitsPel; //!< Bits per pixel/channel
|
||||
unsigned int m_uiHalfPelValue; //!< Bits per pixel/channel
|
||||
bool m_bHasNegativeValues; //!< Half of the scale correspond to negative values
|
||||
|
||||
ClpPel*** m_pppcInputPel;
|
||||
|
||||
@@ -119,12 +118,15 @@ public:
|
||||
/** Numbers of histogram segments depending of image bytes depth*/
|
||||
unsigned int m_uiHistoSegments;
|
||||
|
||||
/**
|
||||
* Common constructor function of a frame
|
||||
*
|
||||
* @param width width of the frame
|
||||
* @param height height of the frame
|
||||
* @param pel_format pixel format index (always use PixelFormats enum)
|
||||
*
|
||||
*/
|
||||
void init( unsigned int width, unsigned int height, int pel_format, unsigned bitsPixel )
|
||||
{
|
||||
init( width, height, pel_format, bitsPixel, false );
|
||||
}
|
||||
|
||||
void init( unsigned int width, unsigned int height, int pel_format, unsigned bitsPixel, bool has_negative_values )
|
||||
{
|
||||
m_bInit = false;
|
||||
m_bHasRGBPel = false;
|
||||
@@ -135,7 +137,6 @@ public:
|
||||
m_iPixelFormat = pel_format;
|
||||
m_uiBitsPel = bitsPixel < 8 ? 8 : bitsPixel;
|
||||
m_uiHalfPelValue = 1 << ( m_uiBitsPel - 1 );
|
||||
m_bHasNegativeValues = has_negative_values;
|
||||
|
||||
if( m_uiWidth == 0 || m_uiHeight == 0 || m_iPixelFormat == -1 || bitsPixel > 16 )
|
||||
{
|
||||
@@ -264,16 +265,10 @@ CalypFrame::CalypFrame( unsigned int width, unsigned int height, int pelFormat,
|
||||
d->init( width, height, pelFormat, bitsPixel );
|
||||
}
|
||||
|
||||
CalypFrame::CalypFrame( unsigned int width, unsigned int height, int pelFormat, unsigned bitsPixel, bool has_negative_values )
|
||||
: d( new CalypFramePrivate )
|
||||
{
|
||||
d->init( width, height, pelFormat, bitsPixel, has_negative_values );
|
||||
}
|
||||
|
||||
CalypFrame::CalypFrame( const CalypFrame& other )
|
||||
: d( new CalypFramePrivate )
|
||||
{
|
||||
d->init( other.getWidth(), other.getHeight(), other.getPelFormat(), other.getBitsPel(), other.getHasNegativeValues() );
|
||||
d->init( other.getWidth(), other.getHeight(), other.getPelFormat(), other.getBitsPel() );
|
||||
copyFrom( &other );
|
||||
}
|
||||
|
||||
@@ -282,7 +277,7 @@ CalypFrame::CalypFrame( const CalypFrame* other )
|
||||
{
|
||||
if( other )
|
||||
{
|
||||
d->init( other->getWidth(), other->getHeight(), other->getPelFormat(), other->getBitsPel(), other->getHasNegativeValues() );
|
||||
d->init( other->getWidth(), other->getHeight(), other->getPelFormat(), other->getBitsPel() );
|
||||
copyFrom( other );
|
||||
}
|
||||
}
|
||||
@@ -402,11 +397,6 @@ unsigned CalypFrame::getHeight( unsigned channel ) const
|
||||
return CHROMASHIFT( d->m_uiHeight, channel > 0 ? d->m_pcPelFormat->log2ChromaHeight : 0 );
|
||||
}
|
||||
|
||||
bool CalypFrame::getHasNegativeValues() const
|
||||
{
|
||||
return d->m_bHasNegativeValues;
|
||||
}
|
||||
|
||||
ClpULong CalypFrame::getPixels( unsigned channel ) const
|
||||
{
|
||||
return getWidth( channel ) * getHeight( channel );
|
||||
@@ -500,24 +490,19 @@ unsigned char* CalypFrame::getRGBBuffer() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ClpPel CalypFrame::operator()( unsigned int ch, unsigned int xPos, unsigned int yPos, bool absolute ) const
|
||||
ClpPel CalypFrame::operator()( unsigned int ch, unsigned int xPos, unsigned int yPos )
|
||||
{
|
||||
int retValue = 0;
|
||||
if( ch < d->m_pcPelFormat->numberChannels )
|
||||
{
|
||||
retValue = d->m_pppcInputPel[ch][yPos][xPos];
|
||||
if( !absolute && d->m_bHasNegativeValues )
|
||||
retValue = retValue - int(d->m_uiHalfPelValue);
|
||||
}
|
||||
return ClpPel( retValue );
|
||||
return d->m_pppcInputPel[ch][yPos][xPos];
|
||||
return 0;
|
||||
}
|
||||
|
||||
CalypPixel CalypFrame::operator()( unsigned int xPos, unsigned int yPos ) const
|
||||
CalypPixel CalypFrame::operator()( unsigned int xPos, unsigned int yPos )
|
||||
{
|
||||
return getPixel( xPos, yPos );
|
||||
}
|
||||
|
||||
CalypPixel CalypFrame::getPixel( unsigned int xPos, unsigned int yPos ) const
|
||||
CalypPixel CalypFrame::getPixel( unsigned int xPos, unsigned int yPos )
|
||||
{
|
||||
CalypPixel PixelValue( d->m_pcPelFormat->colorSpace );
|
||||
for( unsigned int ch = 0; ch < d->m_pcPelFormat->numberChannels; ch++ )
|
||||
|
||||
+4
-23
@@ -113,17 +113,6 @@ public:
|
||||
*/
|
||||
CalypFrame( unsigned int width, unsigned int height, int pelFormat, unsigned bitsPixel = 8 );
|
||||
|
||||
/**
|
||||
* Creates a new frame using the following configuration
|
||||
*
|
||||
* @param width width of the frame
|
||||
* @param height height of the frame
|
||||
* @param pel_format pixel format index (always use PixelFormats enum)
|
||||
*
|
||||
* @note this function might misbehave if the pixel format enum is not correct
|
||||
*/
|
||||
CalypFrame( unsigned int width, unsigned int height, int pelFormat, unsigned bitsPixel, bool has_negative_values );
|
||||
|
||||
/**
|
||||
* Copy contructor
|
||||
*
|
||||
@@ -208,12 +197,6 @@ public:
|
||||
*/
|
||||
unsigned int getHeight( unsigned channel = 0 ) const;
|
||||
|
||||
/**
|
||||
* Check if frame has negative values
|
||||
* @return Boolean with the flag value
|
||||
*/
|
||||
bool getHasNegativeValues() const;
|
||||
|
||||
/**
|
||||
* Get number of pixels of the frame
|
||||
* @param channel/component
|
||||
@@ -274,14 +257,13 @@ public:
|
||||
unsigned char* getRGBBuffer() const;
|
||||
|
||||
/**
|
||||
* Get pixel value at coordinates
|
||||
* Get pixel value at coordinates
|
||||
* @param ch frame channel
|
||||
* @param xPos position in X axis
|
||||
* @param yPos position in Y axis
|
||||
* @param absolute whether it should return positive/negative values
|
||||
* @return pixel value
|
||||
*/
|
||||
ClpPel operator()( unsigned int ch, unsigned int xPos, unsigned int yPos, bool absolute = true ) const;
|
||||
ClpPel operator()( unsigned int ch, unsigned int xPos, unsigned int yPos );
|
||||
|
||||
/**
|
||||
* Get pixel value at coordinates
|
||||
@@ -289,7 +271,7 @@ public:
|
||||
* @param yPos position in Y axis
|
||||
* @return pixel value
|
||||
*/
|
||||
CalypPixel operator()( unsigned int xPos, unsigned int yPos ) const;
|
||||
CalypPixel operator()( unsigned int xPos, unsigned int yPos );
|
||||
|
||||
/**
|
||||
* Get pixel value at coordinates
|
||||
@@ -297,8 +279,7 @@ public:
|
||||
* @param yPos position in Y axis
|
||||
* @return pixel value
|
||||
*/
|
||||
CalypPixel getPixel( unsigned int xPos, unsigned int yPos ) const;
|
||||
|
||||
CalypPixel getPixel( unsigned int xPos, unsigned int yPos );
|
||||
|
||||
/**
|
||||
* Get pixel value at coordinates
|
||||
|
||||
@@ -0,0 +1,500 @@
|
||||
/* This file is a part of Calyp project
|
||||
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
|
||||
* Luis Lucas (luisfrlucas@gmail.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file CalypPythonModuleIf.cpp
|
||||
* \brief Calyp modules interface for python
|
||||
*/
|
||||
|
||||
#include "CalypPythonModuleIf.h"
|
||||
|
||||
bool CalypPythonModuleIf::m_sbPythonInitialized = false;
|
||||
|
||||
// OpenCV
|
||||
#include <opencv2/core/mat.hpp>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
// Python
|
||||
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
|
||||
#include <numpy/arrayobject.h>
|
||||
|
||||
static PyObject* opencv_error = 0;
|
||||
|
||||
static int failmsg( const char* fmt, ... )
|
||||
{
|
||||
char str[1000];
|
||||
|
||||
va_list ap;
|
||||
va_start( ap, fmt );
|
||||
vsnprintf( str, sizeof( str ), fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
PyErr_SetString( PyExc_TypeError, str );
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ArgInfo
|
||||
{
|
||||
const char* name;
|
||||
bool outputarg;
|
||||
// more fields may be added if necessary
|
||||
|
||||
ArgInfo( const char* name_, bool outputarg_ )
|
||||
: name( name_ )
|
||||
, outputarg( outputarg_ ) {}
|
||||
|
||||
// to match with older pyopencv_to function signature
|
||||
operator const char*() const { return name; }
|
||||
};
|
||||
|
||||
class PyAllowThreads
|
||||
{
|
||||
public:
|
||||
PyAllowThreads()
|
||||
: _state( PyEval_SaveThread() ) {}
|
||||
~PyAllowThreads()
|
||||
{
|
||||
PyEval_RestoreThread( _state );
|
||||
}
|
||||
|
||||
private:
|
||||
PyThreadState* _state;
|
||||
};
|
||||
|
||||
class PyEnsureGIL
|
||||
{
|
||||
public:
|
||||
PyEnsureGIL()
|
||||
: _state( PyGILState_Ensure() ) {}
|
||||
~PyEnsureGIL()
|
||||
{
|
||||
PyGILState_Release( _state );
|
||||
}
|
||||
|
||||
private:
|
||||
PyGILState_STATE _state;
|
||||
};
|
||||
|
||||
#define ERRWRAP2( expr ) \
|
||||
try \
|
||||
{ \
|
||||
PyAllowThreads allowThreads; \
|
||||
expr; \
|
||||
} \
|
||||
catch( const cv::Exception& e ) \
|
||||
{ \
|
||||
PyErr_SetString( opencv_error, e.what() ); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
using namespace cv;
|
||||
|
||||
class NumpyAllocator : public MatAllocator
|
||||
{
|
||||
public:
|
||||
NumpyAllocator() { stdAllocator = Mat::getStdAllocator(); }
|
||||
~NumpyAllocator() {}
|
||||
|
||||
UMatData* allocate( PyObject* o, int dims, const int* sizes, int type, size_t* step ) const
|
||||
{
|
||||
UMatData* u = new UMatData( this );
|
||||
u->data = u->origdata = (uchar*)PyArray_DATA( (PyArrayObject*)o );
|
||||
npy_intp* _strides = PyArray_STRIDES( (PyArrayObject*)o );
|
||||
for( int i = 0; i < dims - 1; i++ )
|
||||
step[i] = (size_t)_strides[i];
|
||||
step[dims - 1] = CV_ELEM_SIZE( type );
|
||||
u->size = sizes[0] * step[0];
|
||||
u->userdata = o;
|
||||
return u;
|
||||
}
|
||||
|
||||
UMatData* allocate( int dims0, const int* sizes, int type, void* data, size_t* step, int flags, UMatUsageFlags usageFlags ) const
|
||||
{
|
||||
if( data != 0 )
|
||||
{
|
||||
// issue #6969: CV_Error(Error::StsAssert, "The data should normally be NULL!");
|
||||
// probably this is safe to do in such extreme case
|
||||
return stdAllocator->allocate( dims0, sizes, type, data, step, flags, usageFlags );
|
||||
}
|
||||
PyEnsureGIL gil;
|
||||
|
||||
int depth = CV_MAT_DEPTH( type );
|
||||
int cn = CV_MAT_CN( type );
|
||||
const int f = (int)( sizeof( size_t ) / 8 );
|
||||
int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE : depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT : depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT : depth == CV_64F ? NPY_DOUBLE : f * NPY_ULONGLONG + ( f ^ 1 ) * NPY_UINT;
|
||||
int i, dims = dims0;
|
||||
cv::AutoBuffer<npy_intp> _sizes( dims + 1 );
|
||||
for( i = 0; i < dims; i++ )
|
||||
_sizes[i] = sizes[i];
|
||||
if( cn > 1 )
|
||||
_sizes[dims++] = cn;
|
||||
PyObject* o = PyArray_SimpleNew( dims, _sizes, typenum );
|
||||
if( !o )
|
||||
CV_Error_( Error::StsError, ( "The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims ) );
|
||||
return allocate( o, dims0, sizes, type, step );
|
||||
}
|
||||
|
||||
bool allocate( UMatData* u, int accessFlags, UMatUsageFlags usageFlags ) const
|
||||
{
|
||||
return stdAllocator->allocate( u, accessFlags, usageFlags );
|
||||
}
|
||||
|
||||
void deallocate( UMatData* u ) const
|
||||
{
|
||||
if( !u )
|
||||
return;
|
||||
PyEnsureGIL gil;
|
||||
CV_Assert( u->urefcount >= 0 );
|
||||
CV_Assert( u->refcount >= 0 );
|
||||
if( u->refcount == 0 )
|
||||
{
|
||||
PyObject* o = (PyObject*)u->userdata;
|
||||
Py_XDECREF( o );
|
||||
delete u;
|
||||
}
|
||||
}
|
||||
|
||||
const MatAllocator* stdAllocator;
|
||||
};
|
||||
|
||||
NumpyAllocator g_numpyAllocator;
|
||||
|
||||
template <typename T>
|
||||
static bool pyopencv_to( PyObject* obj, T& p, const char* name = "<unknown>" );
|
||||
|
||||
template <typename T>
|
||||
static PyObject* pyopencv_from( const T& src );
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_NONE = 0,
|
||||
ARG_MAT = 1,
|
||||
ARG_SCALAR = 2
|
||||
};
|
||||
|
||||
// special case, when the converter needs full ArgInfo structure
|
||||
static bool pyopencv_to( PyObject* o, Mat& m, const ArgInfo info )
|
||||
{
|
||||
bool allowND = true;
|
||||
if( !o || o == Py_None )
|
||||
{
|
||||
if( !m.data )
|
||||
m.allocator = &g_numpyAllocator;
|
||||
return true;
|
||||
}
|
||||
|
||||
// if( PyInt_Check(o) )
|
||||
// {
|
||||
// double v[] = {static_cast<double>(PyInt_AsLong((PyObject*)o)), 0., 0., 0.};
|
||||
// m = Mat(4, 1, CV_64F, v).clone();
|
||||
// return true;
|
||||
// }
|
||||
if( PyFloat_Check( o ) )
|
||||
{
|
||||
double v[] = {PyFloat_AsDouble( (PyObject*)o ), 0., 0., 0.};
|
||||
m = Mat( 4, 1, CV_64F, v ).clone();
|
||||
return true;
|
||||
}
|
||||
if( PyTuple_Check( o ) )
|
||||
{
|
||||
int i, sz = (int)PyTuple_Size( (PyObject*)o );
|
||||
m = Mat( sz, 1, CV_64F );
|
||||
for( i = 0; i < sz; i++ )
|
||||
{
|
||||
PyObject* oi = PyTuple_GET_ITEM( o, i );
|
||||
// if( PyInt_Check(oi) )
|
||||
// m.at<double>(i) = (double)PyInt_AsLong(oi);
|
||||
// else
|
||||
if( PyFloat_Check( oi ) )
|
||||
m.at<double>( i ) = (double)PyFloat_AsDouble( oi );
|
||||
else
|
||||
{
|
||||
failmsg( "%s is not a numerical tuple", info.name );
|
||||
m.release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if( !PyArray_Check( o ) )
|
||||
{
|
||||
failmsg( "%s is not a numpy array, neither a scalar", info.name );
|
||||
return false;
|
||||
}
|
||||
|
||||
PyArrayObject* oarr = (PyArrayObject*)o;
|
||||
|
||||
bool needcopy = false, needcast = false;
|
||||
int typenum = PyArray_TYPE( oarr ), new_typenum = typenum;
|
||||
int type = typenum == NPY_UBYTE ? CV_8U :
|
||||
typenum == NPY_BYTE ? CV_8S :
|
||||
typenum == NPY_USHORT ? CV_16U :
|
||||
typenum == NPY_SHORT ? CV_16S :
|
||||
typenum == NPY_INT ? CV_32S :
|
||||
typenum == NPY_INT32 ? CV_32S :
|
||||
typenum == NPY_FLOAT ? CV_32F :
|
||||
typenum == NPY_DOUBLE ? CV_64F : -1;
|
||||
|
||||
if( type < 0 )
|
||||
{
|
||||
if( typenum == NPY_INT64 || typenum == NPY_UINT64 || typenum == NPY_LONG )
|
||||
{
|
||||
needcopy = needcast = true;
|
||||
new_typenum = NPY_INT;
|
||||
type = CV_32S;
|
||||
}
|
||||
else
|
||||
{
|
||||
failmsg( "%s data type = %d is not supported", info.name, typenum );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CV_MAX_DIM
|
||||
const int CV_MAX_DIM = 32;
|
||||
#endif
|
||||
|
||||
int ndims = PyArray_NDIM( oarr );
|
||||
if( ndims >= CV_MAX_DIM )
|
||||
{
|
||||
failmsg( "%s dimensionality (=%d) is too high", info.name, ndims );
|
||||
return false;
|
||||
}
|
||||
|
||||
int size[CV_MAX_DIM + 1];
|
||||
size_t step[CV_MAX_DIM + 1];
|
||||
size_t elemsize = CV_ELEM_SIZE1( type );
|
||||
const npy_intp* _sizes = PyArray_DIMS( oarr );
|
||||
const npy_intp* _strides = PyArray_STRIDES( oarr );
|
||||
bool ismultichannel = ndims == 3 && _sizes[2] <= CV_CN_MAX;
|
||||
|
||||
for( int i = ndims - 1; i >= 0 && !needcopy; i-- )
|
||||
{
|
||||
// these checks handle cases of
|
||||
// a) multi-dimensional (ndims > 2) arrays, as well as simpler 1- and 2-dimensional cases
|
||||
// b) transposed arrays, where _strides[] elements go in non-descending order
|
||||
// c) flipped arrays, where some of _strides[] elements are negative
|
||||
// the _sizes[i] > 1 is needed to avoid spurious copies when NPY_RELAXED_STRIDES is set
|
||||
if( ( i == ndims - 1 && _sizes[i] > 1 && (size_t)_strides[i] != elemsize ) ||
|
||||
( i < ndims - 1 && _sizes[i] > 1 && _strides[i] < _strides[i + 1] ) )
|
||||
needcopy = true;
|
||||
}
|
||||
|
||||
if( ismultichannel && _strides[1] != (npy_intp)elemsize * _sizes[2] )
|
||||
needcopy = true;
|
||||
|
||||
if( needcopy )
|
||||
{
|
||||
if( info.outputarg )
|
||||
{
|
||||
failmsg( "Layout of the output array %s is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)", info.name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( needcast )
|
||||
{
|
||||
o = PyArray_Cast( oarr, new_typenum );
|
||||
oarr = (PyArrayObject*)o;
|
||||
}
|
||||
else
|
||||
{
|
||||
oarr = PyArray_GETCONTIGUOUS( oarr );
|
||||
o = (PyObject*)oarr;
|
||||
}
|
||||
|
||||
_strides = PyArray_STRIDES( oarr );
|
||||
}
|
||||
|
||||
// Normalize strides in case NPY_RELAXED_STRIDES is set
|
||||
size_t default_step = elemsize;
|
||||
for( int i = ndims - 1; i >= 0; --i )
|
||||
{
|
||||
size[i] = (int)_sizes[i];
|
||||
if( size[i] > 1 )
|
||||
{
|
||||
step[i] = (size_t)_strides[i];
|
||||
default_step = step[i] * size[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
step[i] = default_step;
|
||||
default_step *= size[i];
|
||||
}
|
||||
}
|
||||
|
||||
// handle degenerate case
|
||||
if( ndims == 0 )
|
||||
{
|
||||
size[ndims] = 1;
|
||||
step[ndims] = elemsize;
|
||||
ndims++;
|
||||
}
|
||||
|
||||
if( ismultichannel )
|
||||
{
|
||||
ndims--;
|
||||
type |= CV_MAKETYPE( 0, size[2] );
|
||||
}
|
||||
|
||||
if( ndims > 2 && !allowND )
|
||||
{
|
||||
failmsg( "%s has more than 2 dimensions", info.name );
|
||||
return false;
|
||||
}
|
||||
|
||||
m = Mat( ndims, size, type, PyArray_DATA( oarr ), step );
|
||||
m.u = g_numpyAllocator.allocate( o, ndims, size, type, step );
|
||||
m.addref();
|
||||
|
||||
if( !needcopy )
|
||||
{
|
||||
Py_INCREF( o );
|
||||
}
|
||||
m.allocator = &g_numpyAllocator;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool pyopencv_to( PyObject* o, Mat& m, const char* name )
|
||||
{
|
||||
return pyopencv_to( o, m, ArgInfo( name, 0 ) );
|
||||
}
|
||||
|
||||
template <typename _Tp, int m, int n>
|
||||
bool pyopencv_to( PyObject* o, Matx<_Tp, m, n>& mx, const ArgInfo info )
|
||||
{
|
||||
Mat tmp;
|
||||
if( !pyopencv_to( o, tmp, info ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp.copyTo( mx );
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename _Tp, int m, int n>
|
||||
bool pyopencv_to( PyObject* o, Matx<_Tp, m, n>& mx, const char* name )
|
||||
{
|
||||
return pyopencv_to( o, mx, ArgInfo( name, 0 ) );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool pyopencv_to( PyObject* o, Ptr<T>& p, const char* name )
|
||||
{
|
||||
if( !o || o == Py_None )
|
||||
return true;
|
||||
p = makePtr<T>();
|
||||
return pyopencv_to( o, *p, name );
|
||||
}
|
||||
|
||||
template <>
|
||||
PyObject* pyopencv_from( const Mat& m )
|
||||
{
|
||||
if( !m.data )
|
||||
Py_RETURN_NONE;
|
||||
Mat temp, *p = (Mat*)&m;
|
||||
if( !p->u || p->allocator != &g_numpyAllocator )
|
||||
{
|
||||
temp.allocator = &g_numpyAllocator;
|
||||
ERRWRAP2( m.copyTo( temp ) );
|
||||
p = &temp;
|
||||
}
|
||||
PyObject* o = (PyObject*)p->u->userdata;
|
||||
Py_INCREF( o );
|
||||
return o;
|
||||
}
|
||||
|
||||
bool CalypPythonModuleIf::create( std::vector<CalypFrame*> apcFrameList )
|
||||
{
|
||||
_BASIC_MODULE_API_2_CHECK_
|
||||
|
||||
// initialize Python embedding
|
||||
if( !m_sbPythonInitialized )
|
||||
{
|
||||
Py_Initialize();
|
||||
|
||||
// Initialize numpy library
|
||||
import_array1( -1 );
|
||||
m_sbPythonInitialized = true;
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject* pName = PyUnicode_DecodeFSDefault( m_pchPythonFunctionName );
|
||||
#else
|
||||
PyObject* pName = PyString_FromString( m_pchPythonFunctionName );
|
||||
#endif
|
||||
m_pyModule = PyImport_Import( pName );
|
||||
m_pyFunction = PyObject_GetAttrString( m_pyModule, "ClpModule" );
|
||||
Py_DECREF( pName );
|
||||
if( !m_pyFunction || !PyCallable_Check( m_pyFunction ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
unsigned pelFormat = m_bConvertToGray ? CalypFrame::findPixelFormat( "GRAY" ) : apcFrameList[0]->getPelFormat();
|
||||
m_pcOutputFrame = new CalypFrame( apcFrameList[0]->getWidth(), apcFrameList[0]->getHeight(), pelFormat, apcFrameList[0]->getBitsPel() );
|
||||
return true;
|
||||
}
|
||||
|
||||
CalypFrame* CalypPythonModuleIf::process( std::vector<CalypFrame*> apcFrameList )
|
||||
{
|
||||
m_pcOutputFrame->reset();
|
||||
if( m_pyFunction && PyCallable_Check( m_pyFunction ) )
|
||||
{
|
||||
Mat cvMatOutput;
|
||||
Mat cvMatInput[m_uiNumberOfFrames];
|
||||
PyObject* pyInputArg = PyTuple_New( apcFrameList.size() );
|
||||
for( unsigned i = 0; i < apcFrameList.size(); i++ )
|
||||
{
|
||||
apcFrameList[0]->toMat( cvMatInput[i], m_bConvertToGray, false );
|
||||
|
||||
PyObject* pyMat = pyopencv_from( cvMatInput[i] );
|
||||
/* pValue reference stolen here: */
|
||||
PyTuple_SetItem( pyInputArg, i, pyMat );
|
||||
}
|
||||
// execute the function
|
||||
PyObject* pyResult = PyEval_CallObject( m_pyFunction, pyInputArg );
|
||||
if( !pyResult )
|
||||
return m_pcOutputFrame;
|
||||
|
||||
pyopencv_to( pyResult, cvMatOutput );
|
||||
|
||||
// decrement the object references
|
||||
Py_XDECREF( pyResult );
|
||||
Py_XDECREF( pyInputArg );
|
||||
|
||||
m_pcOutputFrame->fromMat( cvMatOutput, CLP_LUMA );
|
||||
}
|
||||
return m_pcOutputFrame;
|
||||
}
|
||||
|
||||
void CalypPythonModuleIf::destroy()
|
||||
{
|
||||
Py_XDECREF( m_pyFunction );
|
||||
//#if PY_MAJOR_VERSION >= 3
|
||||
// Py_FinalizeEx();
|
||||
//#else
|
||||
// Py_Finalize();
|
||||
//#endif
|
||||
if( m_pcOutputFrame )
|
||||
delete m_pcOutputFrame;
|
||||
m_pcOutputFrame = NULL;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* This file is a part of Calyp project
|
||||
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
|
||||
* Luis Lucas (luisfrlucas@gmail.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file CalypPythonModuleIf.h
|
||||
* \ingroup CalypLibGroup
|
||||
* \brief Calyp modules interface for python
|
||||
*/
|
||||
|
||||
#ifndef __CALYPPYTHONMODULEIF_H__
|
||||
#define __CALYPPYTHONMODULEIF_H__
|
||||
|
||||
#include "CalypModuleIf.h"
|
||||
|
||||
// Python
|
||||
#include <Python.h>
|
||||
|
||||
/**
|
||||
* \class CalypPythonModuleIf
|
||||
* \ingroup CalypLib Calyp_Modules
|
||||
* \brief Abstract class for modules using python language
|
||||
*/
|
||||
class CalypPythonModuleIf : public CalypModuleIf
|
||||
{
|
||||
private:
|
||||
static bool m_sbPythonInitialized;
|
||||
PyObject* m_pyModule;
|
||||
PyObject* m_pyFunction;
|
||||
|
||||
protected:
|
||||
const char* m_pchPythonFunctionName;
|
||||
bool m_bConvertToGray;
|
||||
|
||||
public:
|
||||
CalypPythonModuleIf()
|
||||
{
|
||||
m_bConvertToGray = false;
|
||||
};
|
||||
virtual ~CalypPythonModuleIf() {}
|
||||
bool create( std::vector<CalypFrame*> apcFrameList );
|
||||
CalypFrame* process( std::vector<CalypFrame*> apcFrameList );
|
||||
void destroy();
|
||||
};
|
||||
|
||||
#endif // __CALYPPYTHONMODULEIF_H__
|
||||
+5
-11
@@ -103,11 +103,11 @@ private:
|
||||
unsigned int m_uiIndex;
|
||||
|
||||
public:
|
||||
CalypStreamBufferPrivate( unsigned int size, unsigned int width, unsigned int height, int pelFormat, int bitsPixel, bool hasNegative )
|
||||
CalypStreamBufferPrivate( unsigned int size, unsigned int width, unsigned int height, int pelFormat, int bitsPixel )
|
||||
{
|
||||
for( unsigned int i = 0; i < size; i++ )
|
||||
{
|
||||
CalypFrame* pFrame = new CalypFrame( width, height, pelFormat, bitsPixel, hasNegative );
|
||||
CalypFrame* pFrame = new CalypFrame( width, height, pelFormat, bitsPixel );
|
||||
m_apcFrameBuffer.push_back( pFrame );
|
||||
}
|
||||
m_uiIndex = 0;
|
||||
@@ -238,7 +238,7 @@ ClpString CalypStream::getCodecName() const
|
||||
return !d->handler ? "" : d->handler->getCodecName();
|
||||
}
|
||||
|
||||
bool CalypStream::open( ClpString filename, ClpString resolution, ClpString input_format_name, unsigned int bitsPel, int endianness, bool hasNegative,
|
||||
bool CalypStream::open( ClpString filename, ClpString resolution, ClpString input_format_name, unsigned int bitsPel, int endianness,
|
||||
unsigned int frame_rate, bool bInput )
|
||||
{
|
||||
unsigned int width = 0;
|
||||
@@ -261,17 +261,11 @@ bool CalypStream::open( ClpString filename, ClpString resolution, ClpString inpu
|
||||
break;
|
||||
}
|
||||
}
|
||||
return open( filename, width, height, input_format, bitsPel, endianness, hasNegative, frame_rate, bInput );
|
||||
return open( filename, width, height, input_format, bitsPel, endianness, frame_rate, bInput );
|
||||
}
|
||||
|
||||
bool CalypStream::open( ClpString filename, unsigned int width, unsigned int height, int input_format, unsigned int bitsPel, int endianness,
|
||||
unsigned int frame_rate, bool bInput )
|
||||
{
|
||||
return open( filename, width, height, input_format, bitsPel, endianness, false, frame_rate, bInput );
|
||||
}
|
||||
|
||||
bool CalypStream::open( ClpString filename, unsigned int width, unsigned int height, int input_format, unsigned int bitsPel, int endianness, bool hasNegative,
|
||||
unsigned int frame_rate, bool bInput )
|
||||
{
|
||||
if( d->isInit )
|
||||
{
|
||||
@@ -320,7 +314,7 @@ bool CalypStream::open( ClpString filename, unsigned int width, unsigned int hei
|
||||
try
|
||||
{
|
||||
d->frameBuffer = new CalypStreamBufferPrivate( d->isInput ? 3 : 1, d->handler->m_uiWidth, d->handler->m_uiHeight,
|
||||
d->handler->m_iPixelFormat, d->handler->m_uiBitsPerPixel, hasNegative );
|
||||
d->handler->m_iPixelFormat, d->handler->m_uiBitsPerPixel );
|
||||
}
|
||||
catch( CalypFailure& e )
|
||||
{
|
||||
|
||||
+1
-4
@@ -72,13 +72,10 @@ public:
|
||||
ClpString getCodecName() const;
|
||||
;
|
||||
|
||||
bool open( ClpString filename, ClpString resolution, ClpString input_format, unsigned int bitsPel, int endianness, bool hasNegative, unsigned int frame_rate,
|
||||
bool open( ClpString filename, ClpString resolution, ClpString input_format, unsigned int bitsPel, int endianness, unsigned int frame_rate,
|
||||
bool bInput );
|
||||
bool open( ClpString filename, unsigned int width, unsigned int height, int input_format, unsigned int bitsPel, int endianness, unsigned int frame_rate,
|
||||
bool bInput );
|
||||
bool open( ClpString filename, unsigned int width, unsigned int height, int input_format, unsigned int bitsPel, int endianness, bool hasNegative, unsigned int frame_rate,
|
||||
bool bInput );
|
||||
|
||||
bool reload();
|
||||
void close();
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ ADD_MODULE_USE_OPENCV( ThreeSixtySpatialtoTemporal "ThreeSixtySpatialtoTemporal"
|
||||
ADD_MODULE_USE_OPENCV( ThreeSixtyFaceExtraction "ThreeSixtyFaceExtraction" VERSION 3.1.0 MODULES core )
|
||||
ADD_MODULE_USE_OPENCV( ThreeSixtyFaceConcatenation "ThreeSixtyFaceConcatenation" VERSION 3.1.0 MODULES core )
|
||||
|
||||
ADD_PYTHON_MODULE( EdgeDetectionPyhton "EdgeDetectionPyhton" )
|
||||
|
||||
IF(EXISTS ${CALYP_EXTRA_MODULES_DIR} )
|
||||
ADD_EXTRA_MODULES( ${CALYP_EXTRA_MODULES_DIR} )
|
||||
ENDIF()
|
||||
@@ -62,7 +64,8 @@ ENDIF()
|
||||
CREATE_MODULE_MACROS()
|
||||
INCLUDE_DIRECTORIES( ${OpenCV_INCLUDE_DIRS} )
|
||||
ADD_LIBRARY( CalypModules ${Calyp_Mod_SRCS} )
|
||||
TARGET_LINK_LIBRARIES( CalypModules ${PROJECT_LIBRARY} ${OpenCV_LIBRARIES} )
|
||||
TARGET_LINK_LIBRARIES( CalypModules ${PROJECT_LIBRARY} ${OpenCV_LIBRARIES} ${PYTHON_LINKER_LIBS} )
|
||||
|
||||
IF( USE_DYNLOAD )
|
||||
TARGET_LINK_LIBRARIES( CalypModules -ldl )
|
||||
ENDIF()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
def ClpModule( img ):
|
||||
edges = cv2.Canny(img,100,200)
|
||||
return edges
|
||||
@@ -0,0 +1,40 @@
|
||||
/* This file is a part of Calyp project
|
||||
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
|
||||
* Luis Lucas (luisfrlucas@gmail.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file EdgeDetectionPyhton.cpp
|
||||
* \brief Binarize frame module
|
||||
*/
|
||||
|
||||
#include "EdgeDetectionPyhton.h"
|
||||
|
||||
EdgeDetectionPyhton::EdgeDetectionPyhton()
|
||||
{
|
||||
/* Module Definition */
|
||||
m_iModuleAPI = CLP_MODULE_API_2;
|
||||
m_iModuleType = CLP_FRAME_PROCESSING_MODULE;
|
||||
m_pchModuleCategory = "Utilities";
|
||||
m_pchModuleName = "PythonEdgeDetection";
|
||||
m_pchModuleLongName = "Python Edge Detection";
|
||||
m_pchModuleTooltip = "Canny Edge Detection using Python interface";
|
||||
m_uiNumberOfFrames = 1;
|
||||
m_uiModuleRequirements = CLP_MODULE_REQUIRES_NOTHING;
|
||||
m_pchPythonFunctionName = "CalypCannyEdge";
|
||||
m_bConvertToGray = true;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/* This file is a part of Calyp project
|
||||
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
|
||||
* Luis Lucas (luisfrlucas@gmail.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file EdgeDetectionPyhton.h
|
||||
* \brief Detect edges using canny algorithm
|
||||
*/
|
||||
|
||||
#ifndef __EDGEDETECTIONPYHTON_H__
|
||||
#define __EDGEDETECTIONPYHTON_H__
|
||||
|
||||
// CalypLib
|
||||
#include "lib/CalypPythonModuleIf.h"
|
||||
|
||||
class EdgeDetectionPyhton : public CalypPythonModuleIf
|
||||
{
|
||||
REGISTER_CLASS_FACTORY( EdgeDetectionPyhton )
|
||||
public:
|
||||
EdgeDetectionPyhton();
|
||||
virtual ~EdgeDetectionPyhton() {}
|
||||
};
|
||||
|
||||
#endif // __EDGEDETECTIONPYHTON_H__
|
||||
@@ -31,7 +31,7 @@ EightBitsSampling::EightBitsSampling()
|
||||
m_iModuleType = CLP_FRAME_PROCESSING_MODULE;
|
||||
m_pchModuleCategory = "Conversions";
|
||||
m_pchModuleName = "BitsResampling";
|
||||
m_pchModuleLongName = "Re-sampling frame (bpp)";
|
||||
m_pchModuleLongName = "Re-sampling frame";
|
||||
m_pchModuleTooltip = "Re-sampling frame to a different value of bits per pixel";
|
||||
m_uiNumberOfFrames = 1;
|
||||
m_uiModuleRequirements = CLP_MODULE_REQUIRES_OPTIONS;
|
||||
|
||||
+22
-31
@@ -38,12 +38,9 @@ FrameDifference::FrameDifference()
|
||||
m_uiNumberOfFrames = 2;
|
||||
|
||||
m_cModuleOptions.addOptions() /**/
|
||||
( "BitsPerpixel", m_uiBitsPixel, "Bits per pixel (use zero to avoid scaling) [0]" ) /**/
|
||||
( "SumOperation", m_uiSumOperation, "Sum instead of difference [0]" );
|
||||
( "Bits per pixel", m_uiBitsPixel, "Bits per pixel (use zero to avoid scaling) [0]" );
|
||||
|
||||
m_uiBitsPixel = 0;
|
||||
m_uiSumOperation = 0;
|
||||
m_iOperation = 1;
|
||||
|
||||
m_pcFrameDifference = NULL;
|
||||
}
|
||||
@@ -52,8 +49,6 @@ bool FrameDifference::create( std::vector<CalypFrame*> apcFrameList )
|
||||
{
|
||||
_BASIC_MODULE_API_2_CHECK_
|
||||
|
||||
m_uiSumOperation = m_uiSumOperation > 1 ? 0 : m_uiSumOperation;
|
||||
|
||||
unsigned int uiMaxBitsPixel = 0;
|
||||
for( unsigned int i = 0; i < apcFrameList.size(); i++ )
|
||||
{
|
||||
@@ -62,46 +57,42 @@ bool FrameDifference::create( std::vector<CalypFrame*> apcFrameList )
|
||||
if( apcFrameList[i]->getBitsPel() > uiMaxBitsPixel )
|
||||
{
|
||||
uiMaxBitsPixel = apcFrameList[i]->getBitsPel();
|
||||
if( apcFrameList[i]->getHasNegativeValues() )
|
||||
uiMaxBitsPixel -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
uiMaxBitsPixel = m_uiSumOperation ? uiMaxBitsPixel : uiMaxBitsPixel + 1;
|
||||
m_uiBitsPixel = !m_uiBitsPixel ? uiMaxBitsPixel & 0x0F : m_uiBitsPixel;
|
||||
if( !m_uiBitsPixel )
|
||||
{
|
||||
m_uiBitsPixel = ( uiMaxBitsPixel + 1 ) & 0x0F;
|
||||
}
|
||||
|
||||
m_iDiffBitShift = uiMaxBitsPixel - m_uiBitsPixel;
|
||||
m_iMaxDiffValue = ( 1 << ( m_uiSumOperation ? m_uiBitsPixel : m_uiBitsPixel - 1 ) );
|
||||
m_iDiffBitShift = ( uiMaxBitsPixel + 1 ) - m_uiBitsPixel;
|
||||
m_iMaxDiffValue = ( 1 << ( m_uiBitsPixel - 1 ) );
|
||||
|
||||
m_pcFrameDifference = new CalypFrame( apcFrameList[0]->getWidth(), apcFrameList[0]->getHeight(),
|
||||
apcFrameList[0]->getPelFormat(), m_uiBitsPixel, m_uiSumOperation == 1 ? false : true );
|
||||
|
||||
m_iOperation = m_uiSumOperation == 0 ? -1 : 1 ;
|
||||
apcFrameList[0]->getPelFormat(), m_uiBitsPixel );
|
||||
return true;
|
||||
}
|
||||
|
||||
CalypFrame* FrameDifference::process( std::vector<CalypFrame*> apcFrameList )
|
||||
{
|
||||
const CalypFrame& frame1 = apcFrameList[0];
|
||||
const CalypFrame& frame2 = apcFrameList[1];
|
||||
ClpPel* pInput1PelYUV = apcFrameList[0]->getPelBufferYUV()[0][0];
|
||||
ClpPel* pInput2PelYUV = apcFrameList[1]->getPelBufferYUV()[0][0];
|
||||
ClpPel* pOutputPelYUV = m_pcFrameDifference->getPelBufferYUV()[0][0];
|
||||
short aux_pel_1, aux_pel_2;
|
||||
short diff = 0;
|
||||
int aux_pel_1, aux_pel_2;
|
||||
int diff = 0;
|
||||
|
||||
for( unsigned int ch = 0; ch < m_pcFrameDifference->getNumberChannels(); ch++ )
|
||||
for( unsigned int y = 0; y < m_pcFrameDifference->getHeight( ch ); y++ )
|
||||
for( unsigned int x = 0; x < m_pcFrameDifference->getWidth( ch ); x++ )
|
||||
for( unsigned int y = 0; y < m_pcFrameDifference->getHeight(); y++ )
|
||||
for( unsigned int x = 0; x < m_pcFrameDifference->getWidth(); x++ )
|
||||
{
|
||||
aux_pel_1 = frame1(ch, x, y, false );
|
||||
aux_pel_2 = frame2(ch, x, y, false );
|
||||
diff = aux_pel_1 + m_iOperation * aux_pel_2;
|
||||
diff = m_iDiffBitShift > 0 ? diff >> m_iDiffBitShift : diff << -m_iDiffBitShift;
|
||||
diff = std::min<short>( diff, m_iMaxDiffValue - 1 );
|
||||
if( m_uiSumOperation == 0 )
|
||||
{
|
||||
diff = std::max<short>( diff, -m_iMaxDiffValue );
|
||||
diff += m_iMaxDiffValue;
|
||||
}
|
||||
aux_pel_1 = *pInput1PelYUV++;
|
||||
aux_pel_2 = *pInput2PelYUV++;
|
||||
diff = aux_pel_1 - aux_pel_2;
|
||||
diff = m_iDiffBitShift > 0 ? diff >> m_iDiffBitShift : diff << m_iDiffBitShift;
|
||||
diff = std::min( diff, m_iMaxDiffValue - 1 );
|
||||
diff = std::max( diff, -m_iMaxDiffValue );
|
||||
|
||||
diff += m_iMaxDiffValue;
|
||||
*pOutputPelYUV++ = diff;
|
||||
}
|
||||
return m_pcFrameDifference;
|
||||
|
||||
@@ -34,10 +34,8 @@ class FrameDifference : public CalypModuleIf
|
||||
|
||||
private:
|
||||
unsigned int m_uiBitsPixel;
|
||||
unsigned int m_uiSumOperation;
|
||||
int m_iOperation;
|
||||
int m_iDiffBitShift;
|
||||
short m_iMaxDiffValue;
|
||||
int m_iMaxDiffValue;
|
||||
CalypFrame* m_pcFrameDifference;
|
||||
|
||||
public:
|
||||
|
||||
@@ -40,7 +40,7 @@ FrameResampling::FrameResampling()
|
||||
m_iModuleType = CLP_FRAME_PROCESSING_MODULE;
|
||||
m_pchModuleCategory = "Utilities";
|
||||
m_pchModuleName = "FrameResampling";
|
||||
m_pchModuleLongName = "Frame Resampling (Spatial)";
|
||||
m_pchModuleLongName = "Frame Resampling";
|
||||
m_pchModuleTooltip = "Resampling frame to an abritary resolution";
|
||||
m_uiNumberOfFrames = 1;
|
||||
m_uiModuleRequirements = CLP_MODULE_REQUIRES_OPTIONS;
|
||||
|
||||
+5
-10
@@ -23,12 +23,12 @@
|
||||
*/
|
||||
|
||||
#include "CalypTools.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include "config.h"
|
||||
#include "lib/CalypFrame.h"
|
||||
#include "lib/CalypModuleIf.h"
|
||||
#include "lib/CalypStream.h"
|
||||
@@ -79,14 +79,13 @@ int CalypTools::openInputs()
|
||||
ClpString fmtString( "yuv420p" );
|
||||
unsigned int uiBitsPerPixel = 8;
|
||||
unsigned int uiEndianness = 0;
|
||||
bool hasNegativeValues = false;
|
||||
|
||||
CalypStream* pcStream;
|
||||
for( unsigned int i = 0; i < inputFileNames.size() && i < MAX_NUMBER_INPUTS; i++ )
|
||||
{
|
||||
if( Opts().hasOpt( "size" ) )
|
||||
{
|
||||
resolutionString = GET_PARAM( m_strResolution, i );
|
||||
resolutionString = GET_PARAM( m_strResolution, 0 );
|
||||
}
|
||||
if( Opts().hasOpt( "pel_fmt" ) )
|
||||
{
|
||||
@@ -107,14 +106,10 @@ int CalypTools::openInputs()
|
||||
uiEndianness = 1;
|
||||
}
|
||||
}
|
||||
if( Opts().hasOpt( "has_negative" ) )
|
||||
{
|
||||
hasNegativeValues = std::stoi( GET_PARAM( m_strHasNegativeValues, i ).c_str() ) == 0 ? false : true;
|
||||
}
|
||||
pcStream = new CalypStream;
|
||||
try
|
||||
{
|
||||
if( !pcStream->open( inputFileNames[i], resolutionString, fmtString, uiBitsPerPixel, uiEndianness, hasNegativeValues, 1, true ) )
|
||||
if( !pcStream->open( inputFileNames[i], resolutionString, fmtString, uiBitsPerPixel, uiEndianness, 1, true ) )
|
||||
{
|
||||
log( CLP_LOG_ERROR, "Cannot open input stream %s! ", inputFileNames[i].c_str() );
|
||||
return -1;
|
||||
@@ -177,11 +172,11 @@ int CalypTools::Open( int argc, char* argv[] )
|
||||
m_uiOutEndianness = 0;
|
||||
if( Opts().hasOpt( "endianness" ) )
|
||||
{
|
||||
if( GET_PARAM( m_strEndianness, 9999 ) == "big" )
|
||||
if( m_strEndianness[0] == "big" )
|
||||
{
|
||||
m_uiOutEndianness = 0;
|
||||
}
|
||||
else if( GET_PARAM( m_strEndianness, 9999 ) == "little" )
|
||||
else if( m_strEndianness[0] == "little" )
|
||||
{
|
||||
m_uiOutEndianness = 1;
|
||||
}
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
#include "CalypToolsCmdParser.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include "lib/CalypFrame.h"
|
||||
#include "lib/CalypModuleIf.h"
|
||||
#include "lib/CalypStream.h"
|
||||
#include "modules/CalypModulesFactory.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
CalypToolsCmdParser::CalypToolsCmdParser()
|
||||
{
|
||||
m_uiLogLevel = 0;
|
||||
@@ -66,7 +66,6 @@ int CalypToolsCmdParser::parseToolsArgs( int argc, char* argv[] )
|
||||
( "pel_fmt,p", m_strPelFmt, "pixel format" ) /**/
|
||||
( "bits_pel", m_strBitsPerPixel, "bits per pixel" ) /**/
|
||||
( "endianness", m_strEndianness, "File endianness (big, little)" ) /**/
|
||||
( "has_negative", m_strHasNegativeValues, "Flag for files with negatie values" ) /**/
|
||||
( "frames,f", m_iFrames, "number of frames to parse" ) /**/
|
||||
( "quality", m_strQualityMetric, "select a quality metric" ) /**/
|
||||
( "module", m_strModule, "select a module (use internal name)" ) /**/
|
||||
|
||||
@@ -69,7 +69,6 @@ protected:
|
||||
std::vector<ClpString> m_strPelFmt;
|
||||
std::vector<ClpString> m_strBitsPerPixel;
|
||||
std::vector<ClpString> m_strEndianness;
|
||||
std::vector<ClpString> m_strHasNegativeValues;
|
||||
ClpString m_strOutput;
|
||||
long m_iFrames;
|
||||
unsigned m_uiOutEndianness;
|
||||
|
||||
Reference in New Issue
Block a user