在opencv中复制Mat

Copy Mat in opencv

我尝试使用 opencv 将一个图像复制到另一个图像,但我遇到了问题。两张图片不一样,像这样:

这是我使用的代码:

#include <opencv2\opencv.hpp>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cmath>
#include <iostream>
#include <opencv2\opencv.hpp>
int main()
{
    cv::Mat inImg =    cv::imread("C:\Users\DUY\Desktop\basic_shapes.png");  
    //Data point copy  
    unsigned char * pData = inImg.data;  

    int width = inImg.rows;  
    int height = inImg.cols;  

    cv::Mat outImg(width, height, CV_8UC1);  
    //data copy using memcpy function  
    memcpy(outImg.data, pData, sizeof(unsigned char)*width*height);  

   //processing and copy check  
   cv::namedWindow("Test");  
   imshow("Test", inImg);  

   cv::namedWindow("Test2");  
   imshow("Test2", outImg);  

   cvWaitKey(0);  
}

最好的方法是使用opencvclone方法:

cv::Mat outImg = inImg.clone();

只需使用cv::Mat.clone()函数:

cv::Mat source = cv::imread("basic_shapes.png");
cv::Mat dst = source.clone();

这样就可以了。 您正在使用 CV_8UC1 制作只有一个通道的图像(这意味着只有灰色阴影是可能的),您可以使用 CV_8UC3CV_8UC4 但为了简单地复制,请使用克隆功能。

您的原始图片是彩色的。 cv::Mat outImg(width, height, CV_8UC1); 表示您的新图像的数据类型为 CV_8UC1,即 8 位灰度图像。所以你知道那是不正确的。然后你尝试将原始图像的数据量复制到对应于 total pixels * 8-bits 的新图像,它最多是实际图像的 1/3(假设原始图像是 3 种颜色,每种颜色 8 位,又名 24 位图像)甚至可能是 1/4(如果它有一个 alpha 通道,使其成为 4 个 8 位通道或 32 位图像)。

TLDR:您的矩阵不是同一类型,并且您正在假设要从不正确且大小不正确的类型中复制的数据大小。

您实际上不想复制数据,因为您从 RGB CV_8UC3 图像开始,并且想要处理灰度 CV_8UC1 图像。

您应该使用 cvtColor,它将您的 RGB 数据转换为灰度。

#include <opencv2\opencv.hpp>
#include <iostream>

using namespace cv;

int main()
{
    Mat inImg = cv::imread("C:\Users\DUY\Desktop\basic_shapes.png"); // inImg is CV_8UC3 
    Mat outImg;
    cvtColor(inImg, outImg, COLOR_RGB2GRAY); // Now outImg is CV_8UC1

    //processing and copy check  
    imshow("Test", inImg);  
    imshow("Test2", outImg);  
    waitKey();  
}

使用简单的 memcopy,您将像这样复制 uchar 的序列:

BGR BGR BGR BGR  ...

转换为预期的图像(G 代表灰色):

G G G G ...

这导致您的 outImg 不正确。

如果您将 outImage 定义为:

,您的代码将是正确的
cv::Mat outImg(width, height, CV_8UC3);  // Instead of CV_8UC1

下面是复制图片的简单代码。

 #include <opencv2/opencv.hpp>  
 #include <opencv2/highgui/highgui.hpp>  
 #include <opencv2/imgproc/imgproc.hpp>  
 #include <cmath> 
 int main()  
 {  
    cv::Mat inImg = cv::imread("1.jpg");  

    cv::Mat outImg = inImg.clone();   

   cv::namedWindow("Test");  
   imshow("Test", inImg);

   cv::namedWindow("Test2");  
   imshow("Test2", outImg);

   cvWaitKey(0);  
}
Mat source = imread("1.png", 0);
Mat dest;
source.copyTo(dest);