Java -> C++
Code
int Triangle(float* histo, int n_length)
{
// Zack, G. W., Rogers, W. E. and Latt, S. A., 1977,
// Automatic Measurement of Sister Chromatid Exchange Frequency,
// Journal of Histochemistry and Cytochemistry 25 (7), pp. 741-753
//
// modified from Johannes Schindelin plugin
//
// find min and max
int min = 0, dmax = 0, max = 0, min2 = 0;
for (int i = 0; i < n_length; i++)
{
if (histo[i] > 0) {
min = i;
break;
}
}
if (min > 0) min--; // line to the (p==0) point, not to data[min]
// The Triangle algorithm cannot tell whether the data is skewed to one side or another.
// This causes a problem as there are 2 possible thresholds between the max and the 2 extremes
// of the histogram.
// Here I propose to find out to which side of the max point the data is furthest, and use that as
// the other extreme. Note that this is not done in the original method. GL
for (int i = n_length - 1; i > 0; i--)
{
if (histo[i] > 0) {
min2 = i;
break;
}
}
if (min2 < n_length - 1) min2++; // line to the (p==0) point, not to data[min]
for (int i = 0; i < n_length; i++)
{
if (histo[i] > dmax)
{
max = i;
dmax = histo[i];
}
}
// find which is the furthest side
//IJ.log(""+min+" "+max+" "+min2);
bool inverted = false;
if ((max - min) < (min2 - max))
{
// reverse the histogram
//IJ.log("Reversing histogram.");
inverted = true;
int left = 0; // index of leftmost element
int right = n_length - 1; // index of rightmost element
while (left < right)
{
// exchange the left and right elements
int temp = histo[left];
histo[left] = histo[right];
histo[right] = temp;
// move the bounds toward the center
left++;
right--;
}
min = n_length - 1 - min2;
max = n_length - 1 - max;
}
if (min == max) {
//IJ.log("Triangle: min == max.");
return min;
}
// describe line by nx * x + ny * y - d = 0
double nx, ny, d;
// nx is just the max frequency as the other point has freq=0
nx = histo[max]; //-min; // data[min]; // lowest value bmin = (p=0)% in the image
ny = min - max;
d = sqrt(nx * nx + ny * ny);
nx /= d;
ny /= d;
d = nx * min + ny * histo[min];
// find split point
int split = min;
double splitDistance = 0;
for (int i = min + 1; i <= max; i++)
{
double newDistance = nx * i + ny * histo[i] - d;
if (newDistance > splitDistance)
{
split = i;
splitDistance = newDistance;
}
}
split--;
if (inverted)
{
// The histogram might be used for something else, so let's reverse it back
int left = 0;
int right = n_length - 1;
while (left < right)
{
int temp = histo[left];
histo[left] = histo[right];
histo[right] = temp;
left++;
right--;
}
return (n_length - 1 - split);
}
else
return split;
}
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
'영상처리' 카테고리의 다른 글
OpenCV rectangle(Python) (0) | 2024.12.12 |
---|---|
AutoThreshold (Yen) C++ (1) | 2024.12.11 |
AutoThreshold (Shanbhag) C++ (0) | 2024.12.11 |
AutoThreshold (RenyiEntropy) C++ (2) | 2024.12.11 |
AutoThreshold (Percentile) C++ (1) | 2024.12.11 |