主程序(核心部分)

代码




4  IplImage *  binaryImg  =  cvCreateImage(cvSize(w, h),IPL_DEPTH_8U,  1 );
5  cvThreshold(smoothImgGauss,binaryImg, 71 , 255 ,CV_THRESH_BINARY); 
6  cvNamedWindow( " cvThreshold " , CV_WINDOW_AUTOSIZE );
7  cvShowImage(  " cvThreshold " , binaryImg );
8  // cvReleaseImage(&binaryImg); 
9   
10 
11  IplImage *  adThresImg  =  cvCreateImage(cvSize(w, h),IPL_DEPTH_8U,  1 );
12  double  max_value = 255 ;
13  int  adpative_method = CV_ADAPTIVE_THRESH_GAUSSIAN_C; // CV_ADAPTIVE_THRESH_MEAN_C
14    int  threshold_type = CV_THRESH_BINARY;
15  int  block_size = 3 ; // 阈值的象素邻域大小
16    int  offset = 5 ; // 窗口尺寸
17     cvAdaptiveThreshold(smoothImgGauss,adThresImg,max_value,adpative_method,threshold_type,block_size,offset);
18  cvNamedWindow( " cvAdaptiveThreshold " , CV_WINDOW_AUTOSIZE );
19  cvShowImage(  " cvAdaptiveThreshold " , adThresImg );
20  cvReleaseImage( & adThresImg);
21 
22   
23  IplImage *  imgMaxEntropy  =  cvCreateImage(cvGetSize(imgGrey),IPL_DEPTH_8U, 1 );
24  MaxEntropy(smoothImgGauss,imgMaxEntropy);
25  cvNamedWindow( " MaxEntroyThreshold " , CV_WINDOW_AUTOSIZE );
26  cvShowImage(  " MaxEntroyThreshold " , imgMaxEntropy ); // 显示图像
27     cvReleaseImage( & imgMaxEntropy ); 
28 
29 
30  IplImage *  imgBasicGlobalThreshold  =  cvCreateImage(cvGetSize(imgGrey),IPL_DEPTH_8U, 1 );
31  cvCopyImage(srcImgGrey,imgBasicGlobalThreshold);
32  int  pg[ 256 ],i,thre; 
33  for  (i = 0 ;i < 256 ;i ++ ) pg[i] = 0 ;
34  for  (i = 0 ;i < imgBasicGlobalThreshold -> imageSize;i ++ )  //  直方图统计
35     pg[(BYTE)imgBasicGlobalThreshold -> imageData[i]] ++ ; 
36  thre  =  BasicGlobalThreshold(pg, 0 , 256 );  //  确定阈值
37     cout << " The Threshold of this Image in BasicGlobalThreshold is: " << thre << endl; // 输出显示阀值
38     cvThreshold(imgBasicGlobalThreshold,imgBasicGlobalThreshold,thre, 255 ,CV_THRESH_BINARY);  //  二值化 
39     cvNamedWindow( " BasicGlobalThreshold " , CV_WINDOW_AUTOSIZE );
40  cvShowImage(  " BasicGlobalThreshold " , imgBasicGlobalThreshold); // 显示图像
41     cvReleaseImage( & imgBasicGlobalThreshold);
42 
43 
44  IplImage *  imgOtsu  =  cvCreateImage(cvGetSize(imgGrey),IPL_DEPTH_8U, 1 );
45  cvCopyImage(srcImgGrey,imgOtsu);
46  int  thre2;
47  thre2  =  otsu2(imgOtsu);
48  cout << " The Threshold of this Image in Otsu is: " << thre2 << endl; // 输出显示阀值
49  cvThreshold(imgOtsu,imgOtsu,thre2, 255 ,CV_THRESH_BINARY);  //  二值化 
50  cvNamedWindow( " imgOtsu " , CV_WINDOW_AUTOSIZE );
51  cvShowImage(  " imgOtsu " , imgOtsu); // 显示图像 
52  cvReleaseImage( & imgOtsu);
53 
54 
55  IplImage *  imgTopDown  =  cvCreateImage( cvGetSize(imgGrey), IPL_DEPTH_8U,  1  );
56  cvCopyImage(srcImgGrey,imgTopDown);
57  CvScalar mean ,std_dev; // 平均值、 标准差
58  double  u_threshold,d_threshold;
59  cvAvgSdv(imgTopDown, & mean, & std_dev,NULL); 
60  u_threshold  =  mean.val[ 0 ]  + 2.5 *  std_dev.val[ 0 ]; // 上阀值
61  d_threshold  =  mean.val[ 0 ]  - 2.5 *  std_dev.val[ 0 ]; // 下阀值
62  // u_threshold = mean + 2.5 * std_dev;  // 错误
63  // d_threshold = mean - 2.5 * std_dev;
64  cout << " The TopThreshold of this Image in TopDown is: " << d_threshold << endl; // 输出显示阀值
65  cout << " The DownThreshold of this Image in TopDown is: " << u_threshold << endl;
66  cvThreshold(imgTopDown,imgTopDown,d_threshold,u_threshold,CV_THRESH_BINARY_INV); // 上下阀值
67  cvNamedWindow( " imgTopDown " , CV_WINDOW_AUTOSIZE );
68  cvShowImage(  " imgTopDown " , imgTopDown); // 显示图像 
69  cvReleaseImage( & imgTopDown);
70 
71 
72  IplImage *  imgIteration  =  cvCreateImage( cvGetSize(imgGrey), IPL_DEPTH_8U,  1  );
73  cvCopyImage(srcImgGrey,imgIteration);
74  int  thre3,nDiffRec;
75  thre3  = DetectThreshold(imgIteration,  100 , nDiffRec);
76  cout << " The Threshold of this Image in imgIteration is: " << thre3 << endl; // 输出显示阀值
77  cvThreshold(imgIteration,imgIteration,thre3, 255 ,CV_THRESH_BINARY_INV); // 上下阀值
78  cvNamedWindow( " imgIteration " , CV_WINDOW_AUTOSIZE );
79  cvShowImage(  " imgIteration " , imgIteration);
80  cvReleaseImage( & imgIteration);

模块程序

迭代法

代码




4  //  nMaxIter:最大迭代次数;nDiffRec:使用给定阀值确定的亮区与暗区平均灰度差异值
5  int  DetectThreshold(IplImage * img,  int  nMaxIter,  int &  iDiffRec)  // 阀值分割:迭代法
6  {
7  // 图像信息
8  int  height  =  img -> height;
9  int  width  =  img -> width;
10  int  step  =  img -> widthStep / sizeof (uchar);
11  uchar  * data  =  (uchar * )img -> imageData;
12 
13  iDiffRec  = 0 ;
14  int  F[ 256 ] = {  0  };  // 直方图数组
15  int  iTotalGray = 0 ; // 灰度值和
16  int  iTotalPixel  = 0 ; // 像素数和
17  byte  bt; // 某点的像素值
18 
19  uchar iThrehold,iNewThrehold; // 阀值、新阀值
20  uchar iMaxGrayValue = 0 ,iMinGrayValue = 255 ; // 原图像中的最大灰度值和最小灰度值
21  uchar iMeanGrayValue1,iMeanGrayValue2;
22 
23  // 获取(i,j)的值,存于直方图数组F
24  for ( int  i = 0 ;i < width;i ++ )
25  {
26  for ( int  j = 0 ;j < height;j ++ )
27  {
28  bt  =  data[i * step + j];
29  if (bt < iMinGrayValue)
30  iMinGrayValue  =  bt;
31  if (bt > iMaxGrayValue)
32  iMaxGrayValue  =  bt;
33  F[bt] ++ ;
34  }
35  }
36 
37  iThrehold  = 0 ; //
38  iNewThrehold  =  (iMinGrayValue + iMaxGrayValue) / 2 ; // 初始阀值
39  iDiffRec  =  iMaxGrayValue  -  iMinGrayValue;
40 
41  for ( int  a = 0 ;(abs(iThrehold - iNewThrehold) > 0.5 ) && a < nMaxIter;a ++ ) // 迭代中止条件
42  {
43  iThrehold  =  iNewThrehold;
44  // 小于当前阀值部分的平均灰度值
45  for ( int  i = iMinGrayValue;i < iThrehold;i ++ )
46  {
47  iTotalGray  +=  F[i] * i; // F[]存储图像信息
48  iTotalPixel  +=  F[i];
49  }
50  iMeanGrayValue1  =  (uchar)(iTotalGray / iTotalPixel);
51  // 大于当前阀值部分的平均灰度值
52  iTotalPixel  = 0 ;
53  iTotalGray  = 0 ;
54  for ( int  j = iThrehold + 1 ;j < iMaxGrayValue;j ++ )
55  {
56  iTotalGray  +=  F[j] * j; // F[]存储图像信息
57  iTotalPixel  +=  F[j]; 
58  }
59  iMeanGrayValue2  =  (uchar)(iTotalGray / iTotalPixel);
60 
61  iNewThrehold  =  (iMeanGrayValue2 + iMeanGrayValue1) / 2 ;  // 新阀值
62  iDiffRec  =  abs(iMeanGrayValue2  -  iMeanGrayValue1);
63  }
64 
65  // cout<<"The Threshold of this Image in imgIteration is:"<<iThrehold<<endl;
66  return  iThrehold;
67  }
68

Otsu代码一

代码






11 
17 
18  int  otsu (unsigned  char * image,  int  rows,  int  cols,  int  x0,  int  y0,  int  dx,  int  dy,  int vvv)
19  {
20 
21  unsigned  char * np;  //  图像指针
22  int  thresholdValue = 1 ;  //  阈值
23  int  ihist[ 256 ];  //  图像直方图,256个点
24 
25  int  i, j, k;  //  various counters
26  int  n, n1, n2, gmin, gmax;
27  double  m1, m2, sum, csum, fmax, sb;
28 
29  //  对直方图置零
30  memset(ihist,  0 ,  sizeof (ihist));
31 
32  gmin = 255 ; gmax = 0 ;
33  //  生成直方图
34  for  (i  =  y0  + 1 ; i  <  y0  +  dy  - 1 ; i ++ ) 
35  {
36  np  =  (unsigned  char * )image[i * cols + x0 + 1 ];
37  for  (j  =  x0  + 1 ; j  <  x0  +  dx  - 1 ; j ++ )
38  {
39  ihist[ * np] ++ ;
40  if ( * np  >  gmax) gmax =* np;
41  if ( * np  <  gmin) gmin =* np;
42  np ++ ; 
43  }
44  }
45 
46  //  set up everything
47  sum  =  csum  = 0.0 ;
48  n  = 0 ;
49 
50  for  (k  = 0 ; k  <= 255 ; k ++ ) 
51  {
52  sum  +=  ( double ) k  *  ( double ) ihist[k]; 
53  n  +=  ihist[k]; 
54  }
55 
56  if  ( ! n) 
57  {
58  //  if n has no value, there is problems...
59  fprintf (stderr,  " NOT NORMAL thresholdValue = 160\n " );
60  return  ( 160 );
61  }
62 
63  //  do the otsu global thresholding method
64  fmax  = - 1.0 ;
65  n1  = 0 ;
66  for  (k  = 0 ; k  < 255 ; k ++ )
67  {
68  n1  +=  ihist[k];
69  if  ( ! n1) 
70  { 
71  continue ; 
72  }
73  n2  =  n  -  n1;
74  if  (n2  == 0 )
75  { 
76  break ; 
77  }
78  csum  +=  ( double ) k  * ihist[k];
79  m1  =  csum  /  n1;
80  m2  =  (sum  -  csum)  /  n2;
81  sb  =  ( double ) n1  * ( double ) n2  * (m1  -  m2)  *  (m1  -  m2);
82 
83  if  (sb  >  fmax) 
84  {
85  fmax  =  sb;
86  thresholdValue  =  k;
87  }
88  }
89 
90  //  at this point we have our thresholding value
91 
92  //  debug code to display thresholding values
93  if  ( vvv  & 1  )
94  fprintf(stderr, " # OTSU: thresholdValue = %d gmin=%d gmax=%d\n " ,
95  thresholdValue, gmin, gmax);
96 
97  return (thresholdValue);
98  }

Otsu代码二

代码
1
2
3
4 int otsu2 (IplImage *image)
5 {
6 int w = image->width;
7 int h = image->height;
9 unsigned char*np; // 图像指针
10 unsigned char pixel;
11 int thresholdValue=1; // 阈值
12 int ihist[256]; // 图像直方图,256个点
13 
14 int i, j, k; // various counters
15 int n, n1, n2, gmin, gmax;
16 double m1, m2, sum, csum, fmax, sb;
17 
18 // 对直方图置零...
19 memset(ihist, 0, sizeof(ihist));
20 
21 gmin=255; gmax=0;
22 // 生成直方图
23 for (i =0; i < h; i++) 
24 {
25 np = (unsigned char*)(image->imageData + image->widthStep*i);
26 for (j =0; j < w; j++) 
27 {
28 pixel = np[j];
29 ihist[ pixel]++;
30 if(pixel > gmax) gmax= pixel;
31 if(pixel < gmin) gmin= pixel;
32 }
33 }
34 
35 // set up everything
36 sum = csum =0.0;
37 n =0;
38 
39 for (k =0; k <=255; k++) 
40 {
41 sum += k * ihist[k];
42 n += ihist[k];
43 }
44 
45 if (!n) 
46 {
47 // if n has no value, there is problems...
48 //fprintf (stderr, "NOT NORMAL thresholdValue = 160\n");
49 thresholdValue =160;
50 goto L;
51 }
52 
53 // do the otsu global thresholding method
54 fmax =-1.0;
55 n1 =0;
56 for (k =0; k <255; k++) 
57 {
58 n1 += ihist[k];
59 if (!n1) { continue; }
60 n2 = n - n1;
61 if (n2 ==0) { break; }
62 csum += k *ihist[k];
63 m1 = csum / n1;
64 m2 = (sum - csum) / n2;
65 sb = n1 * n2 *(m1 - m2) * (m1 - m2);
66
67 if (sb > fmax)
68 {
69 fmax = sb;
70 thresholdValue = k;
71 }
72 }
73 
74 L:
75 for (i =0; i < h; i++) 
76 {
77 np = (unsigned char*)(image->imageData + image->widthStep*i);
78 for (j =0; j < w; j++) 
79 {
80 if(np[j] >= thresholdValue)
81 np[j] =255;
82 else np[j] =0;
83 }
84 }
85 
86 //cout<<"The Threshold of this Image in Otsu is:"<<thresholdValue<<endl;
87 return(thresholdValue);
88 }

最大熵阀值

代码


8  //  计算当前位置的能量熵
9  double  caculateCurrentEntropy(CvHistogram  *  Histogram1, int  cur_threshold,entropy_state state)
10  {
11  int  start,end;
12  int  total  = 0 ;
13  double  cur_entropy  = 0.0 ;
14  if (state  ==  back) 
15  {
16  start  = 0 ;
17  end  =  cur_threshold; 
18  }
19  else  
20  {
21  start  =  cur_threshold;
22  end  = 256 ; 
23  } 
24  for ( int  i = start;i < end;i ++ ) 
25  {
26  total  +=  ( int )cvQueryHistValue_1D(Histogram1,i); // 查询直方块的值 P304
27  }
28  for ( int  j = start;j < end;j ++ )
29  {
30  if (( int )cvQueryHistValue_1D(Histogram1,j) == 0 )
31  continue ;
32  double  percentage  =  cvQueryHistValue_1D(Histogram1,j) / total;
33 
34  cur_entropy  += - percentage * logf(percentage);
35   
37  }
38  return  cur_entropy;
39  //  return (1-cur_entropy);
40  }
41 
42  // 寻找最大熵阈值并分割
43  void  MaxEntropy(IplImage  * src,IplImage  * dst)
44  {
45  assert(src  !=  NULL);
46  assert(src -> depth  == 8 &&  dst -> depth  == 8 );
47  assert(src -> nChannels  == 1 );
48  CvHistogram  *  hist  =  cvCreateHist( 1 , & HistogramBins,CV_HIST_ARRAY,HistogramRange); // 创建一个指定尺寸的直方图
49  // 参数含义:直方图包含的维数、直方图维数尺寸的数组、直方图的表示格式、方块范围数组、归一化标志
50  cvCalcHist( & src,hist); // 计算直方图
51  double  maxentropy  = - 1.0 ;
52  int  max_index  = - 1 ;
53  //  循环测试每个分割点,寻找到最大的阈值分割点
54  for ( int  i = 0 ;i < HistogramBins;i ++ ) 
55  {
56  double  cur_entropy  =  caculateCurrentEntropy(hist,i, object ) + caculateCurrentEntropy(hist,i,back);
57  if (cur_entropy > maxentropy)
58  {
59  maxentropy  =  cur_entropy;
60  max_index  =  i;
61  }
62  }
63  cout << " The Threshold of this Image in MaxEntropy is: " << max_index << endl;
64  cvThreshold(src, dst, ( double )max_index, 255 , CV_THRESH_BINARY);
65  cvReleaseHist( & hist);
66  }

基本全局阀值法

代码


4  int  BasicGlobalThreshold( int * pg, int  start, int  end)
5  {  //  基本全局阈值法
6  int  i,t,t1,t2,k1,k2;
7  double  u,u1,u2; 
8  t = 0 ; 
9  u = 0 ;
10  for  (i = start;i < end;i ++ ) 
11  {
12  t += pg[i]; 
13  u += i * pg[i];
14  }
15  k2 = ( int ) (u / t);  //  计算此范围灰度的平均值 
16  do  
17  {
18  k1 = k2;
19  t1 = 0 ; 
20  u1 = 0 ;
21  for  (i = start;i <= k1;i ++ ) 
22  {  //  计算低灰度组的累加和
23  t1 += pg[i]; 
24  u1 += i * pg[i];
25  }
26  t2 = t - t1;
27  u2 = u - u1;
28  if  (t1) 
29  u1 = u1 / t1;  //  计算低灰度组的平均值
30  else  
31  u1 = 0 ;
32  if  (t2) 
33  u2 = u2 / t2;  //  计算高灰度组的平均值
34  else  
35  u2 = 0 ;
36  k2 = ( int ) ((u1 + u2) / 2 );  //  得到新的阈值估计值
37  }
38  while (k1 != k2);  //  数据未稳定,继续
39  // cout<<"The Threshold of this Image in BasicGlobalThreshold is:"<<k1<<endl;
40  return (k1);  //  返回阈值
41  }

常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)相关推荐

  1. 【图像算法】七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)...

    图像算法:图像阈值分割 SkySeraph Dec 21st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified Da ...

  2. 七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)...

    转自:http://blog.csdn.net/xw20084898/article/details/17564957 一.工具:VC+OpenCV 二.语言:C++ 三.原理 otsu法(最大类间方 ...

  3. 【转】七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)...

    http://blog.csdn.net/xw20084898/article/details/17564957 一.工具:VC+OpenCV 二.语言:C++ 三.原理 otsu法(最大类间方差法, ...

  4. 【千律】OpenCV基础:图像阈值分割 -- 自适应阈值分割 -- 代码实现

    环境:Python3.8 和 OpenCV 内容:自适应阈值分割代码实现 import cv2 as cv import numpy as np import matplotlib.pyplot as ...

  5. 图像处理合集:图像基础操作(图像翻转、图像锐化、图像平滑等)、图像阈值分割(边缘检测、迭代法、OSTU、区域增长法等)、图像特征提取(图像分割、灰度共生矩阵、PCA图像压缩)

    文章目录 说明 一.图像锐化或增强相关 1. 图像点处理 1.1 图像翻转 1.2 幂运算和对数运算 2. 直方图处理 3. 图像平滑 4. 图像锐化 5. 图像增强 二.图像阈值分割 1. 边缘检测 ...

  6. opencv中几种阈值分割

    七种常见阈值分割代码(Otsu.最大熵.迭代法.自适应阀值.手动.迭代法.基本全局阈值法) 一.工具:VC+OpenCV 二.语言:C++ 三.原理 otsu法(最大类间方差法,有时也称之为大津算法) ...

  7. Halcon算子学习:图像阈值分割-threshold、binary_threshold、dyn_threshold算子

    Halcon算子学习:图像阈值分割算子 前言 1.threshold-全局固定阈值分割 2.Binary Threshold-自动全局阈值分割 3.dyn_threshold-局部动态阈值分割 小结: ...

  8. 图像二值化方法及适用场景分析(OTSU Trangle 自适应阈值分割)

    图像二值化 应用场景 二值图像定义 阈值获取的方法 手动阈值法 自动阈值法 灰度均值法 基于直方图均值法 OTSU Triangle 自适应均值阈值分割方法 总结 参考文献 应用场景 二值图像处理与分 ...

  9. OpenCV —— 阈值分割(直方图技术法,熵算法,Otsu,自适应阈值算法)

    阈值分割 1. 全局阈值分割 直方图技术法 熵算法 Otsu算法 2. 局部阈值分割 自适应阈值 阈值的分割的核心就是如何选取阈值,选取正确的阈值时分割成功的关键.可以使用手动设置阈值,也可以采用直方 ...

最新文章

  1. 学好Linux必备知识
  2. query什么意思php,关于 QueryPHP
  3. IntelliJ IDEA for Mac在MacOS模式下的动态代码模板快捷键(Live Templates Shortcut)
  4. vue this.$set 给data对象新增属性,并触发视图更新
  5. 自动化运维环境搭建过程
  6. img标签中alt和title属性的正确使用
  7. 在谈判中别无选择的时候,怎么办?
  8. idea 设置代码的颜色
  9. android中自定义 toast,Android自定义Toast
  10. 蓝桥杯 基础练习 特殊回文数 JAVA
  11. HashMap常见面试题
  12. 错误1406.无法将数值写入键/Software/Classess/.htm/OpenWithList/devenv.exer的解决方案
  13. 思科2960交换机 - 配置命令大全
  14. Imperfect C++读书笔记(二):前置条件、后置条件和不变式
  15. rockchip rk3566 android11 网口log报错: DMA engine initialization failed
  16. VOT(Visual Object Tracking)评价指标综述
  17. js制作12进制的时钟特效
  18. 华硕h110m主板怎么样_华硕台式机主板怎么样 华硕台式机主板多少钱【详细介绍】...
  19. win10在编写python程序时,问题出现权限不足的问题
  20. LeetCode 开心字符串

热门文章

  1. YOLOv5~目标检测模型精确度
  2. Proteus 8 Professional跑Keil uVision4的文件
  3. 手把手教你设置公众号菜单栏
  4. OverTheWire的bandit游戏1
  5. 稀疏表征:稀疏字典构建
  6. 独角兽公司ucloud照片Linux存储/文件存储工程师
  7. 图床程序 php,开源免费PHP图床程序–Qchan
  8. matlab亥姆霍兹线圈叠加原理,亥姆霍兹线圈仿真剖析.docx
  9. LitJson在Unity中的使用
  10. 成功解决Win10连接上wifi但是却显示“无Internet,安全”