Errors in argument type cause a \texttt{TypeError} exception.
OpenCV errors cause an \texttt{cv.error} exception.
For example a function argument that is the wrong type produces a \texttt{TypeError}:
\begin{lstlisting}
>>> import cv
>>> cv.LoadImage(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument 1 must be string, not int
\end{lstlisting}
A function with the
\begin{lstlisting}
>>> cv.CreateMat(-1, -1, cv.CV_8UC1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
error: Non-positive width or height
\end{lstlisting}
\fi
\ifC% {
Error handling in OpenCV is similar to IPL (Image Processing
Library). In the case of an error, functions do not return the error
code. Instead, they raise an error using \texttt{CV\_ERROR}
macro that calls \cvCPyCross{Error} that, in its turn, sets the error
status with \cvCPyCross{SetErrStatus} and calls a standard or user-defined
error handler (that can display a message box, write to log, etc., see
\cvCPyCross{RedirectError}). There is a global variable, one per each program
thread, that contains current error status (an integer value). The status
can be retrieved with the \cvCPyCross{GetErrStatus} function.
There are three modes of error handling (see \cvCPyCross{SetErrMode} and
\cvCPyCross{GetErrMode}):
\begin{itemize}
\item\textbf{Leaf}. The program is terminated after the error handler is
called. This is the default value. It is useful for debugging, as the
error is signalled immediately after it occurs. However, for production
systems, other two methods may be preferable as they provide more
control.
\item\textbf{Parent}. The program is not terminated, but the error handler
is called. The stack is unwound (it is done w/o using a C++ exception
mechanism). The user may check error code after calling the \texttt{CxCore} function with
\cvCPyCross{GetErrStatus} and react.
\item\textbf{Silent}. Similar to \texttt{Parent} mode, but no error handler
is called.
\end{itemize}
Actually, the semantics of the \texttt{Leaf} and \texttt{Parent} modes are implemented by error handlers and the above description is true for them. \cvCPyCross{GuiBoxReport} behaves slightly differently, and some custom error handlers may implement quite different semantics.
Macros for raising an error, checking for errors, etc.
\begin{lstlisting}
/* special macros for enclosing processing statements within a function and separating
them from prologue (resource initialization) and epilogue (guaranteed resource release) */
#define __BEGIN__{
#define __END__ goto exit; exit: ; }
/* proceeds to "resource release" stage */
#define EXIT goto exit
/* Declares locally the function name for CV_ERROR() use */
__END__; // finish processing. Epilogue follows after the macro.
// release temp_array. If temp_array has not been allocated
// before an error occured, cvReleaseMat
// takes care of it and does nothing in this case.
cvReleaseMat( &temp_array );
}
int main( int argc, char** argv )
{
CvMat* src = cvCreateMat( 1, 512, CV_32F );
#if 1 /* no errors */
CvMat* dst = cvCreateMat( 1, 256, CV_32F );
#else
CvMat* dst = 0; /* test error processing mechanism */
#endif
cvSet( src, cvRealScalar(1.), 0 );
#if 0 /* change 0 to 1 to suppress error handler invocation */
cvSetErrMode( CV_ErrModeSilent );
#endif
cvResizeDCT( src, dst ); // if some error occurs, the message
// box will popup, or a message will be
// written to log, or some user-defined
// processing will be done
if( cvGetErrStatus() < 0 )
printf("Some error occured" );
else
printf("Everything is OK" );
return 0;
}
\end{lstlisting}
\cvCPyFunc{GetErrStatus}
Returns the current error status.
\cvdefC{int cvGetErrStatus( void );}
The function returns the current error status -
the value set with the last \cvCPyCross{SetErrStatus} call. Note that in
\texttt{Leaf} mode, the program terminates immediately after an
error occurs, so to always gain control after the function call,
one should call \cvCPyCross{SetErrMode} and set the \texttt{Parent}
or \texttt{Silent} error mode.
\cvCPyFunc{SetErrStatus}
Sets the error status.
\cvdefC{void cvSetErrStatus( int status );}
\begin{description}
\cvarg{status}{The error status}
\end{description}
The function sets the error status to the specified value. Mostly, the function is used to reset the error status (set to it \texttt{CV\_StsOk}) to recover after an error. In other cases it is more natural to call \cvCPyCross{Error} or \texttt{CV\_ERROR}.
\cvCPyFunc{GetErrMode}
Returns the current error mode.
\cvdefC{int cvGetErrMode(void);}
The function returns the current error mode - the value set with the last \cvCPyCross{SetErrMode} call.
\cvCPyFunc{SetErrMode}
Sets the error mode.
\begin{lstlisting}
#define CV_ErrModeLeaf 0
#define CV_ErrModeParent 1
#define CV_ErrModeSilent 2
\end{lstlisting}
\cvdefC{int cvSetErrMode( int mode );}
\begin{description}
\cvarg{mode}{The error mode}
\end{description}
The function sets the specified error mode. For descriptions of different error modes, see the beginning of the error section.
\cvCPyFunc{Error}
Raises an error.
\cvdefC{int cvError( \par int status,\par const char* func\_name,\par const char* err\_msg,\par const char* filename,\par int line );}
\begin{description}
\cvarg{status}{The error status}
\cvarg{func\_name}{Name of the function where the error occured}
\cvarg{err\_msg}{Additional information/diagnostics about the error}
\cvarg{filename}{Name of the file where the error occured}
\cvarg{line}{Line number, where the error occured}
\end{description}
The function sets the error status to the specified value (via \cvCPyCross{SetErrStatus}) and, if the error mode is not \texttt{Silent}, calls the error handler.
\cvCPyFunc{ErrorStr}
Returns textual description of an error status code.
\cvdefC{const char* cvErrorStr( int status );}
\begin{description}
\cvarg{status}{The error status}
\end{description}
The function returns the textual description for
the specified error status code. In the case of unknown status, the function
If the error handler is set to \texttt{cvStdErrReport}, the above message will be printed to standard error output and the program will be terminated or continued, depending on the current error mode.
\textbf{Error Message printed to Standard Error Output (in \texttt{Leaf} mode)}
\begin{lstlisting}
OpenCV ERROR: Bad argument (input_array or output_array are not valid matrices)
in function cvResizeDCT, D:\User\VP\Projects\avl\_proba\a.cpp(75)
Terminating the application...
\end{lstlisting}
\cvCPyFunc{Alloc}
Allocates a memory buffer.
\cvdefC{void* cvAlloc( size\_t size );}
\begin{description}
\cvarg{size}{Buffer size in bytes}
\end{description}
The function allocates \texttt{size} bytes and returns
a pointer to the allocated buffer. In the case of an error the function reports an
error and returns a NULL pointer. By default, \texttt{cvAlloc} calls
\texttt{icvAlloc} which
itself calls \texttt{malloc}. However it is possible to assign user-defined memory
allocation/deallocation functions using the \cvCPyCross{SetMemoryManager} function.
\cvCPyFunc{Free}
Deallocates a memory buffer.
\cvdefC{void cvFree( void** ptr );}
\begin{description}
\cvarg{ptr}{Double pointer to released buffer}
\end{description}
The function deallocates a memory buffer allocated by
\cvCPyCross{Alloc}. It clears the pointer to buffer upon exit, which is why
the double pointer is used. If the \texttt{*buffer} is already NULL, the function
does nothing.
\fi% }
\cvCPyFunc{GetTickCount}
Returns the number of ticks.
\cvdefC{int64 cvGetTickCount( void );}
\cvdefPy{GetTickCount() -> long}
The function returns number of the ticks starting from some platform-dependent event (number of CPU ticks from the startup, number of milliseconds from 1970th year, etc.). The function is useful for accurate measurement of a function/user-code execution time. To convert the number of ticks to time units, use \cvCPyCross{GetTickFrequency}.
\cvCPyFunc{GetTickFrequency}
Returns the number of ticks per microsecond.
\cvdefC{double cvGetTickFrequency( void );}
\cvdefPy{GetTickFrequency() -> long}
The function returns the number of ticks per microsecond. Thus, the quotient of \cvCPyCross{GetTickCount} and \cvCPyCross{GetTickFrequency} will give the number of microseconds starting from the platform-dependent event.
\cvarg{allocFunc}{Allocation function; the interface is similar to \texttt{malloc}, except that \texttt{userdata} may be used to determine the context}
\cvarg{freeFunc}{Deallocation function; the interface is similar to \texttt{free}}
\cvarg{userdata}{User data that is transparently passed to the custom functions}
\end{description}
The function sets user-defined memory
managment functions (substitutes for \texttt{malloc} and \texttt{free}) that will be called
by \texttt{cvAlloc, cvFree} and higher-level functions (e.g., \texttt{cvCreateImage}). Note
that the function should be called when there is data allocated using
\texttt{cvAlloc}. Also, to avoid infinite recursive calls, it is not
allowed to call \texttt{cvAlloc} and \cvCPyCross{Free} from the custom
allocation/deallocation functions.
If the \texttt{alloc\_func} and \texttt{free\_func} pointers are
\texttt{NULL}, the default memory managing functions are restored.
\cvCPyFunc{SetIPLAllocators}
Switches to IPL functions for image allocation/deallocation.
The generic function \texttt{deallocate} deallocates the buffer allocated with \cvCppCross{allocate}. The number of elements must match the number passed to \cvCppCross{allocate}.
\cvfunc{CV\_Assert}\label{CV Assert}
Checks a condition at runtime.
\cvdefC{CV\_Assert(expr)}
\cvdefCpp{CV\_Assert(expr)}
\cvdefPy{CV\_Assert(expr)}
\begin{lstlisting}
#define CV_Assert( expr ) ...
#define CV_DbgAssert(expr) ...
\end{lstlisting}
\begin{description}
\cvarg{expr}{The checked expression}
\end{description}
The macros \texttt{CV\_Assert} and \texttt{CV\_DbgAssert} evaluate the specified expression and if it is 0, the macros raise an error (see \cvCppCross{error}). The macro \texttt{CV\_Assert} checks the condition in both Debug and Release configurations, while \texttt{CV\_DbgAssert} is only retained in the Debug configuration.
\cvarg{code}{The error code, normally, a negative value. The list of pre-defined error codes can be found in \texttt{cxerror.h}}
\cvarg{msg}{Text of the error message}
\cvarg{args}{printf-like formatted error message in parantheses}
\end{description}
The function and the helper macros \texttt{CV\_Error} and \texttt{CV\_Error\_} call the error handler. Currently, the error handler prints the error code (\texttt{exc.code}), the context (\texttt{exc.file}, \texttt{exc.line} and the error message \texttt{exc.err} to the standard error stream \texttt{stderr}. In Debug configuration it then provokes memory access violation, so that the execution stack and all the parameters can be analyzed in debugger. In Release configuration the exception \texttt{exc} is thrown.
The macro \texttt{CV\_Error\_} can be used to construct the error message on-fly to include some dynamic information, for example:
\begin{lstlisting}
// note the extra parentheses around the formatted text message
CV_Error_(CV_StsOutOfRange,
("the matrix element (%d,%d)=%g is out of range",
i, j, mtx.at<float>(i,j)))
\end{lstlisting}
\cvclass{Exception}
The exception class passed to error
\begin{lstlisting}
class Exception
{
public:
// various constructors and the copy operation
Exception() { code = 0; line = 0; }
Exception(int _code, const string&_err,
const string&_func, const string&_file, int _line);newline
The class \texttt{Exception} encapsulates all or almost all the necessary information about the error happened in the program. The exception is usually constructed and thrown implicitly, via \texttt{CV\_Error} and \texttt{CV\_Error\_} macros, see \cvCppCross{error}.
\cvCppFunc{fastMalloc}
Allocates aligned memory buffer
\cvdefCpp{void* fastMalloc(size\_t size);}
\begin{description}
\cvarg{size}{The allocated buffer size}
\end{description}
The function allocates buffer of the specified size and returns it. When the buffer size is 16 bytes or more, the returned buffer is aligned on 16 bytes.
\cvCppFunc{fastFree}
Deallocates memory buffer
\cvdefCpp{void fastFree(void* ptr);}
\begin{description}
\cvarg{ptr}{Pointer to the allocated buffer}
\end{description}
The function deallocates the buffer, allocated with \cvCppCross{fastMalloc}.
If NULL pointer is passed, the function does nothing.
\cvCppFunc{format}
Returns a text string formatted using printf-like expression
The function acts like \texttt{sprintf}, but forms and returns STL string. It can be used for form the error message in \cvCppCross{Exception} constructor.
\cvCppFunc{getNumThreads}
Returns the number of threads used by OpenCV
\cvdefCpp{int getNumThreads();}
The function returns the number of threads that is used by OpenCV.
See also: \cvCppCross{setNumThreads}, \cvCppCross{getThreadNum}.
\cvCppFunc{getThreadNum}
Returns index of the currently executed thread
\cvdefCpp{int getThreadNum();}
The function returns 0-based index of the currently executed thread. The function is only valid inside a parallel OpenMP region. When OpenCV is built without OpenMP support, the function always returns 0.
See also: \cvCppCross{setNumThreads}, \cvCppCross{getNumThreads}.
\cvCppFunc{getTickCount}
Returns the number of ticks
\cvdefCpp{int64 getTickCount();}
The function returns the number of ticks since the certain event (e.g. when the machine was turned on).
It can be used to initialize \cvCppCross{RNG} or to measure a function execution time by reading the tick count before and after the function call. See also the tick frequency.
\cvCppFunc{getTickFrequency}
Returns the number of ticks per second
\cvdefCpp{double getTickFrequency();}
The function returns the number of ticks per second.
t = ((double)getTickCount() - t)/getTickFrequency();
\end{lstlisting}
\cvCppFunc{setNumThreads}
Sets the number of threads used by OpenCV
\cvdefCpp{void setNumThreads(int nthreads);}
\begin{description}
\cvarg{nthreads}{The number of threads used by OpenCV}
\end{description}
The function sets the number of threads used by OpenCV in parallel OpenMP regions. If \texttt{nthreads=0}, the function will use the default number of threads, which is usually equal to the number of the processing cores.
See also: \cvCppCross{getNumThreads}, \cvCppCross{getThreadNum}