【问题标题】:Copy Mat in opencv在opencv中复制Mat
【发布时间】:2015-10-06 03:44:54
【问题描述】:

我尝试使用 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);  
}

【问题讨论】:

    标签: c++ opencv mat


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 感谢您的帮助,但我想使用 Mat.data 作为无符号字符数组。我需要做一些与此相关的事情
        • 这种情况下你可能需要转换成CV_8UC3格式,那就更复杂了……
        • open cv 具有在数据类型(8UC1 -> 8UC3、8UC3 -> 8UC1 等)之间转换矩阵的功能。您需要确保在使用指向矩阵数据的原始指针之前,您已将该矩阵转换为您将使用指针的数据类型。
        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-16
            • 2023-04-05
            • 2015-04-22
            • 1970-01-01
            相关资源
            最近更新 更多