我正在尝试将一个图像复制到另一个像素(我知道有复杂的方法可用。我正在尝试解决另一个问题并且回答这个问题会很有用)。
这是我的代码:
int main()
{
Mat Img;
Img = imread("../../../stereo_images/left01.jpg");
Mat copyImg = Mat::zeros(Img.size(), CV_8U);
for(int i=0; i<Img.rows; i++){
for(int j=0; j<Img.cols; j++){
copyImg.at<uchar>(j,i) = Img.at<uchar>(j,i);
}}
namedWindow("Image", CV_WINDOW_AUTOSIZE );
imshow("Image", Img);
namedWindow("copyImage", CV_WINDOW_AUTOSIZE );
imshow("copyImage", copyImg);
waitKey(0);
return 0;
}
当我在visual studio中运行此代码时,我收到以下错误
OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)si
ze.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channel
s()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3
) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file c:\opencv\opencv-2.4.9\ope
ncv\build\include\opencv2\core\mat.hpp, line 537
我知道Img的类型是CV_8U。为什么会这样?
谢谢!
答案 0 :(得分:5)
// will read in a rgb image , no matter what the content is
Img = imread("../../../stereo_images/left01.jpg");
使其读取灰度图像使用:
Img = imread("../../../stereo_images/left01.jpg", CV_LOAD_IMAGE_GRAYSCALE);
然后,你不需要复制每个像素(你甚至应该避免这种情况),只需使用:
Mat im2 = Img.clone();
如果你进行逐像素循环,请注意使索引正确。它在这里的行col世界,而不是x,y,所以它应该是:
copyImg.at<uchar>(i,j) = Img.at<uchar>(i,j);
在你的情况下
答案 1 :(得分:3)
你的问题在于这一行:
copyImg.at<uchar>(j,i) = Img.at<uchar>(j,i);
应该是:
copyImg.at<uchar>(i,j) = Img.at<uchar>(i,j);
请注意,如果您想复制图片,可以执行以下操作:
Mat copyImg = Img.clone();
答案 2 :(得分:3)
我知道Img的类型是CV_8U。
但CV_8U只是图像深度( 8 - 位 U - 已签名)。该类型还指定了通道数,通常为三个。一个用于蓝色,一个用于绿色,一个用于红色,默认为OpenCV。类型为CV_8UC3( C -hannels = 3 )。默认情况下,imread
甚至会将黑白图像转换为3通道图像。 imread(filename, CV_LOAD_IMAGE_GRAYSCALE)
将加载1通道图像(CV_8UC1)。但如果您不确定最简单的解决方案是
Mat copyImg = Mat::zeros(Img.size(), Img.type());
要访问数组元素,您必须知道它的大小。在3通道图像上使用.at<uchar>()
只能访问第一个通道,因为每个像素有3 * 8位。因此,在3通道图像上,您必须使用
copyImg.at<Vec3b>(i,j) = Img.at<Vec3b>(i,j);
其中Vec3b
是cv::Vec<uchar, 3>
。您还应该注意at<>(,)
的第一个参数是沿着dim 0的索引,它们是行和第二个参数cols。或者换句话说,在经典的2d-xy-chart顺序中,您可以使用.at<>(y,x) == .at<>(Point(x,y))
访问像素。