| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938 |
- //////////////////////////////////////////////////////////
- // imgBase.cpp : basic image processing functions
- //////////////////////////////////////////////////////////
- #include "img.h"
- #include "math.h"
- #include <fstream>
- #include "stdlib.h"
- #include "stdio.h"
- #include "string.h"
- //int _cdecl blob_ord2(const void *, const void *);
- int blob_ord2(const void *, const void *);
- // Function : img
- // Description : Object constructor
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- img::img()
- {
- dimh = 256;
- dimv = 256;
- nbpix = dimh * dimv;
- itype = TYPE_UCHAR;
- init = 0;
- }
- // Function : ~img
- // Description : Object destructor
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- img::~img()
- {
- if ((data != 0) && (init == 1))
- {
- delete [] ((unsigned char *)data);
- }
- init = 0;
- }
- // Function : Del
- // Description : Free the image data
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::Del()
- {
- if ((data != 0) && (init == 1))
- {
- delete [] ((unsigned char *)data);
- }
- init = 0;
- }
- // Function : Create
- // Description : Allocate the pixel data for the image
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs : Return 1 if OK, 0 if default
- int img::Create(int it, int dh , int dv)
- {
- itype = it;
- dimh = dh;
- dimv = dv;
- nbpix = dimh * dimv;
- if (init == 0)
- {
- // Image 8 bits unsigned
- if (itype == TYPE_UCHAR)
- {
- data = (unsigned char *) new unsigned char[nbpix];
- }
- // Image 8 bits signed
- else if (itype == TYPE_SCHAR)
- {
- data = (char *) new char[nbpix];
- }
- // Image 16 bits unsigned
- else if (itype == TYPE_USHORT)
- {
- data = (unsigned short int *) new unsigned short[nbpix];
- }
- // Image 16 bits signed
- else if (itype == TYPE_SSHORT)
- {
- data = (short int*) new short int[nbpix];
- }
- // Image 32 bits of int
- else if (itype == TYPE_INT)
- {
- data = (int *) new int[nbpix];
- }
- // Image 64 bits unsigned
- else if (itype == TYPE_ULINT)
- {
- data = (unsigned long int *) new unsigned long int[nbpix];
- }
- // Image 32 bits of floats
- else if (itype == TYPE_FLOAT)
- {
- data = (float *) new float [nbpix];
- }
- // Image of doubles
- else if (itype == TYPE_DOUBLE)
- {
- data = (double *) new double[nbpix];
- }
- }
- // Allocation problem
- if (data == 0)
- {
- init = 0;
- }
- else
- {
- init = 1;
- }
- return init;
- }
- // Function : copyto
- // Description : Copy the current image to the image img2 (Image may have different types)
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::CopyTo(img *img2)
- {
- if (itype == TYPE_UCHAR)
- {
- unsigned char *cadd;
- cadd = (unsigned char *) data;
- if (img2->itype == TYPE_UCHAR)
- {
- unsigned char *cadd2, *vcadd;
- cadd2 = (unsigned char *) img2->data;
- vcadd = (unsigned char *) memcpy(cadd2, cadd, (size_t) (nbpix * sizeof(unsigned char)));
- }
- else if (img2->itype == TYPE_USHORT)
- {
- unsigned short *sadd, *smax;
- sadd = (unsigned short *) img2->data;
- smax = sadd + img2->nbpix;
- while (sadd < smax)
- {
- *sadd = *cadd;
- cadd++;
- sadd++;
- }
- }
- }
- else if (itype == TYPE_USHORT)
- {
- unsigned short *cadd;
-
- cadd = (unsigned short *) data;
- if (img2->itype == TYPE_USHORT)
- {
- unsigned short *cadd2, *vcadd;
- cadd2 = (unsigned short *) img2->data;
- vcadd = (unsigned short *) memcpy(cadd2, cadd, (size_t) (nbpix * sizeof(unsigned short)));
- }
- else if (img2->itype == TYPE_UCHAR)
- {
- unsigned short *amax;
- unsigned char *cadd2;
- cadd2 = (unsigned char *) img2->data;
- amax = cadd + nbpix;
- while (cadd < amax)
- {
- *cadd2 = (unsigned char) *cadd;
- cadd++;
- cadd2++;
- }
- }
- }
- else if (itype == TYPE_INT)
- {
- int *cadd;
-
- cadd = (int *) data;
- if (img2->itype == TYPE_INT)
- {
- int *cadd2, *vcadd;
- cadd2 = (int *) img2->data;
- vcadd = (int *) memcpy(cadd2, cadd, (size_t) (nbpix * sizeof(char)));
- }
- else if (img2->itype == TYPE_UCHAR)
- {
- int *amax;
- unsigned char *cadd2;
- cadd2 = (unsigned char *) img2->data;
- amax = cadd + nbpix;
- while (cadd < amax)
- {
- *cadd2 = (unsigned char) *cadd;
- cadd++;
- cadd2++;
- }
- }
- else if (img2->itype == TYPE_USHORT)
- {
- int *amax;
- unsigned short *cadd2;
- cadd2 = (unsigned short *) img2->data;
- amax = cadd + nbpix;
- while (cadd < amax)
- {
- *cadd2 = (unsigned short) *cadd;
- cadd++;
- cadd2++;
- }
- }
- }
- }
- // Function : GetValue
- // Description : Get the value of a pixel
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- int img::GetValue(int x, int y)
- {
- int ng = 0;
- if ((x > 0) && (y > 0) && (x < dimh) && (y < dimv))
- {
- if ( itype == TYPE_UCHAR )
- {
- unsigned char *dadd;
- dadd = (unsigned char *) data;
- dadd += x + y * dimh;
- ng = *dadd;
- }
- else if ( itype == TYPE_USHORT )
- {
- unsigned short *dadd;
- dadd = (unsigned short *) data;
- dadd += x + y * dimh;
- ng = *dadd;
- }
- else if ( itype == TYPE_INT )
- {
- int *dadd;
- dadd = (int *) data;
- dadd += x + y * dimh;
- ng = *dadd;
- }
- }
- return(ng);
- }
- // Function : SetValue
- // Description : Set the value of a pixel
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::SetValue(int x, int y, int value)
- {
- if ((x > 0) && (y > 0) && (x < dimh) && (y < dimv))
- {
- if ( itype == TYPE_UCHAR )
- {
- unsigned char *dadd;
- dadd = (unsigned char *) data;
- dadd += x + y * dimh;
- *dadd = (unsigned char) value;
- }
- else if ( itype == TYPE_USHORT )
- {
- unsigned short *dadd;
- dadd = (unsigned short *) data;
- dadd += x + y * dimh;
- *dadd = (unsigned short) value;
- }
- else if ( itype == TYPE_INT )
- {
- int *dadd;
- dadd = (int *) data;
- dadd += x + y * dimh;
- *dadd = value;
- }
- }
- }
- // Function : Equalize
- // Description : histogram equalization
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::Equalize(int ngray)
- {
- double his[SIZEHISTO];
- double hissom = 0.0;
- int i = 0;
- int x = 0;
- int y = 0;
- int ng1 = 0;
- int ng2 = 0;
- for (i = 0; i < SIZEHISTO; i++) his[i] = 0;
- // fill the histogram
- for (x = 0; x < dimh; x++)
- {
- for (y = 0; y < dimv ;y++)
- {
- ng1 = GetValue(x, y);
-
- if ( ng1 < SIZEHISTO )
- {
- his[ng1]++;
- hissom++;
- }
- }
- }
- // cumulative histogram
- for (i = 1; i < SIZEHISTO; i++)
- {
- his[i] += his[i-1];
- }
- // normalisation
- for (i = 0; i < SIZEHISTO; i++)
- {
- his[i] = his[i] / hissom;
- }
- // Equalization
- for (x = 0; x < dimh; x++)
- {
- for (y = 0; y < dimv; y++)
- {
- ng1 = GetValue(x, y);
- if ( ng1 < SIZEHISTO )
- {
- ng2 = (int) ( ( (double) ( ngray - 1.0 ) * his[ng1] ) );
- if ( ng2 < SIZEHISTO )
- {
- SetValue(x, y, ng2);
- }
- }
- }
- }
- }
- // Function : Fill
- // Description : Fill all the image with a given gray level value
- // Creation date : 08/04
- // Author : CJ
- // Inputs : value of the gry level
- // Outputs :
- void img::Fill(int value)
- {
- if ( itype == TYPE_UCHAR )
- {
- unsigned char *dadd, *amax;
- dadd = (unsigned char *) data;
- amax = dadd + nbpix;
- while ( dadd < amax )
- {
- *dadd = (unsigned char) value;
- dadd++;
- }
- }
- else if ( itype == TYPE_USHORT )
- {
- unsigned short *dadd, *amax;
- dadd = (unsigned short *) data;
- amax = dadd + nbpix;
- while ( dadd < amax )
- {
- *dadd = (unsigned short) value;
- dadd++;
- }
- }
- else if ( itype == TYPE_INT )
- {
- int *dadd, *amax;
- dadd = (int *) data;
- amax = dadd + nbpix;
- while ( dadd < amax )
- {
- *dadd = value;
- dadd++;
- }
- }
- else if (itype == TYPE_DOUBLE)
- {
- double *dadd, *amax;
- dadd = (double *) data;
- amax = dadd + nbpix;
- while ( dadd < amax )
- {
- *dadd = value;
- dadd++;
- }
- }
- }
- //-------------------------------------------------
- // Basic functions of the mathematical morphology
- //-------------------------------------------------
- // Function : BinaryErosion
- // Description : mathematical morphological : binary erosion
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::BinaryErosion(img *res)
- {
- unsigned short *dadd0;
- unsigned short *dadd;
- unsigned short *amax;
- unsigned short *dadd2;
- int i;
- int x;
- int y;
- int offset[8];
- int dx[8];
- int dy[8];
- dx[0] = -1; dy[0] = 1;
- dx[1] = 0; dy[1] = 1;
- dx[2] = 1; dy[2] = 1;
- dx[3] = -1; dy[3] = 0;
- dx[4] = 1; dy[4] = 0;
- dx[5] = -1; dy[5] = -1;
- dx[6] = 0; dy[6] = -1;
- dx[7] = 1; dy[7] = -1;
- offset[0] = -dimh - 1;
- offset[1] = -dimh;
- offset[2] = -dimh + 1;
- offset[3] = -1;
- offset[4] = 1;
- offset[5] = dimh - 1;
- offset[6] = dimh;
- offset[7] = dimh + 1;
- CopyTo(res);
- dadd0 = (unsigned short *) data;
- dadd = dadd0;
- amax = dadd0 + nbpix;
- dadd2 = (unsigned short *) res->data;
- x = 0;
- y = dimv -1;
- while ( dadd < amax )
- {
- if ( *dadd == 1 )
- {
- for(i = 0; i < 8; i++)
- {
- // Overflow
- if ( ( ( x + dx[i] ) < 0 ) || ( ( x + dx[i] ) > ( dimh - 1 ) )
- || ( ( y + dy[i] ) < 0 ) || ( ( y + dy[i] ) > ( dimv - 1 ) ) )
- *dadd2 = 0;
- else {
- if ( *( dadd + offset[i] ) == 0 ) {
- *dadd2 = 0;
- }
- }
- }
- }
- x++;
- if ( x >= dimh )
- {
- x = 0;
- y--;
- }
- dadd++;
- dadd2++;
- }
- }
- // Function : BinaryDilatation
- // Description : mathematical morphological : binary dilatation
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::BinaryDilatation(img *res)
- {
- unsigned short *dadd0;
- unsigned short *dadd;
- unsigned short *amax;
- unsigned short *dadd2;
- int x = 0;
- int y = 0;
- int i = 0;
- int offset[9];
- int dx[8];
- int dy[8];
- offset[0] = -dimh - 1;
- offset[1] = -dimh;
- offset[2] = -dimh + 1;
- offset[3] = -1;
- offset[4] = 1;
- offset[5] = dimh - 1;
- offset[6] = dimh;
- offset[7] = dimh + 1;
- offset[8] = 0;
- dx[0] = -1; dy[0] = 1;
- dx[1] = 0; dy[1] = 1;
- dx[2] = 1; dy[2] = 1;
- dx[3] = -1; dy[3] = 0;
- dx[4] = 1; dy[4] = 0;
- dx[5] = -1; dy[5] = -1;
- dx[6] = 0; dy[6] = -1;
- dx[7] = 1; dy[7] = -1;
- dx[8] = 0; dy[8] = 0;
- CopyTo(res);
- dadd0 = (unsigned short *) data;
- dadd = dadd0 + 1 + dimh;
- amax = dadd0 + nbpix - 1 - dimh;
- dadd2 = (unsigned short *) res->data;
- dadd2+= 1 + dimh;
- x = 0;
- y = dimv - 1;
- while ( dadd < amax )
- {
- for(i = 0; i < 9; i++)
- {
- // Overflow
- if ( ( ( x + dx[i] ) < 0 ) || ( ( x + dx[i] ) > ( dimh - 1 ) )
- || ( ( y + dy[i] ) < 0 ) || ( ( y + dy[i] ) > ( dimv - 1 ) ) )
- *dadd2 = 0;
- else
- {
- if ( *( dadd + offset[i] ) == 1 )
- {
- *dadd2 = 1;
- }
- }
- }
- x++;
- if ( x > dimh - 1 )
- {
- x = 0;
- y--;
- }
- dadd++;
- dadd2++;
- }
- }
- // Function : BinaryOpening
- // Description : mathematical morphological : binary opening
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::BinaryOpening(img *tamp)
- {
- img tamp1;
- BinaryErosion(tamp);
- tamp1.Create(itype, dimh, dimv);
- tamp->CopyTo(&tamp1);
- tamp1.BinaryDilatation(tamp);
- tamp1.Del();
- }
- // Function : BinaryClosing
- // Description : mathematical morphological : binary closing
- // Creation date : 08/04
- // Author : CJ
- // Inputs :
- // Outputs :
- void img::BinaryClosing(img *tamp)
- {
- img tamp1;
- BinaryDilatation(tamp);
- tamp1.Create(itype, dimh, dimv);
- tamp->CopyTo(&tamp1);
- tamp1.BinaryErosion(tamp);
- tamp1.Del();
- }
- void img::RemplaceCouleur(int a, int b)
- {
- int *dadd, *amax;
- dadd = (int *) data;
- amax = dadd + nbpix;
- while (dadd < amax)
- {
- if (*dadd == a)
- {
- *dadd = b;
- }
- dadd++;
- }
- }
- // Fonction de comparaison pour la fonction de quick sort qsort
- int blob_ord2(const void *arg1, const void *arg2)
- {
- struct blob *bl1, *bl2;
- bl1 = (struct blob *) arg1;
- bl2 = (struct blob *) arg2;
- if (bl1->size == bl2->size)
- {
- return 0;
- }
- else if (bl1->size < bl2->size)
- {
- return 1;
- }
- else
- {
- return -1;
- }
- }
- // Function : BlobColoring
- // Description : Algorithme du Blob Coloring
- // Creation date : 05/01/2010
- // Author : CJ
- // Inputs :
- // Outputs : Renvoie -1 si on dépasse MAXBLOB
- int img::BlobColoring(blob tblob[MAXBLOB], img *img1)
- {
- int i, j, ic, lastblob, nblob, vsup, vleft;
- unsigned char *dadd, *amax;
- unsigned int *badd, *badd0, *apix, *apix2, *aleft, *asup, *bmax;
- int tlabel[MAXBLOB+1];
- // Génére une image binaire 0/1
- // seuillage(seuil);
-
- dadd = (unsigned char *) (data);
- badd0 = (unsigned int *) (img1->data);
- badd = badd0;
- amax = dadd + nbpix;
- while (dadd < amax)
- {
- *badd = *dadd;
- dadd++;
- badd++;
- }
- for (i = 0; i < MAXBLOB; i++)
- {
- tblob[i].bind = 0;
- tblob[i].used = 0;
- tblob[i].size = 0;
- tblob[i].first = 0;
- }
- for (i = 0; i < MAXBLOB+1; i++)
- {
- tlabel[i] = 0;
- }
- lastblob = 0;
- nblob = 0;
- // Point en haut à gauche
- apix = badd0;
- if (*apix != 0)
- {
- lastblob++;
- nblob++;
- *apix = lastblob;
- if (lastblob > MAXBLOB)
- {
- return -1;
- }
- tblob[lastblob].bind = lastblob;
- tblob[lastblob].used = 1;
- tblob[lastblob].size = 1;
- tblob[lastblob].first = apix;
- }
- // Première colonne
- for (i=1; i<dimh; i++)
- {
- aleft = apix++;
- if (*apix != 0)
- {
- if (*aleft == 0)
- {
- lastblob++;
- nblob++;
- *apix = lastblob;
- if (lastblob > MAXBLOB)
- {
- return -1;
- }
- tblob[lastblob].bind = lastblob;
- tblob[lastblob].used = 1;
- tblob[lastblob].size = 1;
- tblob[lastblob].first = apix;
- }
- else
- {
- *apix = *aleft;
- tblob[*apix].size++;
- }
- }
- }
- asup = apix - dimh;
- // Colonne 1 à dimv
- for (i = 1; i < dimv; i++)
- {
- aleft = apix++;
- asup++;
- // Première colonne
- if (*apix != 0)
- {
- if (*asup == 0)
- {
- lastblob++;
- nblob++;
- *apix = lastblob;
- if (lastblob > MAXBLOB)
- {
- return -1;
- }
- tblob[lastblob].bind = lastblob;
- tblob[lastblob].used = 1;
- tblob[lastblob].size = 1;
- tblob[lastblob].first = apix;
- }
- else
- {
- *apix = *asup;
- tblob[*apix].size++;
- }
- }
- // Colonne 1 à dimh
- for (ic = 1 ;ic < dimh ; ic++)
- {
- aleft = apix++;
- asup++;
- if (*apix != 0)
- {
- if (*aleft == 0)
- { // case left == 0
- if (*asup == 0)
- {
- lastblob++; nblob++;
- *apix = lastblob;
- if (lastblob > MAXBLOB)
- {
- return -1;
- }
- tblob[lastblob].bind = lastblob;
- tblob[lastblob].used = 1;
- tblob[lastblob].size = 1;
- tblob[lastblob].first = apix;
- }
- else
- {
- *apix = *asup;
- tblob[*apix].size++;
- }
- }
- else
- { // case left != 0
- *apix = *aleft;
- tblob[*apix].size++;
- if ((*asup != 0) && (*asup != *aleft))
- { // fusion
- nblob--;
- vsup = *asup;
- vleft = *aleft;
- if (tblob[vleft].size < tblob[vsup].size)
- {
- tblob[vsup].size += tblob[vleft].size;
- tblob[vleft].used = 0;
- apix2 = tblob[vleft].first;
- while (apix2 <= apix)
- {
- if (*apix2 == (unsigned int) vleft) *apix2 = (int) vsup;
- apix2++;
- }
- }
- else
- {
- tblob[vleft].size += tblob[vsup].size;
- tblob[vsup].used = 0;
- apix2 = tblob[vsup].first;
- while (apix2 <= apix)
- {
- if (*apix2 == (unsigned int) vsup) *apix2 = vleft;
- apix2++;
- }
- }
- }
- }
- }
- }
- }
- // Tri des blobs par taille
- qsort((char *)tblob, lastblob + 1, sizeof(blob), blob_ord2);
- if (nblob > MAXBLOB)
- {
- return -1;
- }
- j = 0;
- for (i = 0; i <= lastblob; i++)
- {
- if (tblob[i].used == 1)
- {
- tlabel[tblob[i].bind] = j++;
- }
- }
- // recoloriage (en tenant compte des blobs utilisés)
- badd = badd0;
- bmax = badd + nbpix;
- while (badd < bmax)
- {
- if ((*badd != 0) && (*badd < MAXBLOB))
- {
- *badd = 1 + tlabel[*badd];
- }
- badd++;
- }
- return (nblob);
- }
- // Renvoie la surface du blob d'indice nblob
- // L'image des blobs est en int
- long img::GetBlobSize(int nblob)
- {
- unsigned int *dadd, *amax;
- long sblob;
- sblob = 0;
- dadd = (unsigned int *) data;
- amax = dadd + nbpix;
- while (dadd < amax)
- {
- if (*dadd == (unsigned int) nblob)
- {
- sblob++;
- }
- dadd++;
- }
- return (sblob);
- }
- void img::SaveImgAsRaw()
- {
- std::ofstream ofs( "C:\\Img.raw", std::ios_base::out | std::ios_base::binary );
- if ( ofs.good() )
- {
- ofs.write( (char*) data, nbpix );
- ofs.close();
- }
- }
|