C++ OpenCV 函数"mat.at<Vec3b>(Point(j, i))"无法生成正确的像素值并崩溃



我正在尝试制作一个简单的程序,该程序读取输入图像的像素值(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...nn";
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...这意味着它认为它是蓝色的,更没有意义......我真的很困惑,如果有人对此功能及其工作原理有任何建议,我将不胜感激。

编辑:这是输出和输入图像。这就是我所说的错误,输出被剥离甚至没有完成:https://i.stack.imgur.com/FtSRz.jpg规格:
Windows 8.1
Visual Studio 2013
OpenCV 2.4.10
C++

我使用您提供的示例输入图像测试了您的代码。您的输入图像包含 Alpha 通道。所以它是一个四通道图像。您应该使用Vec4b而不是Vec3b来获得正确的结果。否则更改语句 input = imread(imgpath, CV_LOAD_IMAGE_UNCHANGED) input = imread(imgpath, CV_LOAD_IMAGE_COLOR)以 3 通道 BGR 格式加载图像并继续Vec3b .

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++)
    {

顺便说一句,BLUEREDGREEN应该是uchar而不是int

最新更新