영상처리

AutoThreshold (Triangle) C++

park__ 2024. 12. 11. 16:02

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