我正在尝试二值化一张图片,当然首先要准备好它(灰度)
我的方法是找到灰度的最大值和最小值,然后找到中间值(这是我的阈值),然后迭代所有像素,比较当前的阈值,如果灰度大于阈值,我把0放在一个矩阵中,或者把其他的放在1。
但现在我面临这个问题。通常我是用白色背景的二值图像,所以我的算法是基于这个特性的但当我遇到一个黑色背景的图像时,一切都会崩溃,但我仍然可以清楚地看到这个数字(现在0和1的开关位置)
如何解决这个问题,使我的程序更通用?
也许我最好找其他的二值化方法/
P.S.我想找一个可以理解的解释大津阈值法,但似乎要么我没有准备好面对这种困难,要么我每次都能找到非常复杂的解释,但我不能用C来写。如果有人能在这里进行HRLP,那就太好了。
很抱歉没有回答问题,只是没看到
首先-代码

for (int y=1;y<Source->Picture->Height;y++)
    for (int x=1;x<Source->Picture->Width;x++)
    {
        unsigned green = GetGValue(Source->Canvas->Pixels[x][y]);
        unsigned red = GetRValue(Source->Canvas->Pixels[x][y]);
        unsigned blue = GetBValue(Source->Canvas->Pixels[x][y]);
        threshold = (0.2125*red+0.7154*green+0.0721*blue);
        if (min>threshold)
            min=threshold;
        if (max<threshold)
            max = threshold;
    }
    middle = (max+min)/2;

然后遍历图像
        if (threshold<middle)
        {
            picture[x][y]=1;
            fprintf( fo,"1");
        } else {
            picture[x][y]=0;
            fprintf( fo,"0");
        }
    }
    fprintf( fo,"\n");
}
fclose(fo);

所以我得到一个文件,像这样的
亿
000001000元
000001000元
00001.1万
000101000号
000001000元
000001000元
000001000元
亿
在这里你可以看到一个例子。
然后我可以插入它,或者做其他的事情(识别),这取决于0和1。
但如果我换颜色,数字就不一样了。所以这种认可是行不通的。我想知道是否有一种算法能帮我解决这个问题。

最佳答案

我从未听说过大津的方法,但我了解维基百科的一些页面,所以我会尽量简化。

1 Count how many pixels are at each level of darkness.
2 "Guess" a threshold.
3 Calculate the variance of the counts of darkness less than the threshold
4 Calculate the variance of the counts of darkness greater than the threshold
5 If the variance of the darker side is greater, guess a darker threshold,
  else guess a higher threshold.
  Do this like a binary search so that it ends.
6 Turn all pixels darker than threshold black, the rest white.

Otsu的方法实际上是“最大化类间方差”,但我不理解这部分数学。
方差的概念是“值之间的距离有多远”。低方差意味着一切都是相似的。高方差意味着这些值相差很远彩虹的变化很大,颜色很多stackoverflow的背景方差为0,因为它完全是白色的,没有其他颜色方差的计算大致如下
double variance(unsigned int* counts, int size, int threshold, bool above) {
    //this is a quick trick to turn the "upper" into lower, save myself code
    if (above) return variance(counts, size-threshold, size-threshold, false);
    //first we calculate the average value
    unsigned long long atotal=0;
    unsigned long long acount=0;
    for(int i=0; i<threshold; ++i) {
        atotal += counts[i]*i //number of px times value
        acount += counts[i];
    }
    //finish calculating average
    double average = double(atotal)/count;
    //next we calculate the variance
    double vtotal=0;
    for(int i=0; i<threshold; ++i) {
        //to do so we get each values's difference from the average
        double t = std::abs(i-average);
        //and square it (I hate mathmaticians)
        vtotal += counts[i]*t*t;
    }
    //and return the average of those squared values.
    return vtotal/count;
}

关于c++ - 二值化方法,中阈值二值化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8854340/

10-11 10:49