Ask Your Question

Revision history [back]

Mat destructor error with homography

I have some code that works correctly. However, at the end of block when it has to go into another iteration of the loop, I get a popup saying "Debug Assertion Failed!" I traced the error to ~Mat that was trying to release a Mat created by findHomography. I used this Mat in perspectiveTransform and it worked correctly. I am unable to figure out why I should have this problem in the destructor. Can someone please help?

Mat destructor error with homography

I have some code that works correctly. However, at the end of block when it has to go into another iteration of the loop, I get a popup saying "Debug Assertion Failed!" I traced the error to ~Mat that was trying to release a Mat created by findHomography. I used this Mat in perspectiveTransform and it worked correctly. I am unable to figure out why I should have this problem in the destructor. Can someone please help?help?\

Adding code. It is adapted from a tutorial.

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/calib3d/calib3d.hpp>

const char * OBJFILE = "segmentedImage.jpg";
// const char * OBJFILE = "Dress2.tif";
const char * IMGFILE = "Taylor8.tif";

int main()
{
    try
    {
        cv::Mat obj = cv::imread ( OBJFILE );
        if ( obj.empty() )
            throw ( std::string ( "Could not open object file " ) + OBJFILE );

//      cv::namedWindow ( "Good matches" );

        char  infile[80], outfile[80];

        for ( int fn = 3; fn < 9; fn++ )
        {
            sprintf ( infile, "Taylor%d.tif", fn );

            cv::Mat frame = cv::imread ( infile );
            if ( frame.empty() )
                throw ( std::string ( "Could not open image file " ) + IMGFILE );


            //*****  Detect the keypoints using SURF detector

            int     minHessian = 400;           // Threshold for the keypoint detector
            cv::SurfFeatureDetector detector ( minHessian );
            std::vector<cv::KeyPoint> keypt_obj, keypt_frame;
            detector.detect ( obj, keypt_obj );
            detector.detect ( frame, keypt_frame );

            //*****  Calculate feature vectors

            cv::SurfDescriptorExtractor extractor;
            cv::Mat descriptor_obj, descriptor_frame;
            extractor.compute ( obj, keypt_obj, descriptor_obj );
            extractor.compute ( frame, keypt_frame, descriptor_frame );

            //***** Matching descriptor vectors using brute force matcher

            cv::BFMatcher   matcher;
            std::vector<cv::DMatch> matches;
            matcher.match ( descriptor_obj, descriptor_frame, matches );


            // Find minimum and maximum distance between keypoints

            float max_dist = 0;
            float min_dist = 50;
            for ( int i = 0; i < descriptor_obj.rows; i++ )
            {
                float& dist = matches[i].distance;
                if ( dist < min_dist )
                    min_dist = dist;
                else
                    if ( dist > max_dist )
                        max_dist = dist;
            }

            std::cout << "Info: Max dist: " << max_dist << std::endl;
            std::cout << "Info: Min dist: " << min_dist << std::endl;

            // Draw only good matches, defined by dist < 3 * min_dist

            std::vector<cv::DMatch> good_matches;
            for ( int i = 0; i < descriptor_obj.rows; i++ )
                if ( matches[i].distance < 3 * min_dist )
                    good_matches.push_back ( matches[i] );

            cv::Mat img_matches = frame;
//          cv::drawMatches (obj, keypt_obj, frame, keypt_frame, good_matches, img_matches,
//              cv::Scalar::all ( -1 ), cv::Scalar::all ( -1 ), std::vector<char>(),
//              cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

            // Localize the object

            std::vector<cv::Point2f> obj_pts, frame_pts;
            for ( unsigned int i = 0; i < good_matches.size(); i++ )
            {
                obj_pts.push_back ( keypt_obj[good_matches[i].queryIdx].pt );
                frame_pts.push_back ( keypt_frame[good_matches[i].trainIdx].pt );
            }

            cv::Mat homography = cv::findHomography ( obj_pts, frame_pts, CV_RANSAC );

            // Get the corners from object to be detected

            std::vector<cv::Point2f> obj_corners ( 4 );
            obj_corners[0] = cv::Point ( 0, 0 );
            obj_corners[1] = cv::Point ( obj.cols, 0 );
            obj_corners[2] = cv::Point ( obj.cols, obj.rows );
            obj_corners[3] = cv::Point ( 0, obj.rows);

            // Get the frame corners

            std::vector<cv::Point2f> frame_corners ( 4 );
            cv::perspectiveTransform ( obj_corners, frame_corners, homography );

            // Check if we have a closed quadrilateral

            bool good_quad = ( frame_corners[0].x < frame_corners[1].x ) &&
                             ( frame_corners[1].y < frame_corners[2].y ) &&
                             ( frame_corners[2].x > frame_corners[3].x ) &&
                             ( frame_corners[3].y > frame_corners[0].y );

//          if ( good_quad )
            {
                sprintf ( outfile, "Taylorout%d.tif", fn );
                // Draw lines between the corners from object to matched object in frame

                for ( int i = 0; i < 4; i++ )
                   cv::line ( img_matches, frame_corners[i], frame_corners[(i+1)%4], cv::Scalar ( 0, 0XFF, 0 ), 4 );
                   // cv::line ( img_matches, frame_corners[i] + obj_corners[1], frame_corners[(i+1)%4] + obj_corners[1], cv::Scalar ( 0, 0XFF, 0 ), 4 );

                cv::imshow ( "Good matches", img_matches );
                if ( cv::waitKey ( 0 ) == 's' )
                    cv::imwrite ( outfile, img_matches);
            }
//          else
//              std::cout << "Could not find object in frame" << std::endl;
        }

    }
    catch ( std::string str )
    {
        std::cerr << "Error: " + str << std::endl;
        return ( 1 );
    }
    catch ( ... )
    {
        std::cerr << "Error: Unhandled exception" << std::endl;
        return ( 1 );
    }

    return ( 0 );
}