martedì 29 aprile 2014

Visione Artificiale - Lab 5: ricerca similarità tramite istogramma

#include <opencv2\opencv.hpp>
#include <fstream>

using namespace std;
using namespace cv;

struct image{
string name; //nome
Mat3b img;   //contenuto
unsigned label;  //classe
vector<float> histo20;  //istogramma 2d
MatND histo30;   //istogramma 3d
double score;  //punteggio
//Ridefinizione operatore per confronto punteggio comparativo (funzione sort)
bool operator< (const image& altro) const { return score > altro.score;}
};

int main(){
ifstream in("input/input_files.txt");
vector<string> filenames;  //Vettore nomi immagini
vector<unsigned> labels;  //Vettore classi immagini
int nBin = 16;  //Numero bin istogramma 2D
string name_query = "input/query/3.jpg";
vector<image> dataset;

//Caricamento nome e classe delle immagini dal file .txt
while(in.good()){
string line;
//Lettura linea: nome + classe dell'immagine
getline(in, line);
if(line.empty())
continue;

string filename;
unsigned type;
stringstream ss(line);
ss >> filename >> type;
cout << filename << "\t" << type << endl;

//Salvataggio nome e classe nei vettori
filenames.push_back(filename);
labels.push_back(type);

}

int channels[] = {0, 1, 2};;
    int histSize[] = {nBin, nBin, nBin};
float Rranges[] = { 0, 256 };
float Granges[] = { 0, 256 };
float Branges[] = { 0, 256 };
const float* ranges[] = { Rranges, Granges, Branges };

for(int i=0;i<filenames.size();++i){
image img_tmp;

//Salvataggio nome, tipo e matrice immagine
img_tmp.name = filenames[i];
img_tmp.label = labels[i];
stringstream ss;
ss << "input/" << filenames[i];
img_tmp.img = imread(ss.str(), 1);

img_tmp.histo20.resize(nBin*3, 0.f);

//Istogramma 2D
cout << "Calcolo istogramma 2d: " << i << endl;
for(int r=0;r<img_tmp.img.rows;++r){
for(int c=0;c<img_tmp.img.cols;++c){
img_tmp.histo20[(img_tmp.img(r,c)[0])*nBin/256]++; //B
img_tmp.histo20[nBin+(img_tmp.img(r,c)[1])*nBin/256]++; //G
img_tmp.histo20[2*nBin+(img_tmp.img(r,c)[2])*nBin/256]++; //R
}
}

//Normalizzazione  dei valori tra 0 e 1
normalize(img_tmp.histo20, img_tmp.histo20, 1.0, 0.0, NORM_L1);

//Istogramma 3D salvato in img_tmp.histo30
calcHist(&img_tmp.img, 1, channels, Mat(), img_tmp.histo30, 3, histSize, ranges, true, false);

dataset.push_back(img_tmp);
}

//Query
Mat3b query = imread(name_query);
vector<float> qhisto(3*nBin, 0.f);
MatND qhistoND;

//Istogramma 3D dell'immagine query
calcHist(&query, 1, channels, Mat(), qhistoND, 3, histSize, ranges, true, false);

for(int r=0;r<query.rows;++r){
for(int c=0;c<query.cols;++c){
qhisto[(query(r,c)[0])*nBin/256]++; //B
qhisto[nBin+(query(r,c)[1])*nBin/256]++; //G
qhisto[2*nBin+(query(r,c)[2])*nBin/256]++; //R
}
}

//Normalizzazione dei valori
normalize(qhisto, qhisto, 1.0, 0.0, NORM_L1);

//Calcolo distanza fra gli istogrammi
for(int i=0;i<dataset.size();++i){
cout << "Comparo istogramma: " << i << endl;
dataset[i].score =  compareHist(dataset[i].histo20, qhisto, CV_COMP_INTERSECT);
}

//Ordinamento immagini in base al punteggio ottenuto (ridefinito operatore)
sort(dataset.begin(), dataset.end());

//Scrittura delle immagini nella cartella di output
for(int i=0;i<dataset.size();++i){
stringstream s;
s << "output/" << i << ".jpg"; 
imwrite(s.str(), dataset[i].img);
}

waitKey();
}

Nessun commento:

Posta un commento