Otsu's Thresholding-Algorithmus
The snippet can be accessed without any authentication.
Authored by
Bökelmann, Stephan
otsu.c 2.87 KiB
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/**
* @brief Berechnet das Histogramm eines Graustufenbildes.
*
* @param image Zeiger auf das Bild.
* @param width Breite des Bildes.
* @param height Höhe des Bildes.
* @param histogram Array zur Speicherung des Histogramms (256 Werte).
*/
void calculateHistogram(unsigned char* image, int width, int height, int* histogram) {
for (int i = 0; i < 256; i++) {
histogram[i] = 0;
}
for (int i = 0; i < width * height; i++) {
histogram[image[i]]++;
}
}
/**
* @brief Führt Otsu's Thresholding auf einem Graustufenbild durch.
*
* @param image Zeiger auf das Bild.
* @param width Breite des Bildes.
* @param height Höhe des Bildes.
* @return Der optimale Schwellenwert.
*/
int otsuThreshold(unsigned char* image, int width, int height) {
int histogram[256];
calculateHistogram(image, width, height, histogram);
int total = width * height;
float sum = 0;
for (int t = 0; t < 256; t++) {
sum += t * histogram[t];
}
float sumB = 0;
int wB = 0;
int wF = 0;
float maxVariance = 0;
int threshold = 0;
for (int t = 0; t < 256; t++) {
wB += histogram[t];
if (wB == 0) {
continue;
}
wF = total - wB;
if (wF == 0) {
break;
}
sumB += (float)(t * histogram[t]);
float mB = sumB / wB;
float mF = (sum - sumB) / wF;
float variance = (float)wB * (float)wF * (mB - mF) * (mB - mF);
if (variance > maxVariance) {
maxVariance = variance;
threshold = t;
}
}
return threshold;
}
/**
* @brief Segmentiert ein Bild basierend auf einem Schwellenwert.
*
* @param image Zeiger auf das Bild.
* @param width Breite des Bildes.
* @param height Höhe des Bildes.
* @param threshold Der Schwellenwert.
*/
void segmentImage(unsigned char* image, int width, int height, int threshold) {
for (int i = 0; i < width * height; i++) {
image[i] = (image[i] > threshold) ? 255 : 0;
}
}
int main() {
// Beispielbild (Graustufenbild)
unsigned char image[] = {
52, 55, 61, 59, 79, 61, 76, 61,
62, 59, 55, 104, 94, 85, 59, 71,
63, 65, 66, 113, 144, 104, 63, 72,
64, 70, 70, 126, 154, 109, 71, 69,
67, 73, 68, 106, 122, 88, 68, 68,
68, 79, 60, 70, 77, 66, 58, 75,
69, 85, 64, 58, 55, 61, 65, 83,
70, 87, 69, 68, 65, 73, 78, 90
};
int width = 8;
int height = 8;
int threshold = otsuThreshold(image, width, height);
printf("Optimaler Schwellenwert: %d\n", threshold);
segmentImage(image, width, height, threshold);
printf("Segmentiertes Bild:\n");
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
printf("%d ", image[i * width + j]);
}
printf("\n");
}
return 0;
}
Please register or sign in to comment