cv::Mat datos copia profunda y copia superficial
En muchos casos, además de una arquitectura poderosa, los detalles también son muy importantes al escribir un programa. Como dice el refrán, los detalles determinan el éxito o el fracaso. Al usar cv::Mat para el procesamiento de imágenes, descubrí que este tipo de datos tiene profundas copia y copia superficial, así que pensé en echarle un vistazo.
cv::método de copia Mat
Supongamos que los datos de la imagen original aquí son matSrc:
método de copia | resultado |
---|---|
matA = matSrc | Copia superficial |
matB(matSrc ) | Copia superficial |
matC = matSrc .clon() | copia profunda |
matSrc .copyTo(matD) | copia profunda |
prueba experimental
Pruebe el código, agregue texto o imágenes superpuestas a la imagen copiada y compare la imagen original y la imagen copiada para ver si la imagen original ha cambiado. Aquí la ventana opencv se usa para incrustarla en la ventana Qt para su visualización:
#include "widget.h"
#include "./ui_widget.h"
#include <Windows.h>
#include <opencv2/highgui/highgui_c.h>
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
cv::Mat src = cv::imread("C:/Users/003/Desktop/qt6demo/img/20230214134245.png");
#if 1
cv::Mat matA = src;
cv::putText(matA, "MatA", cv::Point(200, 50), 16, 1.0, cv::Scalar(0, 255, 0), 2);
//先显示拷贝的图片
showImage("matA", matA, ui->picLabel2);
#elif 0
cv::Mat matB(src);
cv::putText(matB, "MatB", cv::Point(200, 50), 16, 1.0, cv::Scalar(0, 255, 0), 2);
//先显示拷贝的图片
showImage("matB", matA, ui->picLabel2);
#elif 0
cv::Mat matC = src.clone();
cv::putText(matC, "MatC", cv::Point(200, 50), 16, 1.0, cv::Scalar(0, 255, 0), 2);
//先显示拷贝的图片
showImage("matC", matA, ui->picLabel2);
#else
cv::Mat matD;
src.copyTo(matD);
cv::putText(matD, "MatD", cv::Point(200, 50), 16, 1.0, cv::Scalar(0, 255, 0), 2);
//先显示拷贝的图片
showImage("matD", matA, ui->picLabel2);
#endif
//再显示原图看是否改变
showImage("src", src, ui->picLabel1);
}
Widget::~Widget()
{
delete ui;
}
void Widget::showImage(std::string name, cv::Mat& mat, QLabel* label)
{
cv::namedWindow(name, cv::WINDOW_AUTOSIZE);
cv::imshow(name, mat);
HWND hwnd = (HWND)cvGetWindowHandle(name.c_str());
HWND phwnd = GetParent(hwnd);
SetParent(hwnd, (HWND)label->winId());
ShowWindow(phwnd, SW_HIDE);
cv::resizeWindow(name, cv::Size(540, 318));
}
1. matA = matSrc
Resultados de la prueba: después de agregar texto a la imagen copiada, la imagen original también cambió, por lo que esta es una copia superficial, los datos no se copian por completo, solo se asigna el puntero de datos.
2.matB(matSrc)
Resultados de la prueba: después de agregar texto a la imagen copiada, la imagen original también cambió, por lo que esta es una copia superficial, los datos no se copian por completo, solo se asigna el puntero de datos.
3.matC = matSrc.clon()
Resultados de la prueba: después de agregar texto a la imagen copiada, la imagen original no ha cambiado, por lo que se trata de una copia profunda y se han copiado todos los datos.
4.matSrc.copyTo(matD)
Resultados de la prueba: después de agregar texto a la imagen copiada, la imagen original no ha cambiado, por lo que se trata de una copia profunda y se han copiado todos los datos.
Autor: Programador Feima.
Bienvenido al intercambio técnico: QQ: 255895056.
Indique la fuente de la reimpresión. Si hay algo inapropiado, corríjame.