[Discusión sobre copia profunda y copia superficial de datos cv::Mat en opencv]


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

Insertar descripción de la imagen aquí
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)

Insertar descripción de la imagen aquí
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()

Insertar descripción de la imagen aquí
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)

Insertar descripción de la imagen aquí
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.

Supongo que te gusta

Origin blog.csdn.net/haohaohaihuai/article/details/131652744
Recomendado
Clasificación