Created
November 13, 2016 18:36
-
-
Save dejuata/130f2ac8acd5e11dffdc12dbe47477ec to your computer and use it in GitHub Desktop.
Algoritmo de Otsu C++ Procesamiento Digital de Imagenes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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