C++ OpenCV 函数 "mat.at<Vec3b>(Point(j, i))" 未产生正确的像素值并崩溃
C++ OpenCV function "mat.at<Vec3b>(Point(j, i))" not yielding correct pixel values and crashing
我正在尝试编写一个简单的程序来读取输入图像的像素值 (BGR) 并生成相同大小的输出图像,但如果原始图片中的像素为白色,则输出图像的像素 (相同位置)为蓝色,如果像素不是白色,则使输出图像中的相同像素为黑色。但是我很难让它正常工作。这看起来很容易,但它并没有像我期望的那样表现。下面是我的代码:
Mat input;
Mat output;
Vec3b color;
input = imread("C:/temp/COLORTEST2.png", CV_LOAD_IMAGE_UNCHANGED);
output = input;
int rows = input.rows;
int cols = input.cols;
int Blue, Green, Red;
cout << "Rows: " << rows << "\nColumns: " << cols << "\nTotal Pixels: " << (rows*cols) << endl;
cout << "Calculating...\n\n";
for (j = 0; j < rows; j++)
{
for (i = 0; i < cols; i++)
{
color = input.at<Vec3b>(Point(j, i));
Blue = color.val[0];
Green = color.val[1];
Red = color.val[2];
if (Blue == 255 && Green == 255 && Red == 255){
W++; //White count +1
output.at<Vec3b>(Point(j, i))[0] = 255;
output.at<Vec3b>(Point(j, i))[1] = 0;
output.at<Vec3b>(Point(j, i))[2] = 0;
}
else{
NW++; //NonWhite count +1
output.at<Vec3b>(Point(j, i))[0] = 0;
output.at<Vec3b>(Point(j, i))[1] = 0;
output.at<Vec3b>(Point(j, i))[2] = 0;
//cin >> response;
}
}
}
cout << "White Pixels: " << W << "\nNon-White Pixels: " << NW << endl;
imwrite("C:/temp/Output.png", output);
waitKey();
就像我说的,看起来很简单,但是当我 运行 它时它崩溃了。如果我在 for 循环中切换行和列,它 运行 没问题,但输出图像看起来并不像它应该的那样(带有一些黑色像素的垂直条带)。函数 "mat.at(Point(j, i))" 似乎是问题所在,看起来它在某个点崩溃了,好像它正在寻找一个不存在的点,几乎就像切换了行和列但是没有意义...我还通过制作 MS 绘画图片 (20 x 30) 并将单个黑色像素置于 1x1 处对其进行了测试,它表示在 1x1 时其 BGR 为 255、0、0...这意味着它认为它是蓝色的,更没有意义......我真的很困惑,如果有人对此功能及其工作方式有任何建议,我将非常感激。
编辑:这是输出和输入图像。这就是我所说的错误,输出被剥离甚至没有完成:http://imgur.com/a/DPRlO
规格:
Windows8.1
Visual Studio 2013
OpenCV 2.4.10
C++
output = input;
这是一个浅拷贝。这意味着每次更改输出数据时,输入数据都会更改。你应该这样做:
output = input.clone();
Point(x,y)
=> x 指列,y 指行。你反着做了。
改变那些:
for (j = 0; j < rows; j++)
{
for (i = 0; i < cols; i++)
{
致那些:
for (j = 0; j < cols; j++)
{
for (i = 0; i < rows; i++)
{
顺便说一句 BLUE
,RED
,GREEN
应该是 uchar
而不是 int
.
我用样本输入图像测试了你的代码,你 provided.Your 输入图像包含 alpha channel.So 它是一个四通道 image.you 应该使用 Vec4b
而不是 Vec3b
得到正确的结果。
否则改变声明
input = imread(imgpath, CV_LOAD_IMAGE_UNCHANGED)
到 input = imread(imgpath, CV_LOAD_IMAGE_COLOR)
以 3 通道 BGR 格式加载图像并继续 Vec3b
。
我正在尝试编写一个简单的程序来读取输入图像的像素值 (BGR) 并生成相同大小的输出图像,但如果原始图片中的像素为白色,则输出图像的像素 (相同位置)为蓝色,如果像素不是白色,则使输出图像中的相同像素为黑色。但是我很难让它正常工作。这看起来很容易,但它并没有像我期望的那样表现。下面是我的代码:
Mat input;
Mat output;
Vec3b color;
input = imread("C:/temp/COLORTEST2.png", CV_LOAD_IMAGE_UNCHANGED);
output = input;
int rows = input.rows;
int cols = input.cols;
int Blue, Green, Red;
cout << "Rows: " << rows << "\nColumns: " << cols << "\nTotal Pixels: " << (rows*cols) << endl;
cout << "Calculating...\n\n";
for (j = 0; j < rows; j++)
{
for (i = 0; i < cols; i++)
{
color = input.at<Vec3b>(Point(j, i));
Blue = color.val[0];
Green = color.val[1];
Red = color.val[2];
if (Blue == 255 && Green == 255 && Red == 255){
W++; //White count +1
output.at<Vec3b>(Point(j, i))[0] = 255;
output.at<Vec3b>(Point(j, i))[1] = 0;
output.at<Vec3b>(Point(j, i))[2] = 0;
}
else{
NW++; //NonWhite count +1
output.at<Vec3b>(Point(j, i))[0] = 0;
output.at<Vec3b>(Point(j, i))[1] = 0;
output.at<Vec3b>(Point(j, i))[2] = 0;
//cin >> response;
}
}
}
cout << "White Pixels: " << W << "\nNon-White Pixels: " << NW << endl;
imwrite("C:/temp/Output.png", output);
waitKey();
就像我说的,看起来很简单,但是当我 运行 它时它崩溃了。如果我在 for 循环中切换行和列,它 运行 没问题,但输出图像看起来并不像它应该的那样(带有一些黑色像素的垂直条带)。函数 "mat.at(Point(j, i))" 似乎是问题所在,看起来它在某个点崩溃了,好像它正在寻找一个不存在的点,几乎就像切换了行和列但是没有意义...我还通过制作 MS 绘画图片 (20 x 30) 并将单个黑色像素置于 1x1 处对其进行了测试,它表示在 1x1 时其 BGR 为 255、0、0...这意味着它认为它是蓝色的,更没有意义......我真的很困惑,如果有人对此功能及其工作方式有任何建议,我将非常感激。
编辑:这是输出和输入图像。这就是我所说的错误,输出被剥离甚至没有完成:http://imgur.com/a/DPRlO
规格:
Windows8.1
Visual Studio 2013
OpenCV 2.4.10
C++
output = input;
这是一个浅拷贝。这意味着每次更改输出数据时,输入数据都会更改。你应该这样做:
output = input.clone();
Point(x,y)
=> x 指列,y 指行。你反着做了。
改变那些:
for (j = 0; j < rows; j++)
{
for (i = 0; i < cols; i++)
{
致那些:
for (j = 0; j < cols; j++)
{
for (i = 0; i < rows; i++)
{
顺便说一句 BLUE
,RED
,GREEN
应该是 uchar
而不是 int
.
我用样本输入图像测试了你的代码,你 provided.Your 输入图像包含 alpha channel.So 它是一个四通道 image.you 应该使用 Vec4b
而不是 Vec3b
得到正确的结果。
否则改变声明
input = imread(imgpath, CV_LOAD_IMAGE_UNCHANGED)
到 input = imread(imgpath, CV_LOAD_IMAGE_COLOR)
以 3 通道 BGR 格式加载图像并继续 Vec3b
。