C++ C++;OpenCV函数“;材料at<;Vec3b>;(第(j,i)点)“;不产生正确的像素值和崩溃
我试图制作一个简单的程序,读取输入图像的像素值(BGR)并生成相同大小的输出图像,但如果原始图像中的像素为白色,则输出图像的像素(相同位置)为蓝色,如果像素不是白色,则使输出图像中的相同像素为黑色。但是我很难让它正常工作。这看起来很简单,但它不像我期望的那样。下面是我的代码:C++ C++;OpenCV函数“;材料at<;Vec3b>;(第(j,i)点)“;不产生正确的像素值和崩溃,c++,arrays,opencv,for-loop,pixels,C++,Arrays,Opencv,For Loop,Pixels,我试图制作一个简单的程序,读取输入图像的像素值(BGR)并生成相同大小的输出图像,但如果原始图像中的像素为白色,则输出图像的像素(相同位置)为蓝色,如果像素不是白色,则使输出图像中的相同像素为黑色。但是我很难让它正常工作。这看起来很简单,但它不像我期望的那样。下面是我的代码: Mat input; Mat output; Vec3b color; input = imread("C:/temp/COLORTEST2.png", CV_LOAD_IMAGE_UNCHANGED); output =
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();
Mat输入;
垫输出;
Vec3b颜色;
输入=imread(“C:/temp/COLORTEST2.png”,CV\u加载\u图像\u不变);
输出=输入;
int rows=input.rows;
int cols=input.cols;
蓝色、绿色、红色;
库特
这是一份肤浅的副本。这意味着每次更改输出数据时,输入的数据都会更改。你应该这样做:
output = input.clone();
点(x,y)
=>x表示列,y表示行。你的做法是相反的
改变这些:
for (j = 0; j < rows; j++)
{
for (i = 0; i < cols; i++)
{
(j=0;j
{
对于(i=0;i
对那些:
for (j = 0; j < cols; j++)
{
for (i = 0; i < rows; i++)
{
(j=0;j
{
对于(i=0;i
顺便说一句,蓝色
,红色
,绿色
应该是uchar
而不是int
这是一个浅拷贝。这意味着每次更改输出数据时,输入数据都会更改。您应该这样做:
output = input.clone();
点(x,y)
=>x表示列,y表示行。您正在反向操作
改变这些:
for (j = 0; j < rows; j++)
{
for (i = 0; i < cols; i++)
{
(j=0;j
{
对于(i=0;i
对那些:
for (j = 0; j < cols; j++)
{
for (i = 0; i < rows; i++)
{
(j=0;j
{
对于(i=0;i
顺便说一句,BLUE
,RED
,GREEN
应该是uchar
而不是int
,我用您提供的示例输入图像测试了您的代码。您的输入图像包含阿尔法通道。因此它是一个四通道图像。您应该使用Vec4b
而不是Vec3b
,以获得正确的结果。
否则,请更改声明
input=imread(imgpath,CV\u LOAD\u IMAGE\u不变)
toinput=imread(imgpath,CV\u LOAD\u IMAGE\u COLOR)
要加载3通道BGR格式的图像并继续使用Vec3b
我使用您提供的示例输入图像测试了您的代码。您的输入图像包含alpha通道。因此它是一个四通道图像。您应该使用Vec4b
而不是Vec3b
来获得正确的结果。
否则,请更改声明
input=imread(imgpath,CV\u LOAD\u IMAGE\u不变)
toinput=imread(imgpath,CV\u LOAD\u IMAGE\u COLOR)
若要加载3通道BGR格式的图像并继续使用Vec3b
请共享错误消息,该行崩溃..有助于快速识别问题的任何信息请共享错误消息,该行崩溃..有助于快速识别问题的任何信息我已做出了您建议的更改ed,它工作得稍微好一点,但输出没有真正意义。这里是输入和输出:正如你所看到的,有大量白线穿过它,好像它跳过了列,甚至没有完成最右边的部分。你确定像素是100%白色吗?例如,它们可能是255 254 255。你应该检查蓝色、红色、绿色例如,在240-255的范围内,而恰恰是255,所以我做了你建议的更改,它工作得更好一些,但输出没有真正意义。这里是输入和输出:正如你所看到的,有大量的白线穿过它,好像它跳过了列,甚至没有完成最右边的部分。你确定像素are 100%白色?例如,它们可能是255 254 255..您应该检查蓝色、红色、绿色是否在例如240-255的范围内,而不是255为什么不需要点?它与不使用点有什么区别?此外,输出图像是条带化的,甚至没有完成:很抱歉回答不准确。我编辑了我的答案并提供了正确的解决方案解决您面临的问题。使用指针时,我们需要像这样访问像素。.img.at(Point(col,row))。没有指针,您可以像这样访问.input.at((row,col))啊,我不知道它是4通道。这解决了问题,我甚至不知道这是一个问题…或者它甚至是4通道开始,仍然是新的OpenCV。非常感谢!为什么不需要点?它与使用它没有点有什么不同?另外,输出图像是条带化的,甚至没有完成:对不起,回答不准确。我编辑了我的答案,为您面临的问题提供了正确的解决方案。使用指针,我们需要像这样访问像素..img.at(Point(col,row))。没有指针,您可以像这样访问.input.at((row,col))啊,我不知道它是4通道。这解决了问题,我甚至不知道这是一个问题…或者它甚至是4通道开始,仍然是新的OpenCV。非常感谢!