基于一维的means二值化
原理:
//近视一维的means的二值化
-
一个初始化阈值T = 127,可以自己设置或者根据随机方法生成。
-
根据阈值图将每个像素数据P(n,m)分别分为对象像素数据集G1(保存像素灰度值)与背景像素数据集G2。(n为行,m为列)
-
G1的平均值是m1, G2的平均值是m2
-
一个新的阈值T’ = (m1 + m2)/2
-
回到第二步,用新的阈值继续分像素数据为对象与背景像素数据,继续2~4步,直到新的阈值与上一个阈值相同时退出循环
代码:
一维的means函数:
void* One_dimensional_means(QImage &image,QImage &opt)
{
int height = image.height();
int width = image.width();
int i=0,j=0;
int gray = 0;
double means1 = 0;
double means2 = 0;
QVector<int> sub1;
QVector<int> sub2;
//QVector<int>().swap(sub1);
//1. 一个初始化阈值T,可以自己设置或者根据随机方法生成。
int init_threshod = 127;
int final_threshod = 0;
//2. 根据阈值图每个像素数据P(n,m)分为对象像素数据G1与背景像素数据G2。(n为行,m为列)
while(init_threshod != final_threshod)
{
final_threshod = init_threshod;
for(i = 0; i<height; i++)
{
for(j = 0; j<width; j++)
{
gray = qGray(image.pixel(j,i));
if(gray > init_threshod)
{
sub1.push_back(gray);
}else {
sub2.push_back(gray);
}
}
}
//3. G1的平均值是m1, G2的平均值是m2
means1 = getMeans(sub1);
means2 = getMeans(sub2);
//一个新的阈值T’ = (m1 + m2)/2
init_threshod = (means1 + means2) / 2;
QVector<int>().swap(sub1);
QVector<int>().swap(sub2);
}
Threshold(image,opt,double(final_threshod));
return 0;
}
背景数据集与前景数据的平均值 getMeans函数:
/QVector 元素的均值
double getMeans(const QVector<int> &vect)
{
double sum = 0;
for(int i=0; i<vect.size();i++)
{
sum += vect[i];
}
return sum/vect.size();
}
二值化函数 Threshold函数 :
//二值化 (不用创建大小)
void Threshold(const QImage &inputImage,QImage &outputImage,double bThres)
{
BYTE bt;
int width = inputImage.width();
int height = inputImage.height();
QImage* output = new QImage(width,height,QImage::Format_ARGB32);
Init_Image(*output,0);
for(int i = 0; i<height; i++)
{
for(int j = 0; j<width; j++)
{
bt = qGray(inputImage.pixel(j,i));
if(bt>bThres)
{
bt = 255;
}else {
bt = 0;
}
output->setPixel(j,i,qRgb(bt, bt, bt));
}
}
outputImage = *output;
}
效果图:
原图:
二值化后的图: