在opencv中复制Mat

时间:2015-07-16 15:32:33

标签: c++ opencv mat

我尝试使用opencv将图像复制到其他图像,但是我遇到了问题。两张图片不一样,如下:

enter image description here

这是我使用的代码:

#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);  
}

5 个答案:

答案 0 :(得分:11)

只需使用.clone()的{​​{1}}功能:

cv::Mat

这样就可以了。    您使用cv::Mat source = cv::imread("basic_shapes.png"); cv::Mat dst = source.clone(); 仅使用一个通道制作图像(这意味着只能使用灰色阴影),您可以使用CV_8UC1CV_8UC3,但只需使用克隆功能复制即可。

答案 1 :(得分:5)

您实际上不想复制数据,因为您从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

答案 2 :(得分:2)

最好的方法是使用opencv clone方法:

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

答案 3 :(得分:2)

您的原始图片是彩色的。 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:你的矩阵不是同一类型,你假设要从不正确和不正确大小的类型中复制数据的大小。

答案 4 :(得分:2)

这是一个复制图像的简单代码。

 #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);  
}