web-dev-qa-db-ja.com

opencvでマットをコピー

Opencvを使用して画像を他の画像にコピーしようとしましたが、問題が発生しました。次のように、2つの画像は同じではありません。

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);  
}
7
Robotic Vn

_cv::Mat_の.clone()関数を使用するだけです。

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

これでうまくいきます。 _CV_8UC1_を使用して1つのチャネルのみ(つまり、灰色の陰影のみが可能)で画像を作成している場合、_CV_8UC3_または_CV_8UC4_を使用できますが、クローン機能を使用してスティックをコピーするだけです。

14

RGB CV_8UC3イメージから始めて、グレースケールCV_8UC1イメージで作業したいので、実際にはデータをコピーしたくありません。

RGBデータをグレースケールに変換するcvtColorを使用する必要があります。

#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
5
Miki

最良の方法は、opencv clone メソッドを使用することです。

cv::Mat outImg = inImg.clone();
2
Chris Maes

画像をコピーする簡単なコードを次に示します。

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

元の画像はカラーです。 cv::Mat outImg(width, height, CV_8UC1);は、新しい画像のデータ型がCV_8UC1であり、8ビットのグレースケール画像であることを示しています。だからあなたはそれが正しくないことを知っています。次に、元の画像から、実際の画像のせいぜい3分の1であるtotal pixels * 8-bitsに対応する新しい画像にデータ量をコピーしようとします(元の画像が3色、1色あたり8ビットであると仮定) 、別名24ビット画像)およびおそらく1/4(アルファチャネルがある場合は、8ビットまたは32ビット画像の4チャネルになります)。

TLDR:あなたは行列が同じタイプではなく、間違った、そして間違ったサイズのタイプからコピーされるデータのサイズについて仮定をしています。

2
RyanP