#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