Skip to content

Commit

Permalink
otsu finished
Browse files Browse the repository at this point in the history
  • Loading branch information
Lise-Giraud committed Oct 25, 2020
1 parent e28933d commit 29b2022
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 58 deletions.
53 changes: 52 additions & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,26 @@
#include "pixel_operations.h"
#include "display.h"
#include "grayscale.h"
#include "otsu.h"

//Initializong functions
void init_sdl();
SDL_Surface* load_image(char *path);
SDL_Surface* display_image(SDL_Surface *img);
void grayscale (SDL_Surface* image_surface);
void wait_for_keypressed();
int mean(unsigned int *histo, int start, int end);
int sum(unsigned int *histo, int start, int end);
void histo(unsigned int histo[256], unsigned w, unsigned h,
SDL_Surface* image_surface);
int otsu(unsigned int histo[256], unsigned w, unsigned h);
void binarization(unsigned int w, unsigned int h, char binarization[w][h],
int final_t, SDL_Surface* image_surface);
void SDL_FreeSurface(SDL_Surface *surface);

/**
*Main function: use all functions initialized above to display an image and convert it into grayscale
*Main function: use all functions initialized above to display an image and convert it into grayscale.
*Then, it prints the binarization matrice of the given image and display the binarized image.
*/
int main()
{
Expand Down Expand Up @@ -51,6 +60,48 @@ int main()

wait_for_keypressed();

int w = image_surface->w;
int h = image_surface->h;

int histo[256];
histo(histo, w, h, image_surface);

int threshold;
threshold = otsu(histo, w, h);

char binarization[w][h];
binarization(w, h, binarization, threshold, image_surface);

//print the matrix of the binarized image.
printf("binarization: ");
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
printf("%d", binarization[i][j]);
}
printf("\n");
}

//display the binarized image.
Uint8 gray;
for (int i = 0; i <w; i++)
{
for (int j = 0; j < h; j++)
{
Uint32 pixel = get_pixel(image_surface, i, j);
SDL_GetRGB(pixel, image_surface->format, &gray, &gray,
&gray);
pixel = SDL_MapRGB(image_surface->format, gray*255,
gray*255, gray*255);
put_pixel(image_surface, i, j, pixel);
}
}

update_surface(screen_surface, image_surface);

wait_for_keypressed();

SDL_FreeSurface(image_surface);
SDL_FreeSurface(screen_surface);

Expand Down
164 changes: 108 additions & 56 deletions otsu.c
Original file line number Diff line number Diff line change
@@ -1,84 +1,136 @@
#include <stdio.h>
#include <math.h>
#include "display.h"
/**
*Author: Lise Giraud and Valentin Chassignol
*Date: 24/10/2020
*File's name : otsu.c
*/

#include <err.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "pixel_operations.h"
#include "display.h"
#include "grayscale.h"



/**
*Calculation of the median in the histogram between start and end values.
*
*@param histo is the histogram of grayscale in a given image.
*@param start is where to start to calculate the median.
*@param end is where to end to calculate the median.
*
*@return the median value between start and end in the histogram.
*/
int mean(unsigned int *histo, int start, int end) {
return histo[end - start];
}



void otsu_threshold(SDL_Surface* image_surface, int w, int h, char binarization[w][h])
/**
*Calculate the sum between start and end (end excluded) of the histogram.
*
*@param *histo is the histogram of grayscale in a given image.
*@param start is where to start the calculus.
*@param end is where to end the calculus (end is excluded).
*
*@return the sum of all the values between start and end.
*/
int sum(unsigned int *histo, int start, int end) {
int sum = 0;
for (int i = start; i < end; i++)
sum += (int) histo[i];
return sum;
}


/**
*Make the grayscale histogram of a given image.
*
*@param histo is the histogram to complete.
*@param w is the weight of the image.
*@param h is the height of the image.
*@param image_surface is the given image to make histogram.
*/
void histo(unsigned int histo[256], unsigned w, unsigned h,
SDL_Surface* image_surface)
{
int hist[256];
Uint8 average;

Uint8 gray;

//Histogram
for (int i = 0; i < 256; i++)
hist[i]=0;
Uint8 gray;

for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
Uint32 pixel = get_pixel(image_surface, i, j);
SDL_GetRGB(pixel, image_surface->format,
SDL_GetRGB(pixel, image_surface->format,
&gray, &gray, &gray);
hist[gray] += 1;
hist[gray] += 1;
}
}

//Probability density
double prob[256];
for (int i = 0; i < 256; i++)
{
prob[i] = hist[i] / (h*w);
}


