zoukankan      html  css  js  c++  java
  • 自适应阈值二值化之最大类间方差法(大津法,OTSU)

    最大类间方差法是由日本学者大津(Nobuyuki Otsu)于1979年提出的,是一种自适应的阈值确定的方法,又叫大津法,简称OTSU。它是按图像的灰度特性,将图像分成背景和目标2部分。背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致2部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。对于图像I(x,y),前景(即目标)和背景的分割阈值记作Th,属于前景的像素点数占整幅图像的比例记为w1,其平均灰度G1;背景像素点数占整幅图像的比例为w2,其平均灰度为G2。图像的总平均灰度记为G_Ave,类间方差记为 g

    假设图像的背景较暗,并且图像的大小为MXN,图像中像素的灰度值小于阈值的像素个数记作N1,像素灰度大于阈值的像素个数记作N2,则有:

    采用遍历的方法得到使类间方差最大的阈值,即为所求。

    代码如下:

    (C文件)

     1 #include <stdio.h>
     2 #include <math.h>
     3 #include "myOtsu.h"
     4 typedef unsigned char uchar;
     5 int myOtsu(const IplImage *frame) //大津法求阈值   
     6 {  
     7     #define GrayScale 256   //frame灰度级   
     8     int width = frame->width;  
     9     int height = frame->height;  
    10     int pixelCount[GrayScale]={0};  
    11     float pixelPro[GrayScale]={0};  
    12     int i, j, pixelSum = width * height, threshold = 0; 
    13     float w0, w1, u0tmp, u1tmp, u0, u1, deltaTmp, deltaMax = 0; 
    14     uchar* data = (uchar*)frame->imageData;  
    15   
    16     //统计每个灰度级中像素的个数   
    17     for(i = 0; i < height; i++)  
    18     {  
    19         for(j = 0;j < width;j++)  
    20         {  
    21             pixelCount[(int)data[i * width + j]]++;  
    22         }  
    23     }  
    24   
    25     //计算每个灰度级的像素数目占整幅图像的比例   
    26     for(i = 0; i < GrayScale; i++)  
    27     {  
    28         pixelPro[i] = (float)pixelCount[i] / pixelSum;  
    29     }  
    30         
    31     for(i = 0; i < GrayScale; i++)//遍历所有从0到255灰度级的阈值分割条件,测试哪一个的类间方差最大  
    32     {  
    33         w0 = w1 = u0tmp = u1tmp = u0 = u1 = deltaTmp = 0;  
    34         for(j = 0; j < GrayScale; j++)  
    35         {  
    36             if(j <= i)   //背景部分   
    37             {  
    38                 w0 += pixelPro[j];  
    39                 u0tmp += j * pixelPro[j];  
    40             }  
    41             else   //前景部分   
    42             {  
    43                 w1 += pixelPro[j];  
    44                 u1tmp += j * pixelPro[j];  
    45             }  
    46         }  
    47         u0 = u0tmp / w0;  
    48         u1 = u1tmp / w1;  
    49         deltaTmp = (float)(w0 *w1* pow((u0 - u1), 2)) ;  
    50         if(deltaTmp > deltaMax)  
    51         {  
    52             deltaMax = deltaTmp;  
    53             threshold = i;  
    54         }  
    55     }  
    56     return threshold;  
    57 }

    (H文件)

    1 #ifndef MYOTSU_H_
    2 #define MYOTSU_H_
    3 typedef struct {
    4     int width;
    5     int height;
    6     unsigned char imageData;
    7 }IplImage;
    8 extern int myOtsu(const IplImage *frame);
    9 #endif /*MYOTSU_H_*/

    大家转载请注明出处!谢谢!

    在这里要感谢GISPALAB实验室的各位老师和学长学姐的帮助!谢谢~

  • 相关阅读:
    网络编程中 TCP 半开连接和TIME_WAIT 学习
    redis中的小秘密和持久化小细节
    排序
    Es官方文档整理-3.Doc Values和FieldData
    Es官方文档整理-2.分片内部原理
    Elasticsearch doc_value认识
    路边停靠 贴边停车不蹭轮胎的技巧
    mybatis 连接数据库
    putIfAbsent
    Hive与HBase区别 大墨垂杨
  • 原文地址:https://www.cnblogs.com/uestc-mm/p/5366908.html
Copyright © 2011-2022 走看看