简体   繁体   English

在opencv中复制Mat

[英]Copy Mat in opencv

I try to copy a image to other image using opencv, but I got a problem. 我尝试使用opencv将图像复制到其他图像,但我遇到了问题。 Two image is not the same, like this: 两个图像不一样,像这样:

在此输入图像描述

This is the code I used: 这是我使用的代码:

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

Simply use .clone() function of cv::Mat : 只需使用cv::Mat .clone()函数:

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

This will do the trick. 这样就可以了。 You are making an image with one channel only (which means only shades of gray are possible) with CV_8UC1 , you could use CV_8UC3 or CV_8UC4 but for simply copying stick with the clone function. 您正在图像时,仅一个通道(这意味着只有灰色的色调是可能的) CV_8UC1 ,你可以使用CV_8UC3CV_8UC4但简单地复制坚持使用克隆功能。

You actually don't want to copy the data, since you start with a RGB CV_8UC3 image, and you want to work on a grayscale CV_8UC1 image. 您实际上不想复制数据,因为您从RGB CV_8UC3图像开始,并且您想要处理灰度CV_8UC1图像。

You should use cvtColor , that will convert your RGB data into grayscale. 您应该使用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();  
}

With a simple memcopy you're copying a sequence of uchar like this: 使用简单的memcopy您可以像这样复制一系列uchar

BGR BGR BGR BGR  ...

into an image that expects them to be (G for gray): 到期望它们的图像(G代表灰色):

G G G G ...

and that's is causing your outImg to be uncorrect. 那就是导致你的outImg不正确。

Your code will be correct if you define outImage like: 如果您定义outImage您的代码将是正确的:

cv::Mat outImg(width, height, CV_8UC3);  // Instead of CV_8UC1

最好的方法是使用opencv 克隆方法:

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

Your original image is in color. 您的原始图像是彩色的。 cv::Mat outImg(width, height, CV_8UC1); says that your new image is of data type CV_8UC1 which is an 8-bit grayscale image. 说你的新图像是数据类型CV_8UC1 ,它是一个8位灰度图像。 So you know that is not correct. 所以你知道这是不正确的。 Then you try to copy the amount of data from the original image to the new image that corresponds to total pixels * 8-bits which is at best 1/3 of the actual image (assuming the original image was 3 color, 8-bits per color, aka a 24-bit image) and perhaps even 1/4 (if it had an alpha channel, making it 4 channels of 8-bits or a 32-bit image). 然后尝试将原始图像中的数据量复制到与total pixels * 8-bits对应的新图像,最多为实际图像的1/3(假设原始图像为3色,每个8位)颜色,也称为24位图像),甚至可能是1/4(如果它有一个alpha通道,使其成为4通道的8位或32位图像)。

TLDR: you're matrices aren't the same type, and you are making assumptions about the size of the data to be copied off of an incorrect, and incorrectly sized type. TLDR:您的矩阵类型不同,并且您正在假设要从不正确且大小不正确的类型复制的数据大小。

Here is a simple code to copy image. 这是一个复制图像的简单代码。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM