【问题标题】:Count length of black pixels on image计算图像上黑色像素的长度
【发布时间】:2017-03-25 17:43:02
【问题描述】:

我正在使用 OpenCV 来处理一些图像。

假设image.png 是黑白图像(仅BW 用于像素颜色)。

例如,如果我们打印第三行的颜色,它可能是:

WWWWWBBBWWWWWWBBBBBBWWWWWBBWWWW

我想保存每个黑色像素序列的信息,我的意思是,我希望能够为每一行计算值:

number of black sequences in row i:(以上示例为3

x-coordinate of end pixels for each black sequence in row i:(以上示例中的6,815,2026,27

length of each black sequence on row i:(以上示例中的l1=3,l2=6,l3=2)(假设上述项目已完成,这很容易)

我正在使用一些for 循环并测试颜色是否为黑色。当它为黑色时,我保存x 坐标并在内部启动其他循环以从该坐标运行到行尾,测试颜色是否为白色。当它找到白色时,它会停止并保存之前的坐标。

这仅用于计算第一个黑色像素序列的长度。我不知道下一步该怎么走(我什至不知道有多少)。

这是代码的主要部分(带有一些垃圾代码):

for(int y=0;y<img.rows;y++) //img.rows
    {
        for(int x=0;x<img.cols;x++)
        {
            Vec3b color = image.at<Vec3b>(Point(x,y));
            printf("(%d,%d,%d)\n",color[1],color[2],color[3]);
            if(color[0] == 0 && color[1] == 0 && color[2] == 0)
            {
                cor[0]='B';
                ymax = y;
                if (ymin == -1) { ymin = y; }
                int xmin = x;
                int diam_esq = img.cols/2-xmin;
                double dist_esq = sqrt( (x-img.cols/2)*(x-img.cols/2) + (y-img.rows/2)*(y-img.rows/2) );
                for(int z=x;z<img.cols;z++)
                {
                    Vec3b colorz = image.at<Vec3b>(Point(z,y));
                    if(colorz[0] == 255 && colorz[1] == 255 && colorz[2] == 255)
                    {
                        int xmax = z-1;
                        int diam_dir = xmax-img.cols/2;
                        double dist_dir = sqrt( (z-1-img.cols/2)*(z-1-img.cols/2) + (y-img.rows/2)*(y-img.rows/2) );
                        int diam = xmax - xmin;
                        //printf("y=%*d, xmin=%*d, xmax=%*d, esq=%*d, dir=%*d, diam=%*d\n",5,y,5,xmin,5,xmax,5,diam_esq,5,diam_dir,5,diam);
                        printf("%*d%*d%*d%*d%*d%*d%*f%*f\n",5,y,5,xmin,5,xmax,5,diam_esq,5,diam_dir,5,diam,13,dist_esq,13,dist_dir);
                        break;
                    }
                }
                break;
            }
        }
        //break; // only y=0
    }

【问题讨论】:

    标签: opencv image-processing


    【解决方案1】:

    这里有一些代码可以满足您的需求。它只打印结果。它不会将它们保存在任何地方,但我认为您会知道如何执行此操作。

    要在每一行中查找黑色序列,无需为每个序列进行嵌套 for 循环,只需跟踪您是否在黑色序列中,如果是,则跟踪它的开始位置。另外,我使用Mat::ptr 可以更有效地逐行遍历您的图像。

    for(int i = 0; i < image.rows; i++) {
        Vec3b* ptr = image.ptr<Vec3b>(i);
        bool blackSequence = false;
        int blackSequenceStart = -1;
        int numberOfBlackSequences = 0;
    
        for(int j = 0; j < image.cols; j++) {
            Vec3b color = ptr[j];
            if(color[0] == 0 && !blackSequence) { // this is assuming that all pixels are either white or black
                blackSequence = true;
                blackSequenceStart = j;
                numberOfBlackSequences++;
            }
            if(color[0] == 255 && blackSequence) {
                blackSequence = false;
                cout << "Row " << i << ": Sequence " << numberOfBlackSequences << " starts at " << blackSequenceStart 
                       << " and finishes at " << j - 1 << ". Total length: " << j - blackSequenceStart << endl;
            }
            if(j == image.cols - 1 && blackSequence) {
                blackSequence = false;
                cout << "Row " << i << ": Sequence " << numberOfBlackSequences << " starts at " << blackSequenceStart 
                       << " and finishes at " << j << ". Total length: " << j - blackSequenceStart + 1 << endl;
            }
        }
    }
    

    【讨论】:

    • 我理解你的代码。它看起来工作。所以它有助于确认我在这里发布的一些问题:stackoverflow.com/q/43020806/1778537 我在这个i.imgur.com/UjToips.png 上运行你的代码,结果不是恒定的。几乎可以肯定,问题在于 OpenCV 如何读取像素颜色。如果您有时间,请阅读引用的帖子。
    • 如果我们在i.imgur.com/UjToips.png 上测试,长度应该是61,因为黑色区域是从(20,10)(80,50) 的矩形(width=60height=40)。你同意吗?
    • @Sigur 是的,应该是61。如果你举一个小例子,矩形从(0,0)到(1,1),那么宽度是两个像素=> 2跨度>
    • 奇怪。它打印了很多长度:有时是20,21,20(总和为61)。但对于某些行,它是66。我必须学习。
    • color = ptr[j] 应该是什么?一行还是一列?无论如何,它的0坐标color[0]应该是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 2013-10-10
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多