Перевести код из C++ - реализация метода Оцу - C#
Формулировка задачи:
Добрый день. Имеется реалицация метода Оцу на C++, необходимо перенести код в C#. Помогите пожалуйста в реализации, или может имеется готовое решение.
typedef unsigned char imageInt;
// Определение порога методом Оцу
int otsuThreshold(imageInt *image, int size)
{
// Проверки на NULL и проч. опустим, чтобы сконцетрироваться
// на работе метода
// Посчитаем минимальную и максимальную яркость всех пикселей
int min = image[0];
int max = image[0];
for (int i = 1; i < size; i++)
{
int value = image[i];
if (value < min)
min = value;
if (value > max)
max = value;
}
// Гистограмма будет ограничена снизу и сверху значениями min и max,
// поэтому нет смысла создавать гистограмму размером 256 бинов
int histSize = max - min + 1;
int* hist = new int[histSize];
// Заполним гистограмму нулями
for (int t = 0; t < histSize; t++)
hist[t] = 0;
// И вычислим высоту бинов
for (int i = 0; i < size; i++)
hist[image[i] - min]++;
// Введем два вспомогательных числа:
int m = 0; // m - сумма высот всех бинов, домноженных на положение их середины
int n = 0; // n - сумма высот всех бинов
for (int t = 0; t <= max - min; t++)
{
m += t * hist[t];
n += hist[t];
}
float maxSigma = -1; // Максимальное значение межклассовой дисперсии
int threshold = 0; // Порог, соответствующий maxSigma
int alpha1 = 0; // Сумма высот всех бинов для класса 1
int beta1 = 0; // Сумма высот всех бинов для класса 1, домноженных на положение их середины
// Переменная alpha2 не нужна, т.к. она равна m - alpha1
// Переменная beta2 не нужна, т.к. она равна n - alpha1
// t пробегается по всем возможным значениям порога
for (int t = 0; t < max - min; t++)
{
alpha1 += t * hist[t];
beta1 += hist[t];
// Считаем вероятность класса 1.
float w1 = (float)beta1 / n;
// Нетрудно догадаться, что w2 тоже не нужна, т.к. она равна 1 - w1
// a = a1 - a2, где a1, a2 - средние арифметические для классов 1 и 2
float a = (float)alpha1 / beta1 - (float)(m - alpha1) / (n - beta1);
// Наконец, считаем sigma
float sigma = w1 * (1 - w1) * a * a;
// Если sigma больше текущей максимальной, то обновляем maxSigma и порог
if (sigma > maxSigma)
{
maxSigma = sigma;
threshold = t;
}
}Решение задачи: «Перевести код из C++ - реализация метода Оцу»
textual
Листинг программы
private static unsafe int OtsuMethod(ref BitmapData bmData)
{
var hist = new int[256];
Array.Clear(hist, 0, hist.Length);
int height = bmData.Height;
int width = bmData.Width;
int stride = bmData.Stride;
var row = (byte*) (bmData.Scan0);
int i;
for (int j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
hist[row[i]]++;
}
row += stride;
}
float sum = 0; // Total
for (i = 1; i < 256; i++)
{
sum += i*hist[i];
}
float sumB = 0; // Current
int wB = 0; // Weight Background
int wF; // Weight Foreground
int threshold = 0;
int total = width*height;
float mD; // Mean difference
float currentMax, totalMax = 0;
for (i = 0; i < 256; i++)
{
// Weight Background
wB += hist[i];
if (wB == 0) continue;
// Weight Foreground
wF = total - wB;
if (wF == 0) break;
sumB += i*hist[i];
// Means
mD = sumB/wB - (sum - sumB)/wF;
// Variance between classes
// [url]http://upload.wikimedia.org/math/8/9/4/894892ba54d00a159aaebfb515c6643d.png[/url]
currentMax = wB*wF*mD*mD;
// If new maximum found
if (currentMax > totalMax)
{
totalMax = currentMax;
threshold = i; // New threshold
}
}
return threshold;
}