Opencvを使用して画像を他の画像にコピーしようとしましたが、問題が発生しました。次のように、2つの画像は同じではありません。
これは私が使用したコードです:
#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);
}
_cv::Mat
_の.clone()
関数を使用するだけです。
_cv::Mat source = cv::imread("basic_shapes.png");
cv::Mat dst = source.clone();
_
これでうまくいきます。 _CV_8UC1
_を使用して1つのチャネルのみ(つまり、灰色の陰影のみが可能)で画像を作成している場合、_CV_8UC3
_または_CV_8UC4
_を使用できますが、クローン機能を使用してスティックをコピーするだけです。
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
最良の方法は、opencv clone メソッドを使用することです。
cv::Mat outImg = inImg.clone();
画像をコピーする簡単なコードを次に示します。
#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);
}
元の画像はカラーです。 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:あなたは行列が同じタイプではなく、間違った、そして間違ったサイズのタイプからコピーされるデータのサイズについて仮定をしています。