Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

This is how to "decipher" your OpenCV assert error:

  • here https://docs.opencv.org/ you can access the OpenCV documentation
  • from the documentation you can have the C++ signature: double cv::pointPolygonTest (InputArray contour, Point2f pt, bool measureDist)
  • this is the Python signature: retval = cv.pointPolygonTest(contour, pt, measureDist) but since Python OpenCV interface is wrapped from C++, it is important to understand the C++ API
  • InputArray is just a proxy class, the most common OpenCV class is cv::Mat to hold image data or matrix information
  • (depth == CV_32S || depth == CV_32F) means that the expected depth of the input data should be CV_32S (32-bit integer) or CV_32F (32-bit floating point)

Here the mapping:

  • CV_8U <--> 8-bit unsigned integers (unsigned char in C++)
  • CV_8S <--> 8-bit signed integers (char in C++)
  • CV_16U <--> 16-bit unsigned integers (unsigned short in C++)
  • CV_16S <--> 16-bit signed integers (short in C++)
  • CV_32S <--> 32-bit signed integesr (int in C++)
  • CV_32F <--> 32-bit floating-point numbers (float in C++)
  • CV_64F <--> 64-bit floating-point numbers (double in C++)

For cv::Mat, the important things to remember for cv::Mat m; are:

Returns the depth of a matrix element.

The method returns the identifier of the matrix element depth (the type of each individual channel). For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of matrix types contains the following values:

CV_8U - 8-bit unsigned integers ( 0..255 )
CV_8S - 8-bit signed integers ( -128..127 )
CV_16U - 16-bit unsigned integers ( 0..65535 )
CV_16S - 16-bit signed integers ( -32768..32767 )
CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN

) CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )

  • number of channels of a mat m.channels(), e.g. 3 for a color image
  • type of a mat m.type(), that is the combination depth with channels, e.g. CV_8UC3 for a color image

This condition total >= 0 should mean that the number of points in the contour matrix must be >= 0. This looks a little bit odd since we could expect to check for a strictly positive number but this is just like it is written currently in the code:

double cv::pointPolygonTest( InputArray _contour, Point2f pt, bool measureDist )
{
    CV_INSTRUMENT_REGION();

    double result = 0;
    Mat contour = _contour.getMat();
    int i, total = contour.checkVector(2), counter = 0;
    int depth = contour.depth();
    CV_Assert( total >= 0 && (depth == CV_32S || depth == CV_32F));

    bool is_float = depth == CV_32F;
    double min_dist_num = FLT_MAX, min_dist_denom = 1;
    Point ip(cvRound(pt.x), cvRound(pt.y));

    if( total == 0 )
return measureDist ? -DBL_MAX : -1;

Also, don't be afraid to look directly into the source code.

This is how to "decipher" your OpenCV assert error:

  • here https://docs.opencv.org/ you can access the OpenCV documentation
  • from the documentation you can have the C++ signature: double cv::pointPolygonTest (InputArray contour, Point2f pt, bool measureDist)
  • this is the Python signature: retval = cv.pointPolygonTest(contour, pt, measureDist) but since Python OpenCV interface is wrapped from C++, it is important to understand the C++ API
  • InputArray is just a proxy class, the most common OpenCV class is cv::Mat to hold image data or matrix information
  • (depth == CV_32S || depth == CV_32F) means that the expected depth of the input data should be CV_32S (32-bit integer) or CV_32F (32-bit floating point)

Here the mapping:

  • CV_8U <--> 8-bit unsigned integers (unsigned char in C++)C++, uchar in OpenCV)
  • CV_8S <--> 8-bit signed integers (char in C++)C++, schar in OpenCV)
  • CV_16U <--> 16-bit unsigned integers (unsigned short in C++)C++, ushort in OpenCV)
  • CV_16S <--> 16-bit signed integers (short in C++)
  • CV_32S <--> 32-bit signed integesr (int in C++)
  • CV_32F <--> 32-bit floating-point numbers (float in C++)
  • CV_64F <--> 64-bit floating-point numbers (double in C++)

The list of primitive types in OpenCV:

//! - schar  - signed 1 byte integer
//! - uchar  - unsigned 1 byte integer
//! - short  - signed 2 byte integer
//! - ushort - unsigned 2 byte integer
//! - int    - signed 4 byte integer
//! - uint   - unsigned 4 byte integer
//! - int64  - signed 8 byte integer
//! - uint64 - unsigned 8 byte integer

For cv::Mat, the important things to remember for cv::Mat m; are:

Returns the depth of a matrix element.

The method returns the identifier of the matrix element depth (the type of each individual channel). For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of matrix types contains the following values:

CV_8U - 8-bit unsigned integers ( 0..255 )
CV_8S - 8-bit signed integers ( -128..127 )
CV_16U - 16-bit unsigned integers ( 0..65535 )
CV_16S - 16-bit signed integers ( -32768..32767 )
CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN

NAN ) CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )

NAN )
  • number of channels of a mat m.channels(), e.g. 3 for a color image
  • type of a mat m.type(), that is the combination depth with channels, e.g. CV_8UC3 for a color image

This condition total >= 0 should mean that the number of points in the contour matrix must be >= 0. This looks a little bit odd since we could expect to check for a strictly positive number but this is just like it is written currently in the code:

double cv::pointPolygonTest( InputArray _contour, Point2f pt, bool measureDist )
{
    CV_INSTRUMENT_REGION();

    double result = 0;
    Mat contour = _contour.getMat();
    int i, total = contour.checkVector(2), counter = 0;
    int depth = contour.depth();
    CV_Assert( total >= 0 && (depth == CV_32S || depth == CV_32F));

    bool is_float = depth == CV_32F;
    double min_dist_num = FLT_MAX, min_dist_denom = 1;
    Point ip(cvRound(pt.x), cvRound(pt.y));

    if( total == 0 )
return measureDist ? -DBL_MAX : -1;

Also, don't be afraid to look directly into the source code.