영상처리

AutoThreshold (Shanbhag) C++

park__ 2024. 12. 11. 15:57

Java -> C++

 

Code

int Shanbhag(float* histo, int n_length) {
	// Shanhbag A.G. (1994) "Utilization of Information Measure as a Means of
	//  Image Thresholding" Graphical Models and Image Processing, 56(5): 414-419
	// Ported to ImageJ plugin by G.Landini from E Celebi's fourier_0.8 routines
	int threshold;
	int ih, it;
	int first_bin;
	int last_bin;
	double term;
	double tot_ent;  /* total entropy */
	double min_ent;  /* max entropy */
	double ent_back; /* entropy of the background pixels at a given threshold */
	double ent_obj;  /* entropy of the object pixels at a given threshold */
	double* norm_histo = nullptr;
	double* P1 = nullptr;
	double* P2 = nullptr;

	P1 = new double[n_length]; /* cumulative normalized histogram */
	P2 = new double[n_length];
	norm_histo = new double[n_length]; /* normalized histogram */

	int total = 0;
	for (ih = 0; ih < n_length; ih++)
		total += histo[ih];

	for (ih = 0; ih < n_length; ih++)
		norm_histo[ih] = (double)histo[ih] / total;

	P1[0] = norm_histo[0];
	P2[0] = 1.0 - P1[0];

	for (ih = 1; ih < n_length; ih++) 
	{
		P1[ih] = P1[ih - 1] + norm_histo[ih];
		P2[ih] = 1.0 - P1[ih];
	}

	/* Determine the first non-zero bin */
	first_bin = 0;

	for (ih = 0; ih < n_length; ih++) 
	{
		if (!(abs(P1[ih]) < 2.220446049250313E-16)) 
		{
			first_bin = ih;
			break;
		}
	}

	/* Determine the last non-zero bin */
	last_bin = n_length - 1;

	for (ih = n_length - 1; ih >= first_bin; ih--) 
	{
		if (!(abs(P2[ih]) < 2.220446049250313E-16))
		{
			last_bin = ih;
			break;
		}
	}

	// Calculate the total entropy each gray-level
	// and find the threshold that maximizes it 
	threshold = -1;
	min_ent = DBL_MAX;

	for (it = first_bin; it <= last_bin; it++) {
		/* Entropy of the background pixels */
		ent_back = 0.0;
		term = 0.5 / P1[it];

		for (ih = 1; ih <= it; ih++) 
		{ //0+1?
			ent_back -= norm_histo[ih] * log(1.0 - term * P1[ih - 1]);
		}

		ent_back *= term;

		/* Entropy of the object pixels */
		ent_obj = 0.0;
		term = 0.5 / P2[it];

		for (ih = it + 1; ih < n_length; ih++) 
		{
			ent_obj -= norm_histo[ih] * log(1.0 - term * P2[ih]);
		}
		ent_obj *= term;

		/* Total entropy */
		tot_ent = abs(ent_back - ent_obj);

		if (tot_ent < min_ent)
		{
			min_ent = tot_ent;
			threshold = it;
		}
	}

	if (norm_histo)
		delete[] norm_histo;

	if (P1)
		delete[] P1;

	if (P2)
		delete[] P2;

	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

반응형

'영상처리' 카테고리의 다른 글

AutoThreshold (Yen) C++  (1) 2024.12.11
AutoThreshold (Triangle) C++  (0) 2024.12.11
AutoThreshold (RenyiEntropy) C++  (2) 2024.12.11
AutoThreshold (Percentile) C++  (1) 2024.12.11
AutoThreshold (Otsu) C++  (1) 2024.12.11