OpenCV mat在调试模式下无法工作

3
我正在尝试创建一个函数,使得在OpenCV 3.1中可以设置QImage的对比度/亮度。这在发布模式下完美运行,但在调试模式下不起作用(返回空白图像):
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;
}

你看到可能存在的问题了吗?
编辑 我的.pro文件(两个相关的dll在bin目录中)。
INCLUDEPATH += ../lib/opencv/include

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

包括:

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

你在项目设置中添加了所有库吗? - Viktoria
你是怎么构建这个的?你能在这里分享你的qmake/cmake文件吗?也许有一些优化方面的东西...? - mrogal.ski
1
// 将图像转换为带有深度复制的临时cv::Mat - Miki
2个回答

1

QImage 的构造函数使用:

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

构造一个给定宽度、高度和格式的图像,使用现有的内存缓冲区数据。宽度和高度必须以像素为单位指定。bytesPerLine指定每行的字节数(跨度)。
缓冲区必须在QImage的整个生命周期中保持有效,并且所有未修改或未从原始缓冲区分离的副本都必须保持有效。
在从此函数返回之前,请务必调用非const QImage ::bits()
返回指向第一个像素数据的指针。这相当于scanLine(0)。
请注意,QImage使用隐式数据共享。此函数对共享像素数据执行深层拷贝,因此确保此QImage是唯一使用当前返回值的对象。
dest.bits(); // does deep copy
return dest;

或者您在一个堆栈上的Cv::Mat容器中有一个QImage的内部缓冲区,当然,在从getNewImage函数返回后,它已经超出了范围,并且您返回了新的QImage实例,该实例是QImage dest的浅拷贝。这是QImage的一个特性,旨在通过其实例优化传递大块图形数据,而没有发生任何转换,因此我们无法避免在此处调用QImage::bits

显然,由于发布模式和调试模式之间的运行时差异,释放的堆栈内存中的缓冲区被覆盖了,这表明代码存在问题。调试模式运行时确实会写入已释放的运行时内存,以防止出现这种错误:在Visual Studio C++中,什么是内存分配表示?


0
我遇到了同样的问题,如果我在函数中创建Mat对象,那么qtcreator调试器无法调试该函数,只会停止并显示一个空的调试窗口,最终超时。因此,我将Mat对象变量添加到类定义中,然后调试器就可以正常工作了! :)(对于我的英语不好感到抱歉)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接