问题描述:
最近正在学习opencv3,打算使用Qt作为UI显示图像,熟悉cv的常见API。遇到一个问题:
这是头文件,定义了两个Mat变量分别保存处理前后矩阵。
class openQtCv : public QMainWindow
{
Q_OBJECT
public:
openQtCv(QWidget *parent = Q_NULLPTR);
private:
Ui::openQtCvClass ui;
private slots:
void openSlot();//打开
void resetSlot();//重置
void confirmSlot();//应用
void saveSlot();//保存
void smoothSlot();//图像平滑处理
private:
//QImage srcImg;//初始影像
cv::Mat srcMat;//cv 格式初始影像
//QImage dstImg;//当前影像
cv::Mat dstMat; //cv 格式当前影像
private:
void updataUI();
};
在构造函数初始化中使用了这样的语句
openQtCv::openQtCv(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.openBtn, SIGNAL(clicked()), this, SLOT(openSlot()));//图像打开
//模糊
connect(ui.clurSliderK, SIGNAL(valueChanged(int)), ui.clurSpinBox, SLOT(setValue(int)));
connect(ui.clurSpinBox, SIGNAL(valueChanged(int)), ui.clurSliderK, SLOT(setValue(int)));
connect(ui.clurSliderK, SIGNAL(valueChanged(int)), this, SLOT(smoothSlot()));
connect(ui.smoothCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(smoothSlot()));
connect(ui.resetBtn, SIGNAL(clicked()), this, SLOT(resetSlot()));
connect(ui.confirmBtn, SIGNAL(clicked()), this, SLOT(confirmSlot()));
srcMat = cv::imread("C:\\Users\\wcw\\Desktop\\lena512color.tiff");
dstMat = srcMat;
updataUI();
connect(ui.saveBtn, SIGNAL(clicked()), this, SLOT(saveSlot()));
}
后面无论做任何处理,处理前后图像一同变化,很是困惑。
经查询发现是由于cv的默认浅拷贝导致的,例如
srcMat = cv::imread("C:\\Users\\wcw\\Desktop\\lena512color.tiff");
dstMat = srcMat;
cv::boxFilter(srcMat, dstMat, -1, cv::Size(k, k));
那么dstMat就是srcMat的浅拷贝,二者其实共享内存,当改其中一个,另外一个也会相应变化。
由于程序设计需要,希望构造后保存等相关功能就能使用,因此在构造函数中对
dstMat=srcMat;
触发浅拷贝,所以导致了后面的问题。
正确的姿势是使用如下语句:
dstMat = srcMat.clone();
强制深拷贝,产生独立的备份,这样就不会有问题了。