Otsu Thresholding ile Eşik Belirleme

Merhabalar,

Otsu Metodu görüntü işlemede çokça kullanılan metodlardan biridir. Nasıl çalıştığına ve formüllerine buradan bakabilirsiniz.

Between class variance hesabı daha az maliyetli olduğu için kodu yazarken onu kullandım.

Threshold Fonksiyonu böyle oldu:

BYTE* raw_intensity = ConvertBMPToIntensity(buffer, Width, Height);//resmi intensity değerlere çevirip tek bir matrise atıyoruz.
int HistogramValues[256];
int HistogramValue = 0; double ImageSize = Height * Width;
double BackgroundWeight = 0, BackgroundMean = 0, ForegroundWeight = 0, ForegroundMean = 0;
double  SummaryMean = 0, SummaryBackground = 0, BetweenClassVariance = 0, MaxVariance = 0;
double  Summary = 0,SummaryBackgroundMean = 0;
double ThresholdValue = 128;
for (int i = 0; i < 256; i++)//reset list
{
	HistogramValues[i] = 0;
}
for (int row = 0; row < Height; row++)//find histogram
{
	for (int col = 0; col < Width; col++)
	{
		HistogramValue = *(raw_intensity + row * Width + col);
		HistogramValues[HistogramValue] = HistogramValues[HistogramValue] + 1;
	}
}
for (int i = 0; i < 256; i++)
{
	SummaryMean += i * HistogramValues[i];
	Summary += HistogramValues[i];
}
for (int i = 0; i < 256; i++)
{
	SummaryBackground += HistogramValues[i];
	BackgroundWeight = SummaryBackground / ImageSize;//refaktor edilebilir bu kisim
	SummaryBackgroundMean += i * HistogramValues[i];
	BackgroundMean = SummaryBackgroundMean / SummaryBackground;
	ForegroundWeight = (Summary - SummaryBackground) / ImageSize;
	ForegroundMean = (SummaryMean - SummaryBackgroundMean) / (Summary - SummaryBackground);
	//BackgroundWeight += HistogramValues[i];
	//if (BackgroundWeight == 0)continue;
	//ForegroundWeight = Height * Width - BackgroundWeight;
	//if (ForegroundWeight == 0)break;//tüm pikseller bitmistir baska renk yoktur

	//SummaryBackground += i * HistogramValues[i];
	//BackgroundMean = SummaryBackground / BackgroundWeight;
	//ForegroundMean = Summary - SummaryBackground / ForegroundWeight;
	BetweenClassVariance = BackgroundWeight * ForegroundWeight *
		(BackgroundMean - ForegroundMean) *
		(BackgroundMean - ForegroundMean);
	if (BetweenClassVariance > MaxVariance)
	{
		MaxVariance = BetweenClassVariance;
		ThresholdValue = i;
	}
}
label1->Text = ThresholdValue.ToString();
for (int row = 0; row < Height; row++)
{
	for (int col = 0; col < Width; col++)
	{
		if (raw_intensity[row * Width + col] > ThresholdValue)
			raw_intensity[row * Width + col] = 255;
		else
			raw_intensity[row * Width + col] = 0;
	}
}

Yorum Bırak...