Multi otsu(multi-thresholding) with openCV

后端 未结 6 1612
忘掉有多难
忘掉有多难 2020-12-02 23:53

I am trying to carry out multi-thresholding with otsu. The method I am using currently is actually via maximising the between class variance, I have managed to get the same

6条回答
  •  抹茶落季
    2020-12-03 00:31

    @Antoni4 gives the best answer in my opinion and it's very straight forward to increase the number of levels.

    This is for three-level thresholding:

    #include "Shadow01-1.cuh"
    
    void multiThresh(double &optimalThresh1, double &optimalThresh2, double &optimalThresh3, cv::Mat &imgHist, cv::Mat &src)
    {
    double W0K, W1K, W2K, W3K, M0, M1, M2, M3, currVarB, maxBetweenVar, M0K, M1K, M2K, M3K, MT;
    unsigned char *histogram = (unsigned char*)(imgHist.data);
    
    int N = src.rows*src.cols;
    W0K = 0;
    W1K = 0;
    M0K = 0;
    M1K = 0;
    MT = 0;
    maxBetweenVar = 0;
    
    for (int k = 0; k <= 255; k++) {
        MT += k * (histogram[k] / (double) N);
    }
    
    for (int t1 = 0; t1 <= 255; t1++)
    {
        W0K += histogram[t1] / (double) N; //Pi
        M0K += t1 * (histogram[t1] / (double) N); //i * Pi
        M0 = M0K / W0K; //(i * Pi)/Pi
    
        W1K = 0;
        M1K = 0;
    
        for (int t2 = t1 + 1; t2 <= 255; t2++)
        {
            W1K += histogram[t2] / (double) N; //Pi
            M1K += t2 * (histogram[t2] / (double) N); //i * Pi
            M1 = M1K / W1K; //(i * Pi)/Pi
            W2K = 1 - (W0K + W1K);
            M2K = MT - (M0K + M1K);
    
            if (W2K <= 0) break;
    
            M2 = M2K / W2K;
    
            W3K = 0;
            M3K = 0;
    
            for (int t3 = t2 + 1; t3 <= 255; t3++)
            {
                W2K += histogram[t3] / (double) N; //Pi
                M2K += t3 * (histogram[t3] / (double) N); // i*Pi
                M2 = M2K / W2K; //(i*Pi)/Pi
                W3K = 1 - (W1K + W2K);
                M3K = MT - (M1K + M2K);
    
                M3 = M3K / W3K;
                currVarB = W0K * (M0 - MT) * (M0 - MT) + W1K * (M1 - MT) * (M1 - MT) + W2K * (M2 - MT) * (M2 - MT) + W3K * (M3 - MT) * (M3 - MT);
    
                if (maxBetweenVar < currVarB)
                {
                    maxBetweenVar = currVarB;
                    optimalThresh1 = t1;
                    optimalThresh2 = t2;
                    optimalThresh3 = t3;
                }
            }
        }
    }
    }
    

提交回复
热议问题