c++ 图像处理(十六) 三角法的二值化法

三角法的二值化法

原理:

  1. 图像转灰度
  2. 计算图像灰度直方图
  3. 寻找直方图中两侧边界
  4. 寻找直方图最大值
  5. 检测是否最大波峰在亮的一侧,否则翻转
  6. 计算阈值得到阈值T,如果翻转则255-T

代码:

/*
8. 图像转灰度
9. 计算图像灰度直方图
10. 寻找直方图中两侧边界
11. 寻找直方图最大值
12. 检测是否最大波峰在亮的一侧,否则翻转
13. 计算阈值得到阈值T,如果翻转则255-T
//三角法图像二值化
*/
void* Triangle(QImage &image,QImage &otpImage)
{
    int width = image.width();
    int height = image.height();
    int i = 0,j = 0;
    int gray;
    int temp = 0;
    bool isflipped = false;

    QVector<int> histogram(256);


    //直方图
    for(int row = 0; row < height; row++)
    {
        for(int col = 0; col<width; col++)
        {
            gray = qGray(image.pixel(col,row));
            histogram[gray] ++;
        }
    }

    //3. 寻找直方图中两侧边界
    int left_bound = 0;
    int right_bound = 0;
    int max = 0;
    int max_index = 0;

    //左侧为零的位置
    for(i = 0; i<256; i++)
    {
        if(histogram[i]>0)
        {
            left_bound = i;
            break;
        }
    }
    //直方图为零的位置
    if(left_bound > 0)
    {
        left_bound --;
    }


    //直方图右侧为零的位置
    for(i = 255; i>0; i--)
    {
        if(histogram[i]>0)
        {
            right_bound = i;
            break;
        }
    }
    //直方图为零的地方
    if(right_bound >0)
    {
        right_bound++;
    }

    //4. 寻找直方图最大值
    for(i = 0; i<256;i++)
    {
        if(histogram[i] > max)
        {
            max = histogram[i];
            max_index = i;
        }
    }

    //判断最大值是否在最左侧,如果是则不用翻转
    //因为三角法二值化只能适用于最大值在最右侧
    if(max_index - left_bound  < right_bound - max_index)
    {
        isflipped = true;
        i = 0;
        j = 255;
        while( i < j )
        {
            // 左右交换
            temp = histogram[i]; histogram[i] = histogram[j]; histogram[j] = temp;
            i++; j--;
        }
        left_bound = 255-right_bound;
        max_index = 255-max_index;
    }


    // 计算求得阈值
    double thresh = left_bound;
    double a, b, dist = 0, tempdist;
    a = max; b = left_bound-max_index;
    for( i = left_bound+1; i <= max_index; i++ )
    {
       // 计算距离 - 不需要真正计算
       tempdist = a*i + b*histogram[i];
       if( tempdist > dist)
       {
           dist = tempdist;
           thresh = i;
       }
    }
    thresh--;

    // 对已经得到的阈值T,如果前面已经翻转了,则阈值要用255-T
    if( isflipped )
    {
         thresh = 255-thresh;
    }


    //二值化
    Threshold(image,otpImage,thresh);

    return 0;

}

二值化:

//二值化
void Threshold(QImage &inputImage,QImage &outputImage,double bThres)
{
    BYTE bt;
    int width = inputImage.width();
    int height = inputImage.height();
    Init_Image(outputImage,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;
            }
            outputImage.setPixel(j,i,qRgb(bt, bt, bt));
        }
    }
}

在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值