K-Means ile eşik belirleme (Thresholding with K-Means)

Merhabalar,
bir önceki yazımda otsu kullanarak eşik bulmuştuk bu sefer bir kümeleme algoritması kullanacağız. K-Means rastgele seçilen k noktaya en yakın değerlerin gruplanmasına ve yeni ağırlık merkezinin belirlendikten sonra yine en yakın noktaların tespit edilmesine dayanıyor. Buradan daha detaylı bilgi edinebilirsiniz.

Uzun bir süredir bir şeyler yazamadım malum karantina olaylarında motivasyonumuz da düştü sanırsam. (umarım yakın zamanda atlatırız).

tüm piksellerin bir array’e soldan sağa sıralı bir şekilde sıralandığını düşünürsek:

BYTE* intensity = ConvertBMPToIntensity(buffer, Width, Height);//pixel array
int kNumber = 2;
//default k for code = 2 
int HistogramValues[256];
memset(HistogramValues, 0, sizeof(HistogramValues));//reset
int HistogramValue = 0, threshold = 120;
double* kValues, * kValuesOld, * kValuesSummary;
kValues = new double[kNumber];
kValuesOld = new double[kNumber];
kValuesSummary = new double[kNumber];
bool isFind = false;
for (size_t i = 0; i < kNumber; i++)//random number
{
	kValues[i] = rand() % 256;
	kValuesOld[i] = 0;
	kValuesSummary[i] = 0;
}
for (int row = 0; row < Height; row++)//find histogram
{
	for (int col = 0; col < Width; col++)
	{
		HistogramValue = *(intensity + row * Width + col);
		HistogramValues[HistogramValue] = HistogramValues[HistogramValue] + 1;
	}
}
while (true)
{
	for (size_t i = 0; i < kNumber; i++)
	{
		if (kValues[i] == kValuesOld[i])
			isFind = true;
	}
	if (isFind)break;//k degerleri esit olmadikca devam eder
	for (size_t i = 0; i < kNumber; i++)
	{
		kValuesOld[i] = kValues[i];
		kValues[i] = 0;
		kValuesSummary[i] = 0;
	}
	threshold = 0;
	for (int i = 0; i < 256; i++)
	{
		if (abs(kValues[0] - i) < abs(kValues[1] - i))
		{//yakin olana ekliyoruz
			kValues[0] += i * HistogramValues[i];
			kValuesSummary[0] += i;
			threshold++;
		}
		else
		{
			kValues[1] += i * HistogramValues[i];
			kValuesSummary[1] += i;
		}
	}
	kValues[0] = kValues[0] / kValuesSummary[0];
	kValues[1] = kValues[1] / kValuesSummary[1];
}

for (int row = 0; row < Height; row++)
{
	for (int col = 0; col < Width; col++)
	{
		if (intensity[row * Width + col] > threshold)
			intensity[row * Width + col] = 255;
		else
			intensity[row * Width + col] = 0;
	}
}


Yorumlar

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir