精华内容
下载资源
问答
  • otsu图像分割算法与粒子群优化算法结合,加快最佳阈值的寻找
  • OTSU自适应阈值求法与粒子群算法的合作,将OTSU算法作为粒子群算法的适应值函数,来计算每个粒子的适应度与最优阈值相比较,经过3000次迭代最后取得优化后的阈值 原图: 经过联合算法优化的双阈值为90 ,140 将...

      

     OTSU自适应阈值求法与粒子群算法的合作,将OTSU算法作为粒子群算法的适应值函数,来计算每个粒子的适应度与最优阈值相比较,经过3000次迭代最后取得优化后的阈值

    原图:

    经过联合算法优化的双阈值为90 ,140

    将背景像素置0:

    效果图:

    利用所取得的阈值就可以将图像背景和目标区分开来,利用所得阈值二值化后

    效果图:

     

    通过效果图可知将人这个目标从背景中分割出来了

    源代码:

    #include "stdafx.h"
    #include "cv.h"
    #include "highgui.h"
    #include "cxcore.h"
    #include "time.h"
    using namespace std;
    
    #define rnd( low,uper) ((int)(((double)rand()/(double)RAND_MAX)*((double)(uper)-(double)(low))+(double)(low)+0.5))
    /*************************************************************8888
    粒子群算法变量的说明
    ******************************************************************************/
    const int number = 20;
    int antThreshold[number][2];//以阈值作为粒子
    int vect[number][2];//更新的速度
    float pbest[number] = {0.0};;//每个粒子历史最优解
    float gbest = 0.0;//全局历史最优解
    int pbestThreshold[number][2];//每个粒子的最优历史阈值
    int gbestThreshold[2];//全局粒子的最优阈值
    
    float w = 0.9;//惯性因子
    float c1 = 2.0;//加速因子1
    float c2 = 2.0;//加速因子2
    
    //histogram   
    float histogram[256]={0};  
    /*********************************************************************8888
    函数名:GetAvgValue
    参数类型:IplImage* src
    实现功能:获得灰度图像的总平均灰度值
    *****************************************************************************/
    float GetAvgValue(IplImage* src)  
    {  
        int height=src->height;  
        int width=src->width;      
      
    
        for(int i=0;i<height;i++) 
    	{  
            unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;  
            for(int j=0;j<width;j++) 
    		{  
                histogram[*p++]++;  
            }  
        }  
        //normalize histogram   
        int size=height*width;  
        for(int i=0;i<256;i++) {  
            histogram[i]=histogram[i]/size;  
        }  
      
        //average pixel value   
        float avgValue=0;  
        for(int i=0;i<256;i++) {  
            avgValue+=i*histogram[i];  
        }  
    	return avgValue;
    }
    /*****************************************************************************
    函数名:ThresholdOTSU
    参数类型:int threshold1 , int threshold2 , float avgValue
    功能:求得最大类间方差
    **********************************************************************************/
    float  ThresholdOTSU(int threshold1 , int threshold2 , float avgValue)
    {
      
        int threshold;    
        float maxVariance=0;  
        float w=0,u=0;  
        for(int i=threshold1;i< threshold2 ;i++)
    	{  
            w+=histogram[i];  
            u+=i*histogram[i];  
    	}
      
            float t=avgValue*w-u;  
            float variance=t*t/(w*(1-w));  
           /* if(variance>maxVariance)
    		{  
                maxVariance=variance;  
                threshold=i;  
            }  
             */
        return variance;  
    }  
    /*****************************************************************
    函数名:Init
    参数类型:void
    功能:初始化粒子群算法的粒子与速度
    ************************************************************************/
    void Init()
    {
    	for(int index=0;index<number;index++)
    	{
    		antThreshold[index][0] = rnd(10 , 50);
    		antThreshold[index][1] = antThreshold[index][0] + 50;
    		if(antThreshold[index][1]>255)
    			antThreshold[index][1] = 255;
    		vect[index][0] = rnd(3 ,5);
    		vect[index][1] = rnd(3 ,5);
    	}
    		
    }
    /******************************************************************
    函数名:Pso
    参数类型:void
    功能:粒子群算法的实现
    ***************************************************************************/
    
    void Pso(float value)
    {
      for(int index=0;index<number;index++)
      {
    	  float variance;
    	  variance = ThresholdOTSU(antThreshold[index][0] , antThreshold[index][1] , value);
    	  if(variance>pbest[index])
    	  {
    		  pbest[index] = variance;
    		  pbestThreshold[index][0] = antThreshold[index][0];
              pbestThreshold[index][1] = antThreshold[index][1];
    	  }
    	  if(variance>gbest)
    	  {
    		  gbest = variance;
    		  gbestThreshold[0] = antThreshold[index][0];
    		  gbestThreshold[1] = antThreshold[index][1];
    	  }
      }
    }
    /***************************************************************************************88
    函数名:updateData
    参数类型:void
    功能:更新粒子数据与速度
    **************************************************************************************************/
    void updateData()
    {
    	for(int index=0;index<number;index++)
    	{
    		for(int i=0;i<2;i++)
    		{
    			vect[index][i] = w*vect[index][i] + c1*((double)(rand())/(double)RAND_MAX)*(pbestThreshold[index][i]-antThreshold[index][i])+
    				c2*c1*((double)(rand())/(double)RAND_MAX)*(gbestThreshold[i]-antThreshold[index][i]);
    			if(vect[index][i]>5)
    				vect[index][i] = 5;
    			if(vect[index][i]<3)
    				vect[index][i] = 3;
    			antThreshold[index][i] = vect[index][i] + antThreshold[index][i];
    		}
    		if(antThreshold[index][0]>antThreshold[index][1])
    			antThreshold[index][1] = antThreshold[index][0] + 50;
    		if(antThreshold[index][1]>255)
    			antThreshold[index][1] = 255;
    		if(antThreshold[index][0]<0)
    			antThreshold[index][0] = 0;
    	}
    
    }
    /**************************************************************8
    函数名:Threshold
    参数类型:IplImage *src , int lower , int higher
    功能:利用算法得到的双阈值对图像进行阈值分割
    ***********************************************************************/
    void Threshold(IplImage *src , int lower , int higher)
    {
    	assert(src->nChannels==1);
    	for(int h=0;h<src->height;h++)
    		for(int w=0;w<src->width;w++)
    		{
    			if(*(src->imageData+h*src->widthStep+w)<higher&&*(src->imageData+h*src->widthStep+w)>lower)
    				//*(src->imageData+h*src->widthStep+w) = 255;
    				;
    			else
    				*(src->imageData+h*src->widthStep+w) = 0;
    		}
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    	srand((unsigned)time(NULL));
    	IplImage *img =0;
    	IplImage *ycrcb = 0;
    	IplImage *cb = 0;
        cvNamedWindow("cb" , 1);
    	img = cvLoadImage("1.jpg" , 1);
    	ycrcb = cvCreateImage(cvGetSize(img) , 8 ,3);
    	cb = cvCreateImage(cvGetSize(img) , 8 , 1);
    
    	cvCvtColor(img , ycrcb , CV_BGR2YCrCb);
    	cvSplit(ycrcb , 0 ,0,cb , 0);
    
    	cvSmooth(cb , cb , CV_MEDIAN , 3 , 0,0,0);
    	float avgValue = 0.0;
    	avgValue = GetAvgValue(cb);
    	Init();
    	for(int i=0;i<3000;i++)
    	{
           Pso(avgValue);
    	   updateData();
    	}
    
    	//cvThreshold(cb , cb , gbestThreshold[0] , gbestThreshold[1] , CV_THRESH_BINARY);
    	Threshold(cb , gbestThreshold[0] , gbestThreshold[1]);
    	printf("%d , %d\n" ,  gbestThreshold[0] , gbestThreshold[1]);
    	cvShowImage("cb" , cb);
    	cvSaveImage("cb1.jpg" ,cb);
    	cvWaitKey(0);
    
    	return 0;
    }
    
    


     

     

    展开全文
  • 针对三维OTSU分割算法运算量大、计算时间长的问题,提出了一种基于自适应粒子群优化的三维OTSU图像分割算法。首先采用最佳熵的方法初步提取图像的目标区域,根据该目标区域特征自适应地调整三维OTSU算法的背景搜索...
  • Otsu算法

    千次阅读 2018-11-06 15:42:28
    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kksc1099054857/article/details/78321776 1....nbsp; &nbsp; &...一维Otsu算法有计算简...
    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kksc1099054857/article/details/78321776

    1.简介:

           一维Otsu算法有计算简洁、稳定、自适应强等优点,被广泛用于图像分割中。但一维Otsu算法没有考虑图像像素点之间的关系,当图像中有噪声时,会导致分割的效果不理想。因此,刘健庄等人在1993年提出了二维的Otsu算法,提升了算法的抗噪声能力。

    2.算法思想:

           同时考虑像素的灰度值分布和它们邻域像素的平均灰度值分布,因此形成的阈值是一个二维矢量,最佳的阈值在一个二维的测度准则下确定最大值时得到。

    3.算法过程:

    (1)设图像I(x,y),的灰度级为L级,那么图像的邻域平均灰度也分为L级。
    (2)设f(x,y)为像素点(x,y)的灰度值,g(x,y)为像素点(x,y)为中心的K*K的像
            素点集合的灰度平均值。令f(x,y)=i,g(x,y)=j,然后就形成了一个二元组(i,j)。
    (3)设二元组(i,j)出现的次数为fij,然后求出二元组对应的概率密度Pij,
            Pij=fij/N, i,j=1,2,…,L,其中N为图像像素点总数。
    (4)任意选取一个阈值向量(s,t)选取的阈值向量将图像的二维直方图划分成4个
            区域,B、C区域代表图像的前景和背景,A、D区域代表噪声点。

    (5)设C、B两个区域对应的概率分别为w1,w2,对应的均值矢量为u1,u2。整个图
            片所对应的均值矢量为uT。


    4.代码实现(opencv3):

        

    
       
    1. #include "opencv.hpp"
    2. #include "imgproc.hpp"
    3. #include "highgui.hpp"
    4. #include "iostream"
    5. #include "core.hpp"
    6. using namespace cv;
    7. using namespace std;
    8. int Otsu2D(Mat srcimage); //二维Otsu算法
    9. int main()
    10. {
    11. Mat srcimage, grayimage, dstimage;
    12. srcimage = imread( "lena.jpg");
    13. namedWindow( "原图", 0);
    14. imshow( "原图", srcimage); //显示原图
    15. cvtColor(srcimage, grayimage, COLOR_RGB2GRAY); //得到灰度图
    16. double time0 = static_cast< double>(getTickCount()); //记录程序开始时间
    17. int thresholdValue = Otsu2D(grayimage); //调用二维Otsu函数
    18. time0 = (( double)getTickCount() - time0) / getTickFrequency();
    19. cout << "算法运行时间为:" << time0 << endl;
    20. cout << "Otsu阈值为:" << thresholdValue << endl;
    21. threshold(grayimage, dstimage, thresholdValue, 255, THRESH_BINARY); //将得到的阈值传入函数,得到分割效果图
    22. namedWindow( "Otsu算法结果", 0);
    23. imshow( "Otsu算法结果", dstimage);
    24. waitKey();
    25. return 0;
    26. }
    
       
    1. <code class="language-cpp">int Otsu2D(Mat srcimage)  
    2. {  
    3.     double Histogram[256][256];        //建立二维灰度直方图  
    4.     double TrMax = 0.0;                //用于存储矩阵的迹(矩阵对角线之和)  
    5.     int height = srcimage.rows;        //矩阵的行数  
    6.     int width = srcimage.cols;         //矩阵的列数  
    7.     int N = height*width;              //像素的总数  
    8.     int T;                             //最终阈值  
    9.     uchar *data = srcimage.data;  
    10.     for (int i = 0; i < 256; i++)  
    11.     {  
    12.         for (int j = 0; j < 256; j++)  
    13.         {  
    14.             Histogram[i][j] = 0;      //初始化变量  
    15.         }  
    16.     }  
    17.     for (int i = 0; i < height; i++)  
    18.     {  
    19.         for (int j = 0; j < width; j++)  
    20.         {  
    21.             int Data1 = data[i*srcimage.step + j];         //获取当前灰度值  
    22.             int Data2 = 0;                           //用于存放灰度的平均值  
    23.             for (int m = i - 1; m <= i + 1; m++)  
    24.             {  
    25.                 for (int n = j - 1; n <= j + 1; n++)  
    26.                 {  
    27.                     if ((m >= 0) && (m < height) && (n >= 0) && (n < width))  
    28.                         Data2 += data[m*srcimage.step + n];//邻域灰度值总和  
    29.                 }  
    30.             }  
    31.             Data2 = Data2 / 9;  
    32.             Histogram[Data1][Data2]++;                  //记录(i,j)的数量  
    33.         }  
    34.     }  
    35.     for (int i = 0; i < 256; i++)  
    36.         for (int j = 0; j < 256; j++)  
    37.             Histogram[i][j] /= N;     //归一化的每一个二元组的概率分布  
    38.   
    39.     double Fgi = 0.0;    //前景区域均值向量i分量  
    40.     double Fgj = 0.0;    //前景区域均值向量j分量  
    41.     double Bgi = 0.0;    //背景区域均值向量i分量  
    42.     double Bgj = 0.0;    //背景区域均值向量j分量  
    43.     double Pai = 0.0;    //全局均值向量i分量 panorama(全景)  
    44.     double Paj = 0.0;    //全局均值向量j分量  
    45.     double w0 = 0.0;     //前景区域联合概率密度  
    46.     double w1 = 0.0;     //背景区域联合概率密度  
    47.     double num1 = 0.0;   //遍历过程中前景区i分量的值  
    48.     double num2 = 0.0;   //遍历过程中前景区j分量的值  
    49.     double num3 = 0.0;   //遍历过程中背景区i分量的值  
    50.     double num4 = 0.0;   //遍历过程中背景区j分量的值  
    51.     int Threshold_s = 0; //阈值s  
    52.     int Threshold_t = 0; //阈值t  
    53.     double temp = 0.0;   //存储矩阵迹的最大值  
    54.     for(int i=0;i<256;i++)  
    55.     {  
    56.         for (int j = 0; j < 256; j++)  
    57.         {  
    58.             Pai += i*Histogram[i][j];   //全局均值向量i分量计算  
    59.             Paj += j*Histogram[i][j];   //全局均值向量j分量计算  
    60.         }  
    61.     }  
    62.     for (int i = 0; i < 256; i++)  
    63.     {  
    64.         for (int j = 0; j < 256; j++)  
    65.         {  
    66.             w0 += Histogram[i][j];        //前景的概率  
    67.             num1 += i*Histogram[i][j];    //遍历过程中前景区i分量的值  
    68.             num2 += j*Histogram[i][j];    //遍历过程中前景区j分量的值  
    69.   
    70.             w1 = 1 - w0;                  //背景的概率  
    71.             num3 = Pai - num1;            //遍历过程中背景区i分量的值  
    72.             num4 = Paj - num2;            //遍历过程中背景区j分量的值  
    73.   
    74.             Fgi = num1 / w0;                
    75.             Fgj = num2 / w1;  
    76.             Bgi = num3 / w0;  
    77.             Bgj = num4 / w1;  
    78.             TrMax = ((w0*Pai - num1)*(w0*Pai - num1) + (w0*Paj - num2)*(w0*Paj - num2)) / (w0*w1);  
    79.             if (TrMax > temp)  
    80.             {  
    81.                 temp = TrMax;  
    82.                 Threshold_s = i;  
    83.                 Threshold_t = j;  
    84.             }  
    85.         }  
    86.     }  
    87.     cout << Threshold_s << " " << Threshold_t << endl;  
    88.     T = Threshold_s;  
    89.     return T;  
    90. }  
    91. </code>  
    
        
    1. int Otsu2D(Mat srcimage)
    2. {
    3. double Histogram[ 256][ 256]; //建立二维灰度直方图
    4. double TrMax = 0.0; //用于存储矩阵的迹(矩阵对角线之和)
    5. int height = srcimage.rows; //矩阵的行数
    6. int width = srcimage.cols; //矩阵的列数
    7. int N = height*width; //像素的总数
    8. int T; //最终阈值
    9. uchar *data = srcimage.data;
    10. for ( int i = 0; i < 256; i++)
    11. {
    12. for ( int j = 0; j < 256; j++)
    13. {
    14. Histogram[i][j] = 0; //初始化变量
    15. }
    16. }
    17. for ( int i = 0; i < height; i++)
    18. {
    19. for ( int j = 0; j < width; j++)
    20. {
    21. int Data1 = data[i*srcimage.step + j]; //获取当前灰度值
    22. int Data2 = 0; //用于存放灰度的平均值
    23. for ( int m = i - 1; m <= i + 1; m++)
    24. {
    25. for ( int n = j - 1; n <= j + 1; n++)
    26. {
    27. if ((m >= 0) && (m < height) && (n >= 0) && (n < width))
    28. Data2 += data[m*srcimage.step + n]; //邻域灰度值总和
    29. }
    30. }
    31. Data2 = Data2 / 9;
    32. Histogram[Data1][Data2]++; //记录(i,j)的数量
    33. }
    34. }
    35. for ( int i = 0; i < 256; i++)
    36. for ( int j = 0; j < 256; j++)
    37. Histogram[i][j] /= N; //归一化的每一个二元组的概率分布
    38. double Fgi = 0.0; //前景区域均值向量i分量
    39. double Fgj = 0.0; //前景区域均值向量j分量
    40. double Bgi = 0.0; //背景区域均值向量i分量
    41. double Bgj = 0.0; //背景区域均值向量j分量
    42. double Pai = 0.0; //全局均值向量i分量 panorama(全景)
    43. double Paj = 0.0; //全局均值向量j分量
    44. double w0 = 0.0; //前景区域联合概率密度
    45. double w1 = 0.0; //背景区域联合概率密度
    46. double num1 = 0.0; //遍历过程中前景区i分量的值
    47. double num2 = 0.0; //遍历过程中前景区j分量的值
    48. double num3 = 0.0; //遍历过程中背景区i分量的值
    49. double num4 = 0.0; //遍历过程中背景区j分量的值
    50. int Threshold_s = 0; //阈值s
    51. int Threshold_t = 0; //阈值t
    52. double temp = 0.0; //存储矩阵迹的最大值
    53. for( int i= 0;i< 256;i++)
    54. {
    55. for ( int j = 0; j < 256; j++)
    56. {
    57. Pai += i*Histogram[i][j]; //全局均值向量i分量计算
    58. Paj += j*Histogram[i][j]; //全局均值向量j分量计算
    59. }
    60. }
    61. for ( int i = 0; i < 256; i++)
    62. {
    63. for ( int j = 0; j < 256; j++)
    64. {
    65. w0 += Histogram[i][j]; //前景的概率
    66. num1 += i*Histogram[i][j]; //遍历过程中前景区i分量的值
    67. num2 += j*Histogram[i][j]; //遍历过程中前景区j分量的值
    68. w1 = 1 - w0; //背景的概率
    69. num3 = Pai - num1; //遍历过程中背景区i分量的值
    70. num4 = Paj - num2; //遍历过程中背景区j分量的值
    71. Fgi = num1 / w0;
    72. Fgj = num2 / w1;
    73. Bgi = num3 / w0;
    74. Bgj = num4 / w1;
    75. TrMax = ((w0*Pai - num1)*(w0*Pai - num1) + (w0*Paj - num2)*(w0*Paj - num2)) / (w0*w1);
    76. if (TrMax > temp)
    77. {
    78. temp = TrMax;
    79. Threshold_s = i;
    80. Threshold_t = j;
    81. }
    82. }
    83. }
    84. cout << Threshold_s << " " << Threshold_t << endl;
    85. T = Threshold_s;
    86. return T;
    87. }

    5.运行结果(得到2个阈值,取其中一个即可):


    6.修改后的代码

    
       
    1. int Otsu2D(Mat srcimage)
    2. {
    3. double Histogram[ 256][ 256]; //建立二维灰度直方图
    4. double TrMax = 0.0; //用于存储矩阵的迹(矩阵对角线之和)
    5. int height = srcimage.rows; //矩阵的行数
    6. int width = srcimage.cols; //矩阵的列数
    7. int N = height*width; //像素的总数
    8. int T; //最终阈值
    9. uchar *data = srcimage.data;
    10. for ( int i = 0; i < 256; i++)
    11. {
    12. for ( int j = 0; j < 256; j++)
    13. {
    14. Histogram[i][j] = 0; //初始化变量
    15. }
    16. }
    17. for ( int i = 0; i < height; i++)
    18. {
    19. for ( int j = 0; j < width; j++)
    20. {
    21. int Data1 = data[i*srcimage.step + j]; //获取当前灰度值
    22. int Data2 = 0; //用于存放灰度的平均值
    23. for ( int m = i - 1; m <= i + 1; m++)
    24. {
    25. for ( int n = j - 1; n <= j + 1; n++)
    26. {
    27. if ((m >= 0) && (m < height) && (n >= 0) && (n < width))
    28. Data2 += data[m*srcimage.step + n]; //邻域灰度值总和
    29. }
    30. }
    31. Data2 = Data2 / 9;
    32. Histogram[Data1][Data2]++; //记录(i,j)的数量
    33. }
    34. }
    35. for ( int i = 0; i < 256; i++)
    36. {
    37. for ( int j = 0; j < 256; j++)
    38. {
    39. Histogram[i][j] /= N; //归一化的每一个二元组的概率分布
    40. }
    41. }
    42. double S[ 256]; //统计前i行概率的数组
    43. double N1[ 256]; //统计遍历过程中前景区i分量的值
    44. double N2[ 256]; //统计遍历过程中前景区j分量的值
    45. S[ 0] = 0;
    46. N1[ 0] = 0;
    47. N2[ 0] = 0;
    48. for ( int i = 1; i < 256; i++)
    49. {
    50. double x = 0,n1= 0,n2= 0;
    51. for ( int j = 0; j < 256; j++)
    52. {
    53. x += Histogram[i - 1][j];
    54. n1 += ((i -1)*Histogram[i - 1][j]); //遍历过程中前景区i分量的值
    55. n2 += (j*Histogram[i - 1][j]); //遍历过程中前景区j分量的值
    56. }
    57. S[i] = x + S[i - 1];
    58. N1[i] = n1 + N1[i - 1];
    59. N2[i] = n2 + N2[i - 1];
    60. }
    61. double Pai = 0.0; //全局均值向量i分量 panorama(全景)
    62. double Paj = 0.0; //全局均值向量j分量
    63. int Threshold_s = 0; //阈值s
    64. int Threshold_t = 0; //阈值t
    65. int M = 0; //中间变量
    66. double temp = 0.0; //存储矩阵迹的最大值
    67. double num3 = 0.0; //遍历过程中背景区i分量的值
    68. double num4 = 0.0; //遍历过程中背景区j分量的值
    69. double Fgi = 0.0; //前景区域均值向量i分量
    70. double Fgj = 0.0; //前景区域均值向量j分量
    71. double Bgi = 0.0; //背景区域均值向量i分量
    72. double Bgj = 0.0; //背景区域均值向量j分量
    73. for( int i= 0;i< 256;i++)
    74. {
    75. for ( int j = 0; j < 256; j++)
    76. {
    77. Pai += i*Histogram[i][j]; //全局均值向量i分量计算
    78. Paj += j*Histogram[i][j]; //全局均值向量j分量计算
    79. }
    80. }
    81. for ( int i = 0; i < 256; i++)
    82. {
    83. double w0 = 0.0; //前景区域联合概率密度
    84. double w1 = 0.0; //背景区域联合概率密度
    85. double num1 = 0.0; //遍历过程中前景区i分量的值 与w0一样做相关处理
    86. double num2 = 0.0; //遍历过程中前景区j分量的值
    87. if (i >= 1)
    88. {
    89. w0 += S[i - 1];
    90. num1 += N1[i - 1];
    91. num2 += N2[i - 1];
    92. }
    93. for ( int j = 0; j < 256; j++)
    94. {
    95. w0 += Histogram[i][j]; //前景的概率
    96. num1 += i*Histogram[i][j]; //遍历过程中前景区i分量的值
    97. num2 += j*Histogram[i][j]; //遍历过程中前景区j分量的值
    98. w1 = 1 - w0; //背景的概率
    99. num3 = Pai - num1; //遍历过程中背景区i分量的值
    100. num4 = Paj - num2; //遍历过程中背景区j分量的值
    101. }
    102. Fgi = num1 / w0;
    103. Fgj = num2 / w1;
    104. Bgi = num3 / w0;
    105. Bgj = num4 / w1;
    106. TrMax = ((w0*Pai - num1)*(w0*Pai - num1) + (w0*Paj - num2)*(w0*Paj - num2)) / (w0*w1);
    107. if (TrMax > temp)
    108. {
    109. temp = TrMax;
    110. Threshold_s = i;
    111. }
    112. }
    113. cout << Threshold_s << endl;
    114. T = Threshold_s;
    115. return T;
    116. }

    展开全文
  • 智能优化算法应用:基于灰狼算法的二维Otsu图像阈值分割 文章目录智能优化算法应用:基于灰狼算法的二维Otsu图像阈值分割1.二维Otsu算法原理2.基于灰狼优化(GWO)的二维otsu阈值分割3.算法结果4.参考文献5.MATLAB...

    智能优化算法应用:基于灰狼算法的二维Otsu图像阈值分割


    摘要:1维Otsu法根据1维直方图来确定分割阈值,由于未考虑像素点邻域平均灰度值导致确定的分割阈值不准确,造成图像分割不正确,因研究人员提出了一种2维Otsu分割法。结合灰狼寻优能够得到较好的分割结果。

    1.二维Otsu算法原理

    2维Otsu法是在1维Otsu法的基础上引入像素点的邻域均值,原理如下 :假设原图像 f ( x , y ) f(x,y) f(x,y)和经过均值滤波(滤波窗口为 3× 3 )后的图像
    g ( x , y ) g(x,y) g(x,y) 的灰度级总数都为 L L L,所有像素点的像素和为 N N N,那么可以用二元数组 ( i , j ) (i,j) (i,j)来描述图像中的任意像素点,其中i和j分别是像素灰度值和邻域平均灰度值。假设在图像中像素点 ( i , j ) (i,j) (i,j) 存在的个数为 N i j N_{ij} Nij ,则该像素点出现的概率为:
    P i j = N i j / N , ∑ i = 0 L − 1 ∑ j = 0 L − 1 p i j = 1 (1) P_{ij}=N_{ij}/N,\sum_{i=0}^{L-1}\sum_{j=0}^{L-1}p_{ij}=1\tag{1} Pij=Nij/N,i=0L1j=0L1pij=1(1)
    随机给定一个分割阈值数组 ( s , t ) (s,t) (s,t),可将图像分为如图1所示的4个部分。图1中a、b、c、d依次表示图像中的边界、背景、目标和噪声。设该分割阈值将图像划分出的背景类 C 0 C_0 C0 和目标类 C 1 C_1 C1 出现的概率分别为 w 0 w_0 w0 w 1 w_1 w1 ,即:
    w 0 = ∑ i = 0 s − 1 ∑ j = 0 t − 1 p i j (2) w_0=\sum_{i=0}^{s-1}\sum_{j=0}^{t-1}p_{ij}\tag{2} w0=i=0s1j=0t1pij(2)

    w 1 = ∑ i = s s − 1 ∑ j = t t − 1 p i j (3) w_1=\sum_{i=s}^{s-1}\sum_{j=t}^{t-1}p_{ij}\tag{3} w1=i=ss1j=tt1pij(3)

    在这里插入图片描述

    图1 2维Otsu分割的图像分区

    则背景 C 0 C_0 C0和目标 C 1 C_1 C1区域对应的均值矢量为:
    u 0 = ( u 0 i , u o j ) T = [ ∑ i = 0 s − 1 ∑ j = 0 t − 1 i p i j , ∑ i = 0 s − 1 ∑ j = 0 t − 1 j p i j ] T (4) u_0=(u_{0i},u_{oj})^T=[\sum_{i=0}^{s-1}\sum_{j=0}^{t-1}ip_{ij},\sum_{i=0}^{s-1}\sum_{j=0}^{t-1}jp_{ij}]^T\tag{4} u0=(u0i,uoj)T=[i=0s1j=0t1ipij,i=0s1j=0t1jpij]T(4)

    u 1 = ( u 1 i , u 1 j ) T = [ ∑ i = s L − 1 ∑ j = t L − 1 i p i j , ∑ i = 0 s − 1 ∑ j = 0 t − 1 j p i j ] T (5) u_1=(u_{1i},u_{1j})^T=[\sum_{i=s}^{L-1}\sum_{j=t}^{L-1}ip_{ij},\sum_{i=0}^{s-1}\sum_{j=0}^{t-1}jp_{ij}]^T\tag{5} u1=(u1i,u1j)T=[i=sL1j=tL1ipij,i=0s1j=0t1jpij]T(5)

    则总的均值矢量为:
    u = ( u 1 i , u j ) T = [ ∑ i = 0 L − 1 ∑ j = 0 L − 1 i p i j , ∑ i = 0 L − 1 ∑ j = 0 L − 1 j p i j ] T (6) u=(u_{1i},u_{j})^T=[\sum_{i=0}^{L-1}\sum_{j=0}^{L-1}ip_{ij},\sum_{i=0}^{L-1}\sum_{j=0}^{L-1}jp_{ij}]^T\tag{6} u=(u1i,uj)T=[i=0L1j=0L1ipij,i=0L1j=0L1jpij]T(6)
    其类间离散矩阵定义如下:
    Q ( s , t ) = w 0 ( u 0 − u ) 2 + w 1 ( u 1 − u ) 2 (7) Q(s,t)=w_0(u_0-u)^2+w_1(u_1-u)^2\tag{7} Q(s,t)=w0(u0u)2+w1(u1u)2(7)
    将离散矩阵的迹作为 C 0 C_0 C0 区域和 C 1 C_1 C1 区域的类间离散度测度,即:
    R t r a c e ( Q ( s , t ) ) = ( w 0 + w 1 ) ∗ [ ( u 0 i − u i ) 2 + ( u o j − u j ) 2 ] (8) R_{trace}(Q(s,t))=(w_0+w_1)*[(u_{0i}-u_i)^2+(u_{oj}-u_j)^2]\tag{8} Rtrace(Q(s,t))=(w0+w1)[(u0iui)2+(uojuj)2](8)
    R t r a c e ( Q ( s , t ) ) R_{trace}(Q(s,t)) Rtrace(Q(s,t))取最大值时,此时确定的分割阈值 ( s 0 , t 0 ) (s_0,t_0) (s0,t0)是最优的,则目标可以较好地被分割出来,即:
    R t r a c e ( Q ( s 0 , t 0 ) ) = m a x ( R t r a c e ( Q ( s , t ) ) ) , 0 ≤ s ≤ L − 1 , 0 ≤ t ≤ L − 1 (9) R_{trace}(Q(s_0,t_0)) = max(R_{trace}(Q(s,t))),0\leq s\leq L-1,0\leq t \leq L-1 \tag{9} Rtrace(Q(s0,t0))=max(Rtrace(Q(s,t))),0sL1,0tL1(9)

    2.基于灰狼优化(GWO)的二维otsu阈值分割

    由上述二维Otsu阈值分割法的原理可知,要得到最终的阈值,需要去寻找阈值(s,t),使得离散度测度最大。于是可以利用智能优化算法进行阈值的寻优,使得获得最佳阈值。

    于是优化的适应度函数就是:
    f u n { T 1 ∗ , T 2 ∗ , . . . , T n − 1 ∗ } = m a x ( R t r a c e ( Q ( s , t ) ) ) , 0 ≤ s ≤ L − 1 , 0 ≤ t ≤ L − 1 fun\{T_1^*,T_2^*,...,T_{n-1}^*\} =max(R_{trace}(Q(s,t))),0\leq s\leq L-1,0\leq t \leq L-1 fun{T1,T2,...,Tn1}=max(Rtrace(Q(s,t))),0sL1,0tL1
    设置阈值分割的个数,寻优边界为0到255(因为直方图的灰度级范围为0-255),设置相应的灰狼算法参数(灰狼算法具体原理及代码参照我之前写灰狼算法原理:https://blog.csdn.net/u011835903/article/details/107716390)。

    3.算法结果

    以lena,cameraman为例子

    在这里插入图片描述

    阈值分割结果
    在这里插入图片描述
    在这里插入图片描述

    4.参考文献

    [1]邵闯,王生怀,邹春龙,周红勋.基于混合粒子群优化的2维Otsu路面裂缝图像阈值分割方法[J].湖北汽车工业学院学报,2019,33(03):53-57.

    5.MATLAB代码

    基于灰狼算法的二维Otsu图像阈值分割
    基于穷举法的二维Otsu图像阈值分割

    个人资料介绍

    展开全文
  • OTSU算法简述

    2014-11-22 15:22:00
    OTSU算法,又称为最大类间方差法,有时

    OTSU算法,又称为最大类间方差法,也称为大津算法,是由日本学者OTSU于1979年突出的一种对图像进行二值化的高效算法。通过算法自动选择阈值,实现灰度值的二分化,产生差异最大的两个灰度值,以此突出要识别的物体。


    G=w1 * (u1 - u) * (u1 - u) + w1 * (u1 - u) * (u1 - u)

    W1:前景值占比例,均值为u1w1:后景值占比例,均值为u1;u为整个图的均值;G为最佳阈值;


    通过最佳阈值,可以有效的提高物体特征的识别率,从画面中突出目标物体。虽然因此对光照的适应性有了极大的提高,但是该方法对背景和前景复杂的图片处理能力有限。如下图所示:

    <img src="https://img-blog.csdn.net/20141130145108789" alt="" />
    
     
    
    <span style="font-size:10px;">该图盗自:http://blog.csdn.net/wuhaibing_cver/article/details/8473498</span>
    
    

    展开全文
  • 智能优化算法应用:基于灰狼算法的Otsu图像多阈值分割-附代码 文章目录智能优化算法应用:基于灰狼算法的Otsu图像多阈值分割-附代码1.Otsu阈值分割法原理2.基于灰狼优化(GWO)的多阈值分割3.算法结果:4.参考文献:...
  • OTSU算法及其改进算法学习

    万次阅读 2014-02-19 22:53:48
    这篇文章还是来自斯坦福课后作业hw2_3,主要是结合一个例子介绍otsu算法【亦称为大律算法,小日本】及其改进算法。  本文将先介绍老外的题目、解题思路及maltab解答,然后分析otsu算法步骤,末了给出opencv实现。 ...
  • 针对二维 Otsu阈值算法计算复杂度高的缺点,提出一种快速算法。该方法首先对阈值的判定公式作了一定 的推导以减少计算变量,然后用迭代的方法消除计算冗余,最后结合小波分解和对角线优先搜索的策略获得图像 分割阈值。...
  • Niblack算法OTSU算法的实现

    千次阅读 2014-03-30 21:50:03
    1、OTSU算法是设阈值将图像分割成俩组,一组灰度对应目标,另一组灰度对应背景,则这俩组灰度值的类内方差最小,俩组的类间方差最大。相关公式:  g = w0 *(u0 - u)*(u0 - u) + w1*(u1 - u)*(u1 - u) = w0 * w1 *...
  • 通过Otsu算法与粒子群优化算法结合,来降低图像分割的时间复杂度;针对影响因素的多样性,通过分离因子确定阈值分割个数。实验结果表明,该方法对贴剂图像具有良好的分割效果,满足速度和精度要求。
  • 算法通过求两个一维Otsu法的阈值来代替传统的二维Otsu法的分割阈值为保证分割对象的完整性,算法引入类内最小离散度的概念,并通过遗传算法实现对参数的自动优化。理论分析和实验结果表明本算法计算速度不仅优于原...
  • 粒子群优化算法(PSO):它是进化算法的一种,它源于鸟群捕食的行为研究,基本思想是通过群体中个体之间的协作和信息共享来寻找最优解。在PSO中,每个优化问题的潜在解都是搜索空间中的一只鸟,抽象为粒子,每个粒子...
  • otsu.py定义了最大类间方差函数,test.py用于运行GA model,IGA为遗传算法策略的改进版本,make_video.py用于将每一代的结果制作成视频(如果将每个点家加上一个随机偏移,画出来的效果会更好哦,可以自己尝试)。...
  • OTSU算法对图像二值化

    千次阅读 2017-07-20 14:10:03
    OTSU算法对图像二值化
  • 遗传算法优化otsu分割问题python实现

    千次阅读 2018-11-27 16:54:47
    最大类间方差法(Otsu) 详见https://www.cnblogs.com/xiaomanon/p/4110006.html,这里就不去赘述了。 遗传算法策略 关于遗传算法的详解什么的,可以参考其他的类似文章,下面讲讲我自己的策略 种群编码策略 二...
  • DSP移植-OTSU算法

    2016-07-29 20:11:01
    有关OTSU算法的原理,网络上有很过资源,描述得也很清楚,这里引用已有代码,稍加修改后(原来的代码可能有溢出,无法找到正确的阈值),能够正确运行。 两段代码的效果类似,第一个函数的阈值是149, 第二个函数的...
  • Otsu算法原理与python实现

    千次阅读 2020-05-10 17:24:27
    [注:下面公式所涉及的是带权重的均值与方差,一开始我并不明白为什么要这样做,还去查了关于带权重与不带权重计算均值或方差的区别,后面发现,应该是因为该算法的计算是基于概率分布,而概率分布意味着这是一个...
  • C++实现OTSU算法,使得两类的区分度最大。该函数可以直接使用。
  • OTSU算法提取图像阈值的C语言实现

    千次阅读 2011-10-29 14:59:00
    OTSU算法也称最大类间差法,有时也称之为大津算法,被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。它是按图像的灰度特性,将图像分成背景和...
  • 优化算法——差分进化算法(DE)

    万次阅读 2018-09-11 13:43:20
    一、差分进化算法的介绍 ...DE算法也属于智能优化算法,与前面的启发式算法,如ABC,PSO等类似,都属于启发式的优化算法。DE算法是我在一篇求解盒子覆盖问题论文中使用的一种优化算法。 二、差分进化算法的流...
  • 该方法使用二维灰色Otsu模型作为鸡群优化算法的适应度函数,利用鸡群中公鸡、母鸡和小鸡的角色分工、协同工作快速逼近最佳阈值。实验结果表明,该方法在收敛速度和分割效果两方面均优于基于遗传算法、人工鱼群算法等...
  • OTSU大津阈值及其加速算法解析:详解大津阈值算法原理,并粗略给出其求解过程的伪代码。之后,给出算法加速的方案解析及其流程,并最终指出加速前后的时间对比情况
  • 基于粒子群优化OTSU 图像分割

    千次阅读 2019-04-16 13:30:10
    思想:粒子群算法是一种优化算法,与狼群算法,遗传算法类似,用于求取全局最优解;将粒子群与 OTSU 相结合目的是为了快速找到图像分割的最佳阈值,提高图像分割的效率。 粒子群算法原理: 受飞鸟集群飞行觅食行为...
  • Otsu最佳全局算法c#实现-基于EmguCV

    千次阅读 2016-09-22 02:29:41
    算法网上有很多详细介绍的,这里就不讲,只贴代码,本人是根据《数字图像处理第三版》冈萨雷斯 里面所描述,再根据自己的理解写出来的,可能会存在一些问题。 代码也没进行优化,可能运行速度比较慢。 此函数根据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 710
精华内容 284
关键字:

otsu优化算法