在opencv中复制Mat
Copy Mat in opencv
我尝试使用 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);
}
最好的方法是使用opencvclone方法:
cv::Mat outImg = inImg.clone();
只需使用cv::Mat
的.clone()
函数:
cv::Mat source = cv::imread("basic_shapes.png");
cv::Mat dst = source.clone();
这样就可以了。
您正在使用 CV_8UC1
制作只有一个通道的图像(这意味着只有灰色阴影是可能的),您可以使用 CV_8UC3
或 CV_8UC4
但为了简单地复制,请使用克隆功能。
您的原始图片是彩色的。 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:您的矩阵不是同一类型,并且您正在假设要从不正确且大小不正确的类型中复制的数据大小。
您实际上不想复制数据,因为您从 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
下面是复制图片的简单代码。
#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);
}
Mat source = imread("1.png", 0);
Mat dest;
source.copyTo(dest);
我尝试使用 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);
}
最好的方法是使用opencvclone方法:
cv::Mat outImg = inImg.clone();
只需使用cv::Mat
的.clone()
函数:
cv::Mat source = cv::imread("basic_shapes.png");
cv::Mat dst = source.clone();
这样就可以了。
您正在使用 CV_8UC1
制作只有一个通道的图像(这意味着只有灰色阴影是可能的),您可以使用 CV_8UC3
或 CV_8UC4
但为了简单地复制,请使用克隆功能。
您的原始图片是彩色的。 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:您的矩阵不是同一类型,并且您正在假设要从不正确且大小不正确的类型中复制的数据大小。
您实际上不想复制数据,因为您从 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
下面是复制图片的简单代码。
#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);
}
Mat source = imread("1.png", 0);
Mat dest;
source.copyTo(dest);