Skip to content

Instantly share code, notes, and snippets.

@dejuata
Created November 13, 2016 18:36
Show Gist options
  • Save dejuata/130f2ac8acd5e11dffdc12dbe47477ec to your computer and use it in GitHub Desktop.
Save dejuata/130f2ac8acd5e11dffdc12dbe47477ec to your computer and use it in GitHub Desktop.
Algoritmo de Otsu C++ Procesamiento Digital de Imagenes
// Information -> http://www.labbookpages.co.uk/software/imgProc/otsuThreshold.html
#include <cstdlib>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <algorithm> // std::min_element, std::max_element
#include <math.h>
#define length(x) (sizeof(x)/sizeof(x[0]))
using namespace std;
double histograma[6] = {8,7,2,6,9,4};
double accHistogramaBack[6];
double accHistogramaFore[6];
double weightBack[6];
double weightFore[6];
double meanBack[6];
double meanFore[6];
double varianceBack[6];
double varianceFore[6];
double classVariance[6];
double sizeImage = 36;
// Funcion que calcula el histograma acumulado
void calculateAccHistograma()
{
int sumB = 0;
int sumF = 0;
accHistogramaBack[0] = 0;
for(int i = 1; i < length(histograma); i++)
{
sumB += histograma[i-1];
accHistogramaBack[i] = sumB;
}
for(int i = length(histograma) - 1; i >= 0 ; i--)
{
sumF += histograma[i];
accHistogramaFore[i] = sumF;
}
}
// Funcion que calcula el promedio y lo almacena en un array
void calculateWeight()
{
double sumB = 0;
double sumF = 0;
weightBack[0] = sumB;
for(int i = 1; i < length(histograma); i++)
{
sumB += histograma[i-1] / sizeImage;
weightBack[i] = sumB;
}
for(int i = length(histograma) - 1; i >= 0 ; i--)
{
sumF += histograma[i] / sizeImage;
weightFore[i] = sumF;
}
}
// Funcion que calcula la media
void calculateMean()
{
int sumB = 0;
int sumF = 0;
meanBack[0] = 0;
for(int i = 1; i < length(histograma); i++)
{
sumB += (i - 1) * histograma[i - 1];
meanBack[i] = sumB / accHistogramaBack[i];
}
for(int i = length(histograma) - 1; i >= 0 ; i--)
{
sumF += i * histograma[i];
meanFore[i] = sumF / accHistogramaFore[i];
}
}
// Funcion que calcula la varianza
void calculateVariance()
{
int countB = 0;
int countF = length(histograma);
double sumB;
double sumF;
varianceBack[0] = 0;
for(int i = 1; i < length(histograma); i++)
{
sumB = 0;
countB = countB + 1;
for(int j = 0; j < countB; j++)
{
sumB += pow(j - meanBack[i] , 2) * histograma[j];
}
varianceBack[i] = sumB / accHistogramaBack[i];
}
for(int i = length(histograma) - 1; i >= 0 ; i--)
{
sumF = 0;
countF = countF - 1;//9-8
for(int j = length(histograma) - 1; j >= countF; j--)
{
sumF += pow(j - meanFore[i] , 2) * histograma[j];
}
varianceFore[i] = sumF / accHistogramaFore[i];
}
}
void calculateClassVariance()
{
for(int i = 0; i < length(histograma); i++)
{
classVariance[i] = (weightBack[i] * varianceBack[i]) + (weightFore[i] * varianceFore[i]);
}
}
void result()
{
double minClassVariance;
double threshold;
calculateAccHistograma();
calculateWeight();
calculateMean();
calculateVariance();
calculateClassVariance();
cout<<"Background"<<endl;
for(int i = 0; i < length(histograma); i++)
{
cout<<"Weight: "<<weightBack[i]<<" "<<"Mean: "<<meanBack[i]<<" "<<"Variance: "<<varianceBack[i]<<" "<<endl;
}
cout<<endl;
cout<<"Foreground"<<endl;
for(int i = 0; i < length(histograma); i++)
{
cout<<"Weight: "<<weightFore[i]<<" "<<"Mean: "<<meanFore[i]<<" "<<"Variance: "<<varianceFore[i]<<" "<<endl;
}
cout<<endl;
cout<<"Within Class Variance"<<endl;
for(int i = 0; i < length(histograma); i++)
{
cout<<classVariance[i]<<endl;
}
// hallar la varianza minima
minClassVariance = *std::min_element(classVariance,classVariance+length(classVariance));
// Hallar el indice de la varianza minima, para poder asociarlos con el pixel que seria el threshold
for(int i = 0; i < length(classVariance); i++)
{
if(classVariance[i] == minClassVariance)threshold = i;
}
cout<<endl<<"Min Class Variance: "<<minClassVariance<<endl<<"Threshold: "<<threshold<<endl;
}
int main(int argc, char** argv) {
result();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment