我正在尝试二值化一张图片,当然首先要准备好它(灰度)
我的方法是找到灰度的最大值和最小值,然后找到中间值(这是我的阈值),然后迭代所有像素,比较当前的阈值,如果灰度大于阈值,我把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/