最优阈值分割算法(迭代)

原理太多,不再赘述

#include<iostream>
#include<opencv2/opencv.hpp>

void OptimSegmentation(unsigned char*inputimage, int height, int width);
using namespace cv;
void OptimSegmentation(unsigned char*inputimage, int height, int width)
{
    //1.计算直方图
    int *histarray = new int[256];
    int i,x,y;
    for (i = 0; i < 256; i++)
    {
        histarray[i] = 0;
    }
    //中间变量
    int temp,temp1,temp2;
    //统计灰度直方图
    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {
            int k = width*y + x;
            temp = inputimage[k];
            histarray[temp]++;
        }
    }

    //2.计算最优阈值
//  int minT = 0,maxT=0;
    double MinGrayValue = 0, MaxGrayValue =0;
    //float P0 = 0.0, Pt = 0.0;
    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {
            int k = width*y + x;
            temp1 = inputimage[k];
            if (MinGrayValue > temp1)
                MinGrayValue = temp1;//最小灰度值
        }
    }
    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {
            int k = width*y + x;
            temp2 = inputimage[k];
            if (MaxGrayValue < temp2)
                MaxGrayValue = temp2;//最大灰度值
        }
    }
    double newT = (MinGrayValue + MaxGrayValue) / 2;
    //std::cout << newT << std::endl;
    double T = 0.0;
    double S0 = 0.0,N1 = 0.0; //初始化大于阈值的元素的个数及其灰度总值
    double S1 = 0.0,N2 = 0.0; //初始化小于阈值的元素的个数及其灰度总值
    while (abs(newT - T)>0)
    {
        T = newT;
        //std::cout << T << std::endl;
        for (i = 0; i < 256; i++)
        {
            if (i > T)
            {
                S0 = S0 + histarray[i]; //记录大于阈值的元素个数及其灰度总值
                //N1 = N1 + 1;
                N1 += i*histarray[i];
            }
            else
            {
                S1 = S1 + histarray[i];
                //N2 = N2 + 1;
                N2 += i*histarray[i];
            }
        }
        double T0 = N1/S0;  //生成新阈值
        double T1 = N2/S1;
        newT = (T0 + T1) / 2;
    //  std::cout << newT << std::endl;
        S0 = 0.0; N1 = 0.0;  //重置初值
        S1 = 0.0; N2 = 0.0;
    }

    //3.图像二值化
//  unsigned char *outimage1=new unsigned char[height*width];
    for (y = 0; y<height; y++)
    {
        for (x = 0; x < width; x++)
        {
            int k = width*y + x;
            //outimage1[k] = inputimage[k];
            //std::cout << outimage1[k] << std::endl;
        //  std::cout << T << std::endl;
            if (inputimage[k] > T)   //亮点为白色
                inputimage[k] = 255;

            else
                inputimage[k] = 0;

        }
    }
    delete[] histarray;
    //delete[] outimage1;
}
int main()
{
    Mat lena = imread("test2.png");
    //imshow("1", lena);
    cvtColor(lena, lena, CV_RGB2GRAY);
    int height = lena.rows;
    int width = lena.cols;
    uchar* covertimage = new uchar[height * width];
    uchar* p;
    int i, j;
    for (i = 0; i<height; i++)
    {
        p = lena.ptr<uchar>(i);
        for (j = 0; j<width; j++)
        {
            covertimage[i*width + j] = p[j];
        }
    }
    OptimSegmentation(covertimage, width, height);
    Mat outimage(height, width, CV_8UC1, covertimage); //一维数组转Mat类
    //cvNamedWindow("图像显示", CV_WINDOW_AUTOSIZE);
    imshow("output", outimage);
    waitKey(0);
    delete[] covertimage;
    return 0;
}
  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值