0
我試圖使用Otsu的方法來計算閾值。示例圖像是8位,灰度,bmp文件。Otsu閾值
直方圖用於通過以下產生的圖像:
/* INITIALIZE ARRAYS */
for(int i = 0; i < 255; i++) occurrence[i] = 0;
for(int i = 0; i < 255; i++) histogram[i] = 0;
/* START AT BEGINNING OF RASTER DATA */
fseek(input_img, (54 + 4 * color_number), SEEK_SET);
/* READ RASTER DATA */
for(int r = 0; r <= original_img.rows - 1; r++) {
for(int c = 0; c <= original_img.cols -1; c++) {
fread(p_char, sizeof(char), 1, input_img);
pixel_value = *p_char;
/* COUNT OCCURRENCES OF PIXEL VALUE */
occurrence[pixel_value] = occurrence[pixel_value] + 1;
total_pixels++;
}
}
for(int i = 0; i <= 255; i++) {
/* TAKES NUMBER OF OCCURRENCES OF A PARTICULAR PIXEL
* AND DIVIDES BY THE TOTAL NUMBER OF PIXELS YIELDING
* A RATIO */
histogram[i] = (float) occurrence[i]/(float) total_pixels;
}
直方圖然後被傳遞在主要起作用otsu_method
:
threshold_value = otsu_method(histogram, total_pixels);
功能otsu_method
:
int otsu_method(float *histogram, long int total_pixels) {
double omega[256], myu[256];
double max_sigma, sigma[256];
int threshold;
omega[0] = histogram[0];
myu[0] = 0.0;
for(int i = 1; i < 256; i++) {
omega[i] = omega[i - 1] + histogram[i];
myu[i] = myu[i - 1] + i * histogram[i];
}
threshold = 0;
max_sigma = 0.0;
for(int i = 0; i < 255; i++) {
if(omega[i] != 0.0 && omega[i] != 1.0)
sigma[i] = pow(myu[255] * omega[i], 2)/(omega[i] * (1.0 - omega[i]));
else
sigma[i] = 0.0;
if(sigma[i] > max_sigma) {
max_sigma = sigma[i];
threshold = i;
}
}
printf("Threshold value: %d\n", threshold);
return threshold;
}
而基於二值化圖像閾值:
void threshold_image(FILE* input_file, FILE* output_file, unsigned long vector_size, int threshold_value) {
unsigned char* p_char;
unsigned char dummy;
struct_img binary_img;
unsigned char* binary_data;
dummy = '0';
p_char = &dummy;
binary_img.data = malloc(vector_size * sizeof(char));
if(binary_img.data == NULL) printf("Failed to malloc binary_img.data\n");
binary_data = binary_img.data;
/* CONVERT PIXEL TO BLACK AND WHITE BASED ON THRESHOLD VALUE */
for(int i = 0; i < vector_size - 1; i++) {
fread(p_char, sizeof(char), 1, input_file);
if(*p_char < threshold_value) *(binary_data + i) = 0;
else *(binary_data + i) = 255;
fwrite((binary_data + i), sizeof(char), 1, output_file);
}
/* FREE ALLOCATED MEMORY */
free(binary_data);
}
程序輸出:
Reading file 512gr.bmp
Width: 512
Height: 512
File size: 263222
# Colors: 256
Vector size: 262144
Total number of pixels: 262144
Threshold value: 244
我覺得244是不是正確計算的閾值,因爲當所有像素功能threshold_image值化圖像轉換爲黑色。
如果我跳過otsu_method
並從用戶輸入函數threshold_image
中獲得閾值,可以正常工作。
功能otsu_method
是複製粘貼的代碼,因此我對變量或條件並不清楚。 我正在學習圖像處理,並試圖找出基本知識。任何關於Otsu算法的信息和關於我的代碼的任何反饋都會有所幫助。