void verif_minutie(ImagePNG &originale,string numero)//enleve le surplus de bifurc { const unsigned height=originale.height(); const unsigned width=originale.width(); for (unsigned i=9;i<height-9;i++) { for (unsigned j=9;j<width-9;j++) { if (originale[i][j]==PIXEL_BLUE) { if (!compteur_loin(originale,i,j)) { for (unsigned k=i-9;k<i+9;k++) { for (unsigned f=j-9;f<j+9;f++) { if (originale[k][f]==PIXEL_BLUE) { originale[k][f]=PIXEL_BLACK; } } } } } } } originale.save("bifurcation2"+numero+".png"); }
void terminaison(ImagePNG &originale)//pas sur les bords (qu'au milieu) { int somme(0); const unsigned height=originale.height(); const unsigned width=originale.width(); for (unsigned i=8;i<height-8;i++) { for (unsigned j=8;j<width-8;j++) { if (originale[i][j]==PIXEL_BLACK) { if ((compteur_proche(originale,i,j)==1)&&verif_not_bifurc(originale,i,j)) { somme++; originale[i][j]=PIXEL_RED; (originale[i+1][j]=PIXEL_RED); (originale[i][j+1]=PIXEL_RED); (originale[i-1][j]=PIXEL_RED); (originale[i][j-1]=PIXEL_RED); (originale[i-1][j-1]=PIXEL_RED); (originale[i+1][j-1]=PIXEL_RED); (originale[i+1][j+1]=PIXEL_RED); (originale[i-1][j+1]=PIXEL_RED); } } } } originale.save("terminaison.png"); }
void bifurcation(ImagePNG &originale, string numero)//calcul des bifurcations { const unsigned height=originale.height(); const unsigned width=originale.width(); int somme(0); for (unsigned i=1;i<height-1;i++) { for (unsigned j=1;j<width-1;j++) { if (originale[i][j]==PIXEL_BLACK) { if (compteur_proche(originale,i,j)==3) { originale[i][j]=PIXEL_BLUE; somme++; /* (originale[i+1][j]=PIXEL_BLUE); (originale[i][j+1]=PIXEL_BLUE); (originale[i-1][j]=PIXEL_BLUE); (originale[i][j-1]=PIXEL_BLUE); (originale[i-1][j-1]=PIXEL_BLUE); (originale[i+1][j-1]=PIXEL_BLUE); (originale[i+1][j+1]=PIXEL_BLUE); (originale[i-1][j+1]=PIXEL_BLUE); */ } } } } originale.save("bifurcation"+numero+".png"); }
void filtre (ImagePNG &gg, string numero)//filtre moyenneur { ImagePNG originale; originale=gg; int gris1,gris2,gris3,gris4,gris5,gris6,gris7,gris8,gris9,total; for (unsigned i=1;i<originale.height()-1;i++) { for (unsigned j=1;j<originale.width()-1;j++) { gris1=(originale[i+1][j].red()+originale[i+1][j].blue()+originale[i+1][j].green())/3; gris2=(originale[i-1][j].red()+originale[i-1][j].blue()+originale[i-1][j].green())/3; gris3=(originale[i][j-1].red()+originale[i][j-1].blue()+originale[i][j-1].green())/3; gris4=(originale[i][j+1].red()+originale[i][j+1].blue()+originale[i][j+1].green())/3; gris5=(originale[i-1][j-1].red()+originale[i-1][j-1].blue()+originale[i-1][j-1].green())/3; gris6=(originale[i+1][j-1].red()+originale[i+1][j-1].blue()+originale[i+1][j-1].green())/3; gris7=(originale[i+1][j+1].red()+originale[i+1][j+1].blue()+originale[i+1][j+1].green())/3; gris8=(originale[i-1][j+1].red()+originale[i-1][j+1].blue()+originale[i-1][j+1].green())/3; gris9=(originale[i][j].red()+originale[i][j].blue()+originale[i][j].green())/3; total=(gris1+gris2+gris3+gris4+gris5+gris6+gris7+gris8+gris9)/9; if (total<180) { gg[i][j]=PIXEL_BLACK; } else { gg[i][j]=PIXEL_WHITE; } } } gg.save("filtre"+numero+".png"); }
void Translation::run(vector<string> pArgParam,string input, string output){ unused(pArgParam); ImagePNG* img = new ImagePNG(); img->load(input); double start = Data::get_time(); cout << &img << endl; translation(img,atoi(pArgParam[0].c_str()),atoi(pArgParam[1].c_str()), new Color(0,0,0,255)); if (Data::CHRONO) cout << description<<" effectue en " << 1000*(Data::get_time() - start)<<" ms"<<endl; img->save(output); }
void Difference::run(vector<string> pArgParam,string input, string output){ unused(pArgParam); ImagePNG* img = new ImagePNG(); img->load(input); ImagePNG* img2 = new ImagePNG(); img2->load(pArgParam[0]); double start = Data::get_time(); difference(img, img2); if (Data::CHRONO) cout << description<<" effectue en " << 1000*(Data::get_time() - start)<<" ms"<<endl; img->save(output); }
int main(int argc,char** argv) { (void) argc; string nom_image; nom_image=argv[1];//nom de l'image (adresse) string numero,numero2; numero=argv[2];//premiere ou seconde image a comparer (pour sauvegarder le ratio) numero2=argv[3];//le type de filtre voulu ImagePNG img; img.load(nom_image); float largeur; float hauteur; largeur=max_largeur(img)-min_largeur(img); hauteur=max_hauteur(img)-min_hauteur(img); unsigned minl,minh,maxl,maxh; minl=min_largeur(img); minh=min_hauteur(img); maxl=max_largeur(img); maxh=max_hauteur(img); //niveau_de_gris(img); binarise(img,numero); img.load("binarise"+numero+".png"); if (numero2=="1") { filtre_median(img,numero); img.load("filtre_median"+numero+".png"); } if (numero2=="2") { filtre(img,numero); img.load("filtre"+numero+".png"); } squelette(img,numero); img.load("squelette"+numero+".png"); bifurcation(img,numero); img.load("bifurcation"+numero+".png"); verif_minutie(img,numero); img.load("bifurcation2"+numero+".png"); ecriture(img,largeur,hauteur,minh,minl,maxl,maxh,numero);//2=bb return 0; }
unsigned min_largeur( ImagePNG &originale)//calcule le xmin (cf rapport) { // remplace tous les pixels par des pixels blancs const unsigned height=originale.height(); const unsigned width=originale.width(); unsigned min(width); for (unsigned i=1;i<height-1;i++) { for (unsigned j=1;j<width-1;j++) { if (compteur_black(originale,i,j)>6) { if (min>j) { min=j; } } } } return min; }
void squelette( ImagePNG &copie, string numero)//applique toutes les conditions precedentes pour squelettiser { const unsigned height=copie.height(); const unsigned width=copie.width(); for (unsigned i=1;i<height-1;i++) { for (unsigned j=1;j<width-1;j++) { if (copie[i][j]!=PIXEL_WHITE) { if ( (premiere_conditions(copie,i,j))&&(deuxieme_condition(copie,i,j)) && ((troisieme_condition(copie,i,j))||(quatrieme_condition(copie,i,j))) && ((cinquieme_condition(copie,i,j))||(sixieme_condition(copie,i,j)))) { copie[i][j]=PIXEL_WHITE; } } } } copie.save("squelette"+numero+".png"); }
unsigned max_hauteur(ImagePNG &originale)//calcule le ymax (cf rapport) { // remplace tous les pixels par des pixels blancs const unsigned height=originale.height(); const unsigned width=originale.width(); unsigned max(0); for (unsigned i=height-2;i>1;i--) { for (unsigned j=width-2;j>1;j--) { if (compteur_black(originale,i,j)>6) { if(max<i) { max=i; } } } } return max; }
void filtre_median(ImagePNG &originale,string numero)//filtre median { int tab[8]; ImagePNG copie=originale; int gris1,gris2,gris3,gris4,gris5,gris6,gris7,gris8; for (unsigned i=1;i<originale.height()-1;i++) { for (unsigned j=1;j<originale.width()-1;j++) { gris1=(copie[i+1][j].red()+copie[i+1][j].blue()+copie[i+1][j].green())/3; gris2=(copie[i-1][j].red()+copie[i-1][j].blue()+copie[i-1][j].green())/3; gris3=(copie[i][j-1].red()+copie[i][j-1].blue()+copie[i][j-1].green())/3; gris4=(copie[i][j+1].red()+copie[i][j+1].blue()+copie[i][j+1].green())/3; gris5=(copie[i-1][j-1].red()+copie[i-1][j-1].blue()+copie[i-1][j-1].green())/3; gris6=(copie[i+1][j-1].red()+copie[i+1][j-1].blue()+copie[i+1][j-1].green())/3; gris7=(copie[i+1][j+1].red()+copie[i+1][j+1].blue()+copie[i+1][j+1].green())/3; gris8=(copie[i-1][j+1].red()+copie[i-1][j+1].blue()+copie[i-1][j+1].green())/3; tab[0]=gris1; tab[1]=gris2; tab[2]=gris3; tab[3]=gris4; tab[4]=gris5; tab[5]=gris6; tab[6]=gris7; tab[7]=gris8; tab[8]=(copie[i][j].red()+copie[i][j].blue()+copie[i][j].green())/3; tri_a_bulle(tab,8); if(tab[5]<120) { originale[i][j]=PIXEL_BLACK; } else originale[i][j]=PIXEL_WHITE; } } originale.save("filtre_median"+numero+".png"); }
void ecriture(ImagePNG &originale,float largeur, float hauteur, unsigned min_hauteur, unsigned min_largeur,unsigned max_largeur,unsigned max_hauteur,string numero)//ecris dans un fichier texte la signature de l'empreinte { string nom,nom_complet; int compteur(0); nom="ratio"+numero; nom_complet="touch "+nom+".txt"; system(nom_complet.c_str()); ofstream fichier(nom+".txt"); const unsigned height=originale.height(); const unsigned width=originale.width(); for (unsigned i=0;i<height;i++) { for (unsigned j=0;j<width;j++) { if ((originale[i][j]==PIXEL_BLUE))//+(originale[i][j]==PIXEL_RED)) { compteur++; fichier<<round(((i-min_hauteur)/hauteur)*1000)/1000<<" "<<round(((j-min_largeur)/largeur)*1000)/1000<<" "<<round(((max_hauteur-i)/hauteur)*1000)/1000<<" "<<round(((max_largeur-j)/largeur)*1000)/1000<<endl; } } } }
//------------------------------------------------------------------------------ void QuadTree::importer(const ImagePNG & img) { /*On récupère la largeur de l'image sur laquelle on travaille utile pour savoir si on peut extraire la couleur des pixels. Dans le cas de base length = 2 correspond a une image de 4 pixels */ int length = img.hauteur(); //On créé des QuadTree qui vont être embranchés QuadTree *NW = new QuadTree; QuadTree *NE = new QuadTree; QuadTree *SE = new QuadTree; QuadTree *SW = new QuadTree; //Cas de base on travaille sur une image de 4 pixels if(length == 2){ /* On crée la liaison entre les différents noeuds, ici les fils du QuadTree créé pointent sur les racines des QuadTree créés */ _racine.fils[0] = &NW->_racine; _racine.fils[1] = &SW->_racine; _racine.fils[2] = &NE->_racine; _racine.fils[3] = &SE->_racine; // On créé la liaison dans l'autre sens de la précédente, on fait pointer les QuadTree créés sur leur père NW->_racine.pere = &(_racine); //On remplit la couleur des Quadtree, ceux si n'ont pas de fils il s'agit de feuilles NW->_racine.rvb = img.lirePixel(0,0); NE->_racine.pere = &(_racine); NE->_racine.rvb = img.lirePixel(1,0); SE->_racine.pere = &(_racine); SE->_racine.rvb = img.lirePixel(1,1); SW->_racine.pere = &(_racine); SW->_racine.rvb = img.lirePixel(0,1); //On stocke la couleur des 4 feuilles dans une vecteur vector<Couleur> vecCol; for(int i = 0; i <= 3; ++i){ vecCol.push_back(_racine.fils[i]->rvb); } //On remplit le noeud père des feuilles avec la couleur moyenne de celles-ci _racine.rvb = moyenne(vecCol); //Mise à jour de la taille, ici cas de base, on a 4 feuilles _taille = 4; } else{ //Découpage de l'image en 4 sous images de taille égale ImagePNG image0 = ImagePNG(length/2,length/2); ImagePNG image1 = ImagePNG(length/2,length/2); ImagePNG image2 = ImagePNG(length/2,length/2); ImagePNG image3 = ImagePNG(length/2,length/2); //Remplissage des images crées for(int y = 0; y <= length/2 -1; ++y){ for(int x = 0; x <= length/2 -1; ++x){ image0.ecrirePixel(x,y,img.lirePixel(x,y)); image1.ecrirePixel(x,y,img.lirePixel(x,y+length/2)); image2.ecrirePixel(x,y,img.lirePixel(x+length/2,y)); image3.ecrirePixel(x,y,img.lirePixel(x+length/2,y+length/2)); } } /* On crée la liaison entre les différents noeuds, ici les fils du QuadTree créé pointent sur les racines des QuadTree créés */ _racine.fils[0] = &(NW->_racine); //On créé la liaison dans l'autre sens, pointant sur le père NW->_racine.pere = &_racine; //On importe la nouvelle image créé sur le nouveau quadtree (récursivité) NW->importer(image0); _racine.fils[1] = &(SW->_racine); SW->_racine.pere = &_racine; SW->importer(image1); _racine.fils[2] = &(NE->_racine); NE->_racine.pere = &_racine; NE->importer(image2); _racine.fils[3] = &(SE->_racine); SE->_racine.pere = &_racine; SE->importer(image3); //On stocke la couleur des 4 feuilles dans une vecteur vector<Couleur> vecCol; for(int i = 0; i <= 3; ++i){ vecCol.push_back(_racine.fils[i]->rvb); } //Mise à jour couleur moyenne du noeud _racine.rvb = moyenne(vecCol); //Mise à jour de la taille, somme des tailles des fils du noeud _taille = (NW->_taille) + (NE->_taille) + (SW->_taille) + (SE->_taille); //Compression sans perte qu'on met en commentaire (pas ici) /* for(int i = 0; i <= 2; ++i){ if(diff_lum(_racine.fils[i]->rvb, _racine.fils[i+1]->rvb) == 0){ flag = false; break; } } if(flag == true){ _racine.rvb = _racine.fils[0]->rvb; }else{ _racine.rvb = moyenne(vecCol); }*/ } }