영상처리
AutoThreshold (Minimum) C++
park__
2024. 12. 11. 11:28
Java -> C++
Code
inline bool bimodalTest(double* y, int n_length)
{
int len = n_length;
bool b = false;
int modes = 0;
for (int k = 1; k < len - 1; k++)
{
if (y[k - 1] < y[k] && y[k + 1] < y[k])
{
modes++;
if (modes > 2)
return false;
}
}
if (modes == 2)
b = true;
return b;
}
int Minimum(float* histo, int n_length)
{
if (n_length < 2)
return 0;
// J. M. S. Prewitt and M. L. Mendelsohn, "The analysis of cell images," in
// Annals of the New York Academy of Sciences, vol. 128, pp. 1035-1053, 1966.
// ported to ImageJ plugin by G.Landini from Antti Niemisto's Matlab code (GPL)
// Original Matlab code Copyright (C) 2004 Antti Niemisto
// See http://www.cs.tut.fi/~ant/histthresh/ for an excellent slide presentation
// and the original Matlab code.
//
// Assumes a bimodal histogram. The histogram needs is smoothed (using a
// running average of size 3, iteratively) until there are only two local maxima.
// Threshold t is such that yt-1 > yt ≤ yt+1.
// Images with histograms having extremely unequal peaks or a broad and
// flat valley are unsuitable for this method.
int iter = 0;
int threshold = -1;
int max = -1;
double* iHisto = nullptr;
double* tHisto = nullptr;
iHisto = new double[n_length];
tHisto = new double[n_length]; // Instead of double[] tHisto = iHisto ;
for (int i = 0; i < n_length; i++)
{
iHisto[i] = (double)histo[i];
if (histo[i] > 0)
max = i;
}
while (!bimodalTest(iHisto, n_length))
{
//smooth with a 3 point running mean filter
for (int i = 1; i < n_length - 1; i++)
tHisto[i] = (iHisto[i - 1] + iHisto[i] + iHisto[i + 1]) / 3;
tHisto[0] = (iHisto[0] + iHisto[1]) / 3; //0 outside
tHisto[n_length - 1] = (iHisto[n_length - 2] + iHisto[n_length - 1]) / 3; //0 outside
std::memcpy(iHisto, tHisto, n_length * sizeof(double)); //Instead of iHisto = tHisto ;
iter++;
if (iter > 10000)
{
threshold = -1;
std::cout << ("Minimum Threshold not found after 10000 iterations.");
return threshold;
}
}
// The threshold is the minimum between the two peaks. modified for 16 bits
for (int i = 1; i < max; i++)
{
//IJ.log(" "+i+" "+iHisto[i]);
if (iHisto[i - 1] > iHisto[i] && iHisto[i + 1] >= iHisto[i])
{
threshold = i;
break;
}
}
return threshold;
}
imageJ 관련 문서 : https://imagej.net/plugins/auto-threshold
github link : https://github.com/fiji/Auto_Threshold/blob/master/src/main/java/fiji/threshold/Auto_Threshold.java