Crashes in Mat destructor

asked 2015-11-08 06:58:57 -0600

Uzaku gravatar image

Hey :),

I'm an IT-student and was assigned with the task to implement a harris detector by hand, I'm allowed to use OpenCV for image loading and accessing. So the first step is to implement the image derivation. Not too hard of a task, I thought, and started writing the source. I coppied it all together in one file, to make it easier for you.

So my problem is: there is an exception in the mat-dtor when leaving the derivate() function (sometimes on the first call, sometimes on the seccond call) and I really have no Idea why. It also does not get caught by the catch(std::exception) ... . Here is the call-stack at the crash:

>   opencv_core300d.dll!cv::fastFree(void * ptr) Zeile 81   C++
    opencv_core300d.dll!cv::StdMatAllocator::deallocate(cv::UMatData * u) Zeile 218 C++
    opencv_core300d.dll!cv::MatAllocator::unmap(cv::UMatData * u) Zeile 63  C++
    opencv_core300d.dll!cv::Mat::deallocate() Zeile 434 C++
    Ex2.exe!cv::Mat::release() Zeile 668    C++
    Ex2.exe!cv::Mat::~Mat() Zeile 555   C++
    Ex2.exe!derivate(cv::Mat & source, cv::Mat & target, Direction dir) Zeile 88    C++
    Ex2.exe!main(int argc, char * * argv) Zeile 120 C++

I use OpenCV3 (I link against the debug build in debug mode, and against the release build in release mode, so thats not the source of the problem, btw) and VisualStudio2013.

Here is my source:

#include <iostream>
#include <chrono>

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

//#include "derivate.h"

using namespace std;
using namespace std::chrono;

class FastAccess
{
public:
    FastAccess(cv::Mat &image)
    {
        auto h = image.size().height;
        ptr = new int*[h];

        for (int row = 0; row < h; ++row)
            ptr[row] = image.ptr<int>(row);

    }

    ~FastAccess()
    {
        //delete[] ptr;
    }

    int *operator [] (size_t row)
    {
        return ptr[row];
    }

private:
    int **ptr;
};

void pad_image(cv::Mat &source, cv::Mat &target, bool isHorz)
{
    int top, bot, left, right;

    top = bot = (isHorz) ? 0 : 1;
    left = right = (isHorz) ? 1 : 0;

    cv::copyMakeBorder(source, target, top, bot, left, right, IPL_BORDER_CONSTANT, 0);
}

enum class Direction
{
    Horizontal, Vertical
};

void derivate(cv::Mat &source, cv::Mat &target, Direction dir)
{
    bool isHorz = (dir == Direction::Horizontal);
    cv::Mat workingImage;
    pad_image(source, workingImage, isHorz);
    target.create(source.size(), source.type());
    unsigned startW, startH, targetW, targetH;

    if (isHorz)
    {
        startW = 1; startH = 0;
        targetW = source.size().width + 1;
        targetH = source.size().height;
    }
    else
    {
        startW = 0; startH = 1;
        targetW = source.size().width;
        targetH = source.size().height + 1;
    }

    FastAccess faDerivative(target);
    FastAccess faWImage(workingImage);

    for (auto row = startH; row < targetH; ++row)
    {
        for (auto col = startW; col < targetW; ++col)
        {
            faDerivative[row - startH][col - startW] = isHorz ?
                faWImage[row][col + 1] - faWImage[row][col - 1] :
                faWImage[row + 1][col] - faWImage[row - 1][col];
        }
    }
}

int main(int argc, char **argv)
{
    try
    {
        if (argc != 2)
        {
            cout << " Usage: Pass in the path of the image you want to load" << endl;
            return -1;
        }

        cv::Mat image = cv::imread(argv[1]);
        cv::imshow("Orignal", image);
        cv::waitKey(0);

        cv::Mat grayImage;
        if (image.channels() == 1)
            grayImage = image;
        else
            cv::cvtColor(image, grayImage, CV_BGR2GRAY);

        cout << "Beginning ...
(more)
edit retag flag offensive close merge delete

Comments

your whole code could be replaced faster, better, smaller,(and safe) with a plain Sobel()

image.ptr<int>(row); <-- i bet a fiver, your Mat type is not int.

berak gravatar imageberak ( 2015-11-08 09:23:17 -0600 )edit

Yeah, your right about Sobel, but as I said, I have to implement it by hand. How can I find out the mat-type?

Uzaku gravatar imageUzaku ( 2015-11-08 09:26:37 -0600 )edit

You were right. Once I used uchar as template param, all the problems vanished

Uzaku gravatar imageUzaku ( 2015-11-08 10:41:36 -0600 )edit