//omega and mu generation
double omega[256];
omega[0] = prob[0];
double mu[256];
mu[0] = 0.0;
for (int i = 1; i < 256; i++)
{
omega[i] = omega[i-1] + prob[i];
mu[i] = mu[i-1] + i*prob[i];
}
}

//maximization of sigma -> determines optimal threshold value
int threshold = 0;
double max_sigma = 0.0;
double sigma[256];

for (int i = 0; i < 255; i++)
{
if (omega[i] !=0.0 && omega[i] != 1.0)
sigma[i] = pow(mu[255]*omega[i] - mu[i], 2)/
(omega[i]*(1.0 - omega[i]));
else
sigma[i] = 0.0;
if (sigma[i] > max_sigma)
{
max_sigma = sigma[i];
threshold = i;
}
}

//binarization output

/**
*Use the otsu's method to calculate the optimal threshold of a grayscale image.
*
*@param histo is the histogram of grayscale of the image.
*@param w is the weight of the image.
*@param h is the height of the image.
*
*@return the optimal threshold.
*/
int otsu(unsigned int histo[256], unsigned w, unsigned h)
{
double final_thresh = -1.0;
int final_t = -1;
double mean_weight = 1.0 / (w * h);
for (int t = 1; t < 255; t++)
{
double wb = (double) sum(histo, 0, t) * mean_weight;
double wf = (double) sum(histo, t, 255) * mean_weight;

int mub = mean(histo, 0, t);
int muf = mean(histo, t, 255);

double value = wb * wf * (mub - muf);
value *= value;
if (value > final_thresh)
{
final_thresh = value;
final_t = t;
}
}
return final_t;
}



/**
*Complete the binarization matrice (matrice of 1 and 0).
*
*@param w is the weight of the image to binarize.
*@param h is the height of the image to binarize.
*@param binarization is the binarization matrice of the image. Must contain only 0 and 1.
*@param final_t is the optimal threshold of the image to binarize.
*@param image_surface is the image to binarize.
*/
void binarization(unsigned int w, unsigned int h, char binarization[w][h],
int final_t, SDL_Surface* image_surface)
{
Uint8 average;
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
Uint32 pixel = get_pixel(image_surface, i, j);
SDL_GetRGB(pixel, image_surface->format, &average,
SDL_GetRGB(pixel, image_surface->format, &average,
&average, &average);
if (average > threshold)
if (average > final_t)
binarization[i][j] = 1;
else
else
binarization[i][j] = 0;
}
}
}

70 changes: 69 additions & 1 deletion otsu.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,74 @@
/**
*Authors: Lise Giraud and Valentin Chassignol
*Date: 24/10/2020
*File's name: otsu.h
*/
#ifndef OTSU_H
#define OTSU_H

void ostu_threshold(SDL_Surface* image_surface, int w, int h, char binarization[w][h]);
/**
*Calculation of the median in the histogram between start and end values.
*
*@param histo is the histogram of grayscale in a given image.
*@param start is where to start to calculate the median.
*@param end is where to end to calculate the median.
*
*@return the median value between start and end in the histogram.
*/
int mean(unsigned int *histo, int start, int end);



/**
*Calculate the sum between start and end (end excluded) of the histogram.
*
*@param *histo is the histogram of grayscale in a given image.
*@param start is where to start the calculus.
*@param end is where to end the calculus (end is excluded).
*
*@return the sum of all the values between start and end.
*/
int sum(unsigned int *histo, int start, int end);



/**
*Make the grayscale histogram of a given image.
*
*@param histo is the histogram to complete.
*@param w is the weight of the image.
*@param h is the height of the image.
*@param image_surface is the given image to make histogram.
*/
void histo(unsigned int histo[256], unsigned w, unsigned h,
SDL_Surface* image_surface);



/**
*Use the otsu's method to calculate the optimal threshold of a grayscale image.
*
*@param histo is the histogram of grayscale of the image.
*@param w is the weight of the image.
*@param h is the height of the image.
*
*@return the optimal threshold.
*/
int otsu(unsigned int histo[256], unsigned w, unsigned h);



/**
*Complete the binarization matrice (matrice of 1 and 0).
*
*@param w is the weight of the image to binarize.
*@param h is the height of the image to binarize.
*@param binarization is the binarization matrice of the image. Must contain only 0 and 1.
*@param final_t is the optimal threshold of the image to binarize.
*@param image_surface is the image to binarize.
*/
void binarization(unsigned int w, unsigned int h, char binarization[w][h],
int final_t, SDL_Surface* image_surface)


#endif

0 comments on commit 29b2022

Please sign in to comment.