3

I'm a newbie of C++ and opencv. I've written a simple program that you can find below but when I run it I always get an exception thrown by findContours(img, ctr, CV_RETR_LIST, CV_CHAIN_APPROX_NONE) raised by type assertion failed

OpenCV Error: Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN (type0) && ((1 << type0) & fixedDepthMask) != 0)) in create, file C:\opencv\modu les\core\src\matrix.cpp, line 1466.

I need a class that represents a single contour and integrates contour analisys method. I know that CONTOUR is a different type respect to vector<Point> but since it extends the latter, shouldn't CONTOUR be also a vector<Point> type (and in the same way vector<CONTOUR> be also a vector< vector<Point> > ) ? Am I wrong?

Please note that if you declare CONTOUR as a class derived from vector<vector<Point>> and declare Ctr in the code below as a CONTOUR object in place of vector<CONTOUR> everything work out fine.

Many thanks in advance.

Here is my code

#include "opencv2/opencv.hpp"

#include <vector>

using namespace cv;
using namespace std;

class CONTOUR : public vector<Point>
{
public:
    CONTOUR() : vector<Point>(){ };
    CONTOUR(const CONTOUR& orig) : vector<Point> (orig){ };
    virtual ~CONTOUR(){ };

    CONTOUR& operator=(const CONTOUR& rhs)
    {
        vector<Point> :: operator = (rhs);
        return *this;
    }

    CONTOUR& operator=(const vector<Point>& rhs)
    {
        vector<Point> :: operator = (rhs);
        return *this;
    }
};

/** @function main */
int main(int argc, char** argv)
{
    VideoCapture Camera;

    if(Camera.open(0))
    {
        Mat img;

        namedWindow("VIDEO", CV_WINDOW_AUTOSIZE);

        for(;;)
        {

            Camera >> img;

            if(!img.empty())
            {
                CONTOUR ctr;
                RNG n(12345);

                GaussianBlur(img, img, Size(5,5), 1.0, 1.0);
                cvtColor(img, img, CV_BGR2GRAY);
                Canny(img, img, 20, 80, 3);

                findContours(img, ctr, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

                Mat shape = Mat::zeros( img.size(), CV_8UC3 );

                for( unsigned int i = 0; i< ctr.size(); i++ )
                {
                    Scalar color(n.uniform(0,255), n.uniform(0,255), n.uniform(0,255));
                    drawContours(shape, ctr, i, color, 1, 8);
                }

                imshow("VIDEO", shape);

                if(waitKey(30) >= 0)
                {
                    break;
                }
            }
        }
    }
    else
    {
        cout << "Camera not opened" << endl;
    }

    return 0;
}
Arloong
  • 39
  • 1
  • 4

2 Answers2

7

First, allow me to say this: Attempting to use Standard Library containers polymorphically is a Bad Idea. Don't do it. It's not even necessary in your case.

The fix for your problem is simple: dispense with the class CONTOUR and pass a vector<vector<cv::Point>>. This is because cv::findContours() requires you to pass either a that or an equivalent cv::Mat. This is because it uses a proxy type as an argument which can only be constructed from these types, hence the assertion failure. If you want to define a shorthand for a contour, use typedef std::vector<cv::Point> Contour, rather than #define CONTOUR. This gives you the benefit of type safety.

Also, vector<CONTOUR> is NOT the same type as vector<vector<Point>>. Even though CONTOUR inherits from vector<cv::Point>, they are different types. Thus, vectors of them are also different types. This answer might also be helpful in understanding this issue.

Also, I note that in your code, CONTOUR is derived from vector<cv::Point>. This assertion is stating that you need a vector of vectors: vector<vector<cv::Point>>.

Community
  • 1
  • 1
Aurelius
  • 11,111
  • 3
  • 52
  • 69
  • Thanks for the answer. edit my question hope it's a bit clearer. – Arloong Jul 23 '13 at 19:17
  • 1
    @Arloong On this site, it's better if you [post your solution as an answer](http://stackoverflow.com/help/self-answer) and [accept](http://stackoverflow.com/help/someone-answers) the one that is most helpful. That aside, I **strongly** recommend you to not use your posted solution. Sure, it works, but it introduces unnecessary complexity. – Aurelius Jul 23 '13 at 19:21
1

Assertion fail error in findContour function is only due to mismatch in your compiler and opencv binary. Choose those proper compiler from project property.

C_Raj
  • 162
  • 7