femtozer
femtozer

Reputation: 687

OpenCV mat not working in debug mode

I'm trying to create a function making possible the setting of the contrast/brightness of a QImage with OpenCV 3.1. This perfectly works in release but not in debug (it returns a blank image) :

QImage getNewImage(QImage *img, float contrast, float brightness)
{
    // Convert image to temporary cv::Mat with a deep copy
    // Output format is BGRA
    cv::Mat temp(img->height(),img->width(),CV_8UC4,(uchar*)img->bits(),img->bytesPerLine());

    temp.convertTo(temp, -1, contrast, brightness);
    cv::cvtColor(temp, temp, CV_BGRA2RGB);

    // Convert back to QImage RGB
    QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
    return dest;
}

Do you see what could be the problem ?


EDIT

My .pro (the two related dll are in the bin dir).

INCLUDEPATH += ../lib/opencv/include

CONFIG(debug, debug|release) {
    LIBS += ../lib/opencv/opencv_world310d.lib
} else {
    LIBS += ../lib/opencv/opencv_world310.lib
}

Includes :

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

Upvotes: 3

Views: 1137

Answers (2)

I have had the same problem, as if I created the Mat object in a function than the qtcreator debugger can not debug that function just stopped with an empty debug window and timed out after a while, so I added the Mat object variable in the class definition and after that the debugger went smoothly and worked as expected! :) (sorry for bad english)

Upvotes: 0

Alexander V
Alexander V

Reputation: 8718

The constructor of QImage used:

QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);

Constructs an image with the given width, height and format, that uses an existing memory buffer, data. The width and height must be specified in pixels. bytesPerLine specifies the number of bytes per line (stride).

The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer.

Make sure to call non-const QImage::bits() before returning from this function:

Returns a pointer to the first pixel data. This is equivalent to scanLine(0).

Note that QImage uses implicit data sharing. This function performs a deep copy of the shared pixel data, thus ensuring that this QImage is the only one using the current return value.

dest.bits(); // does deep copy
return dest;

Or you have an internal buffer of QImage in an on-stack Cv::Mat container which is of course out of scope after returning from getNewImage function and you return new QImage instance made a shallow copy of QImage dest. That is a feature of QImage aimed to optimize passing big chunks of graphic data through its instances while no transformation happened, so we cannot avoid calling QImage::bits here.

Apparently due run-time differences/between release and debug mode the buffer in a freed stack memory was overridden and that shows the code had a problem. And debug mode run-time does write to freed run-time memory to prevent bugs like this: In Visual Studio C++, what are the memory allocation representations?

Upvotes: 1

Related Questions