二值化算法之(二) --- bernsen二值化

来源:互联网 发布:java金融项目经验简历 编辑:程序博客网 时间:2024/05/21 20:24

bernsen算法的中心思想:

先人为设定两个值S与TT(Bemsen最初设S为15,TT设为128),计算以图像中任意像素尸为中心的大小为k×k窗口内的所有像素的最大值M与最小值N,两者的均值T,如果朋M-N大于S,则当前P的阈值为T;若小于S,则表示该窗口所在区域灰度级灰度级差别较小,那么窗口在目标区或在背景区,再判断T与TT的关系,若T>TT则当前点灰度值为255,否则当前点灰度值为0。

改进的bernsen算法:

1.消除个别灰度特异点,设采用的阈值为T1。

T1的取值满足:
这里写图片描述

A为图像的总像素个数。

代码:

int getThreshBernsen(IplImage *src)    {        uchar num[256];        int w = src->width;        int h = src->height;        int s = src->widthStep;        int T1 = 0;        int pix = 0;        int a = w * h;        memset(num, 0, 256);        //统计灰度值的个数        for(int i=0; i<=255; i++)        {            for(int j=1; j<= h; j++)            {                for(int m=1; m<= w; m++)                {                    if(((uchar*)src->imageData + j*s)[m] == i)                    {                        num[i] = num[i] + 1;                    }                }            }        }        for(int i=255; i>=0; i--)        {            pix = pix + num[i];            if(pix >= (0.1*a))            {                T1 = i;                break;            }        }        cout << T1 << endl;        return T1;    }

2 计算每一个点的阈值
这里写图片描述
为了避免伪阴影及笔画断裂现象的产生,引入阈值T3:
这里写图片描述
对T2进行平滑滤波得到阈值T4:
这里写图片描述

IplImage *T2 = cvCreateImage(cvGetSize(src), 8, 1);        memset((uchar*)T2->imageData, 0, T2->height*T2->widthStep);        IplImage *T3 = cvCreateImage(cvGetSize(src), 8, 1);        memset((uchar*)T3->imageData, 0, T3->height*T3->widthStep);        for(int i = BOX_SIFT; i<T2->height - BOX_SIFT; i++)        {            for(int j=BOX_SIFT; j<T2->width - BOX_SIFT; j++)            {                CvRect rect;                rect.x = j - BOX_SIFT;                rect.y = i - BOX_SIFT;                rect.height = BOX_SCALE;                rect.width = BOX_SCALE;                int max_pix = getMaxPix(src, rect);                int min_pix = getMinPix(src, rect);                ((uchar *)T2->imageData + i*T2->widthStep)[j] = (min_pix + max_pix) * 0.5;                ((uchar *)T3->imageData + i*T2->widthStep)[j] = (min_pix + max_pix);            }        }IplImage *T4 = cvCreateImage(cvGetSize(src), 8, 1);        memset((uchar*)T4->imageData, 0, T4->height*T4->widthStep);        for(int i = BOX_SIFT; i<T4->height - BOX_SIFT; i++)        {            for(int j=BOX_SIFT; j<T4->width - BOX_SIFT; j++)            {                CvRect rect;                rect.x = j - BOX_SIFT;                rect.y = i - BOX_SIFT;                rect.height = BOX_SCALE;                rect.width = BOX_SCALE;                int mean = getMean(T2, rect);                ((uchar *)T4->imageData + i*T4->widthStep)[j] = mean;            }        }

3.逐点二值化
伪代码:

if f(x,y) > (1+a)*T1;    b(xy) = 255;else if f(x,y) < (1-a)*T1;    b(xy) = 0;else    if T3(x,y) > a*T1        if f(x,y) < T4(x,y)            b(x,y) = 0        else            b(x,y) = 255    else        if f(x,y) < T3(x,y)            b(x,y) = 0    else            b(x,y) = 255
1 0
原创粉丝点击