多级阈值处理。大津的方法

时间:2016-01-18 13:32:32

标签: opencv image-processing computer-vision

我知道这个问题可能与Multi otsu(multi-thresholding) with openCV重复,因为它非常相似。但我没有足够的权限对​​此发表评论,所以我的问题得到了解答。

我尝试使用OPENCV库使用Otsu的方法进行三级阈值。我正在关注@ Antoni4发布的指南,但它只涉及两级阈值,我无法将其扩展到三级。

我知道如何使Otsu的原始方法起作用,最大化类间差异,但我如何添加外部(或内部)for循环来计算我不知道的第三级阈值。

我使用此代码进行两级阈值处理:

#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;

        currVarB = W0K * (M0 - MT) * (M0 - MT) + W1K * (M1 - MT) * (M1 - MT) + W2K * (M2 - MT) * (M2 - MT);

        if (maxBetweenVar < currVarB)
        {
            maxBetweenVar = currVarB;
            optimalThresh1 = t1;
            optimalThresh2 = t2;
        }

    }
}

}

我实际上并不知道这两行是什么:

W2K = 1 - (W0K + W1K);
M2K = MT - (M0K + M1K);

我如何将它们扩展到第三个阈值。

提前致谢。

1 个答案:

答案 0 :(得分:1)

[编辑]修复了@reexre报告的错误 是的,没关系。

我实现了第三个内部for循环以添加另一个阈值级别并使用以下行作为W3K和M3K,即使我仍然不知道他们为什么会这样。

W3K = 1 - (W1K + W2K);
M3K = MT - (M1K + M2K);

有效。

整个代码是:

#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;

        W2K = 0;
        M2K = 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 - (W0K + W1K + W2K);
            M3K = MT - (M0K + 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;
            }
        }
    }
}
}