Browse Source

增加 前景分割

孙武 1 day ago
parent
commit
a79684905f
1 changed files with 86 additions and 0 deletions
  1. 86 0
      utils.cpp

+ 86 - 0
utils.cpp

@@ -98,3 +98,89 @@ int applyInvertMask(unsigned short* input, unsigned char* pmask, int Width, int
 
 	return 1;
 }
+
+
+int getForegroundMask(unsigned short* input, unsigned char* pmask, int Width, int Height, unsigned char* output)
+{
+	if (!input || !pmask || !output) {
+		std::cerr << "Error: Null pointer input!" << std::endl;
+		return 0;
+	}
+	if (Width <= 0 || Height <= 0) {
+		std::cerr << "Error: Invalid image size!" << std::endl;
+		return 0;
+	}
+
+	int max_grayv = 65535;
+	int* h = new int[max_grayv + 1]();
+	int i, j = { 0 };
+	double masksum = 0;
+	double mu = 0;
+#pragma omp parallel for
+	for (i = 0; i < Width* Height; i++)
+	{
+		if (pmask[i])
+		{
+			h[input[i]]++;
+			masksum++;
+			mu += input[i];
+		}	
+	}
+	
+	mu /= masksum;
+
+	if (masksum < 1e-6) {
+		std::cerr << "Warning: Mask region is empty." << std::endl;
+		delete[] h;
+		std::fill(output, output + Width * Height, 0);
+		return 0;
+	}
+
+	double mu1 = 0, q1 = 0;
+	double max_sigma = 0, max_val = 0;
+	double scale = 1. / masksum;
+	for (i = 0; i < max_grayv + 1; i++)
+	{
+		double p_i, q2, mu2, sigma;
+
+		p_i = h[i] * scale;
+		mu1 *= q1;
+		q1 += p_i;
+		q2 = 1. - q1;
+
+		if (std::min(q1, q2) < FLT_EPSILON || std::max(q1, q2) > 1. - FLT_EPSILON)
+			continue;
+
+		mu1 = (mu1 + i * p_i) / q1;
+		mu2 = (mu - q1 * mu1) / q2;
+		sigma = q1 * q2 * (mu1 - mu2) * (mu1 - mu2);
+		if (sigma > max_sigma)
+		{
+			max_sigma = sigma;
+			max_val = i;
+		}
+	}
+
+	delete[]h;
+
+	for (i = 0; i < Width * Height; i++)
+	{
+		if (pmask[i])
+		{
+			if (input[i] < max_val)
+			{
+				output[i] = 1;
+			}
+			else
+			{
+				output[i] = 0;
+			}
+		}
+		else
+		{
+			output[i] = 0;
+		}
+	}
+
+	return 1;
+}