00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <math.h>
00035 #include <time.h>
00036
00037 #include "mdmath.h"
00038 #include "miscIPOL.h"
00039 #include "colorfilteringIPOL.h"
00040
00041
00060 struct infoPixel {
00061 float R, G, B;
00062
00063
00064 float AA, BB, CC, DD;
00065
00066 float Rcm, Gcm, Bcm;
00067
00068
00069 unsigned char processed;
00070
00071
00072 unsigned char projected;
00073
00074
00075 unsigned char ignore;
00076
00077 };
00078
00079
00088 struct RGBpoint {
00089 float R, G, B;
00090 int idpix;
00091 struct RGBpoint *next, *nextneigh;
00092
00093 };
00094
00100 struct RGBbin {
00101 struct RGBpoint *first, *last;
00102
00103 };
00104
00119 struct infoProjection {
00120 float Rp, Gp, Bp;
00121 float A, B, C, D;
00122 float weight1, weight2;
00123
00124
00125
00126 float Rcm, Gcm, Bcm;
00127
00128 };
00129
00161 int initialize_colorfiltering_data(unsigned char *R, unsigned char *G,
00162 unsigned char *B, int w, int h,
00163 struct RGBbin ****checkOut,
00164 struct infoPixel **infopixOut,
00165 struct infoPixel **infopixBOut,
00166 int **repeatedRGBOut,
00167 unsigned char ignore000)
00168 {
00169 struct RGBbin ***check;
00170 struct infoPixel *infopix, *infopixB=NULL;
00171 struct RGBpoint *point;
00172 int *repeatedRGB;
00173 int iR, iG, n, nRGB;
00174
00175
00176 check=new struct RGBbin**[256];
00177 for (iR=0; iR < 256; iR++) {
00178 check[iR]=new struct RGBbin*[256];
00179 for (iG=0; iG < 256; iG++) {
00180 check[iR][iG]=new struct RGBbin[256];
00181 memset(check[iR][iG], 0, 256*sizeof(struct RGBbin));
00182 }
00183 }
00184
00185
00186 nRGB=0;
00187 infopix=new struct infoPixel[w*h];
00188 if (infopixBOut) infopixB=new struct infoPixel[w*h];
00189 for (n=0; n < w*h; n++) {
00190 infopix[n].R=(float) R[n];
00191 infopix[n].G=(float) G[n];
00192 infopix[n].B=(float) B[n];
00193 infopix[n].processed=0;
00194 infopix[n].projected=0;
00195
00196
00197 infopix[n].ignore=0;
00198 if (ignore000 && ((R[n] == 0) && (G[n] == 0) && (B[n] == 0))) {
00199 infopix[n].ignore=1;
00200 } else {
00201
00202 point=new struct RGBpoint;
00203 point->R=(float) R[n];
00204 point->G=(float) G[n];
00205 point->B=(float) B[n];
00206 point->idpix=n;
00207 point->next=NULL;
00208 if (check[R[n]][G[n]][B[n]].first == NULL) nRGB++;
00209 if (check[R[n]][G[n]][B[n]].first == NULL)
00210 check[R[n]][G[n]][B[n]].first=point;
00211 else check[R[n]][G[n]][B[n]].last->next=point;
00212 check[R[n]][G[n]][B[n]].last=point;
00213 }
00214 }
00215
00216 printf("\nNumber of colors of input image: %i\n", nRGB);
00217
00218
00219 *checkOut=check;
00220 *infopixOut=infopix;
00221 if (infopixBOut) *infopixBOut=infopixB;
00222
00223 if (repeatedRGBOut) {
00224
00225
00226
00227
00228 repeatedRGB=new int[w*h];
00229 memset(repeatedRGB, 0, w*h*sizeof(int));
00230 for (int iR=0; iR < 256; iR++)
00231 for (int iG=0; iG < 256; iG++)
00232 for (int iB=0; iB < 256; iB++) {
00233 if (check[iR][iG][iB].first) {
00234 repeatedRGB[check[iR][iG][iB].first->idpix]=1;
00235
00236 for (point=check[iR][iG][iB].first->next; point;
00237 point=point->next) {
00238 repeatedRGB[point->idpix]=0;
00239 repeatedRGB[check[iR][iG][iB].first->idpix]++;
00240
00241 }
00242 }
00243 }
00244 *repeatedRGBOut=repeatedRGB;
00245 }
00246
00247
00248 return nRGB;
00249
00250 }
00251
00252
00256 void delete_colorfiltering_data(struct RGBbin ***check,
00257 struct infoPixel *infopix,
00258 struct infoPixel *infopixB)
00259 {
00260 int iR, iG, iB;
00261 struct RGBpoint *point, *pointnext;
00262
00263 for (iR=0; iR < 256; iR++) {
00264 for (iG=0; iG < 256; iG++) {
00265 for (iB=0; iB < 256; iB++) {
00266 if (check[iR][iG][iB].first) {
00267 for (point=check[iR][iG][iB].first; point; point=pointnext) {
00268 pointnext=point->next;
00269 delete point;
00270 }
00271 }
00272 }
00273 delete[] check[iR][iG];
00274 }
00275 delete[] check[iR];
00276 }
00277 delete[] check;
00278 delete[] infopix;
00279 if (infopixB) delete[] infopixB;
00280 }
00281
00282
00304 void add_neighboursRGB(float R0, float G0, float B0, struct RGBbin ***check,
00305 int iR, int iG, int iB, int rneigh,
00306 struct RGBpoint **firstneighIn,
00307 struct RGBpoint **lastneighIn,
00308 int &nneigh, int &nneighdiff)
00309 {
00310 struct RGBpoint *firstneigh, *lastneigh;
00311 struct RGBpoint *point, *pointB;
00312 unsigned char found;
00313
00314 firstneigh=*firstneighIn;
00315 lastneigh=*lastneighIn;
00316
00317
00318 for (point=check[iR][iG][iB].first; point; point=point->next) {
00319
00320
00321 if ((fabs(point->R-R0) <= rneigh) && (fabs(point->G-G0) <= rneigh)
00322 && (fabs(point->B-B0) <= rneigh)) {
00323 found=0;
00324 if (!firstneigh) firstneigh=point;
00325 else {
00326
00327 for (pointB=check[iR][iG][iB].first;
00328 (pointB != point) && !found; pointB=pointB->next) {
00329 found=(pointB->R == point->R) &&
00330 (pointB->G == point->G) &&
00331 (pointB->B == point->B);
00332 }
00333 lastneigh->nextneigh=point;
00334 }
00335 lastneigh=point;
00336 point->nextneigh=NULL;
00337
00338 nneigh++;
00339
00340 if (!found) nneighdiff++;
00341 }
00342 }
00343
00344 *firstneighIn=firstneigh;
00345 *lastneighIn=lastneigh;
00346 }
00347
00376 struct RGBpoint *find_neighboursRGB(float R0, float G0, float B0,
00377 struct RGBbin ***check,
00378 int rneigh, int nneighmax,
00379 int &nneigh, int &nneighdiff)
00380 {
00381 struct RGBpoint *firstneigh, *lastneigh;
00382 int iR, iG, iB;
00383
00384
00385 nneigh=nneighdiff=0;
00386 firstneigh=NULL;
00387 lastneigh=NULL;
00388
00389
00390 int iR1, iR2, iG1, iG2, iB1, iB2, rn;
00391 rn=0;
00392 iR1=iR2=(int) R0;
00393 iG1=iG2=(int) G0;
00394 iB1=iB2=(int) B0;
00395
00396 do {
00397
00398 for (iB=iB1; iB <= iB2; iB++) {
00399 if ((iB >= 0) && (iB <= 255)) {
00400 if ((iB == iB1) || (iB == iB2)) {
00401 for (iR=iR1; iR <= iR2; iR++) {
00402 if ((iR >= 0) && (iR <= 255)) {
00403 for (iG=iG1; iG <= iG2; iG++) {
00404 if ((iG >= 0) && (iG <= 255)) {
00405 add_neighboursRGB(R0, G0, B0, check, iR, iG, iB, rneigh,
00406 &firstneigh, &lastneigh, nneigh,
00407 nneighdiff);
00408 }
00409 }
00410 }
00411 }
00412 } else {
00413
00414 iR=iR1;
00415 if ((iR >= 0) && (iR <= 255)) {
00416 for (iG=iG1; iG <= iG2; iG++) {
00417 if ((iG >= 0) && (iG <= 255)) {
00418 add_neighboursRGB(R0, G0, B0, check, iR, iG, iB, rneigh,
00419 &firstneigh, &lastneigh, nneigh,
00420 nneighdiff);
00421 }
00422 }
00423 }
00424 iR=iR2;
00425 if ((iR >= 0) && (iR <= 255)) {
00426 for (iG=iG1; iG <= iG2; iG++) {
00427 if ((iG >= 0) && (iG <= 255)) {
00428 add_neighboursRGB(R0, G0, B0, check, iR, iG, iB, rneigh,
00429 &firstneigh, &lastneigh, nneigh, nneighdiff);
00430 }
00431 }
00432 }
00433 iG=iG1;
00434 if ((iG >= 0) && (iG <= 255)) {
00435 for (iR=iR1+1; iR <= iR2-1; iR++) {
00436 if ((iR >= 0) && (iR <= 255)) {
00437 add_neighboursRGB(R0, G0, B0, check, iR, iG, iB, rneigh,
00438 &firstneigh, &lastneigh, nneigh,
00439 nneighdiff);
00440 }
00441 }
00442 }
00443 iG=iG2;
00444 if ((iG >= 0) && (iG <= 255)) {
00445 for (iR=iR1+1; iR <= iR2-1; iR++) {
00446 if ((iR >= 0) && (iR <= 255)) {
00447 add_neighboursRGB(R0, G0, B0, check, iR, iG, iB, rneigh,
00448 &firstneigh, &lastneigh, nneigh,
00449 nneighdiff);
00450 }
00451 }
00452 }
00453 }
00454 }
00455 }
00456
00457
00458 iR1--;
00459 if (iR1 < 0) iR1=-1;
00460 iR2++;
00461 if (iR2 > 255) iR2=256;
00462 iG1--;
00463 if (iG1 < 0) iG1=-1;
00464 iG2++;
00465 if (iG2 > 255) iG2=256;
00466 iB1--;
00467 if (iB1 < 0) iB1=-1;
00468 iB2++;
00469 if (iB2 > 255) iB2=256;
00470 rn++;
00471
00472 } while ((rn <= rneigh) && ((nneighmax <= 0) || (nneighdiff < nneighmax)));
00473
00474
00475 return firstneigh;
00476 }
00477
00478
00479
00480
00493 void project_point(float R0, float G0, float B0,
00494 float &newR, float &newG, float &newB,
00495 float Rcm, float Gcm, float Bcm,
00496 float vx, float vy, float vz,
00497 unsigned char option)
00498 {
00499 float vv[3];
00500 vv[0]=vx; vv[1]=vy; vv[2]=vz;
00501 if (option == 1) {
00502 float dp[3], lambda;
00503
00504 dp[0]=R0-Rcm;
00505 dp[1]=G0-Gcm;
00506 dp[2]=B0-Bcm;
00507 lambda=scalar_product(dp, vv);
00508 newR=Rcm+lambda*vv[0];
00509 newG=Gcm+lambda*vv[1];
00510 newB=Bcm+lambda*vv[2];
00511 } else {
00512
00513 float A, B, C, D, lambda;
00514 A=vv[0];
00515 B=vv[1];
00516 C=vv[2];
00517 D=-(A*Rcm+B*Gcm+C*Bcm);
00518 lambda=-(D+R0*A+G0*B+B0*C);
00519 newR=R0+lambda*A;
00520 newG=G0+lambda*B;
00521 newB=B0+lambda*C;
00522 }
00523 }
00524
00525
00526
00550 unsigned char get_projectionRGB(float R0, float G0, float B0,
00551 struct RGBpoint *firstneigh,
00552 struct infoProjection *infoproj,
00553 unsigned char option)
00554 {
00555 int nneigh;
00556 double Rcm, Gcm, Bcm;
00557 float newR, newG, newB;
00558 float uu[3], vv[3], ww[3];
00559 double mean[3], C[3][3], VecPs[3][3], ValPs[3];
00560 unsigned char projection_type;
00561
00562
00563 for (int i=0; i < 3; i++) mean[i]=0;
00564 for (int i=0; i < 3; i++)
00565 for (int j=0; j < 3; j++) C[i][j]=0;
00566 nneigh=0;
00567 for (struct RGBpoint *point=firstneigh; point; point=point->nextneigh) {
00568 mean[0]+=(double) point->R;
00569 mean[1]+=(double) point->G;
00570 mean[2]+=(double) point->B;
00571 C[0][0]+=((double) point->R)*((double) point->R);
00572 C[0][1]+=((double) point->R)*((double) point->G);
00573 C[0][2]+=((double) point->R)*((double) point->B);
00574 C[1][1]+=((double) point->G)*((double) point->G);
00575 C[1][2]+=((double) point->G)*((double) point->B);
00576 C[2][2]+=((double) point->B)*((double) point->B);
00577 nneigh++;
00578 }
00579 for (int i=0; i < 3; i++) mean[i]/=((double) nneigh);
00580 for (int i=0; i < 3; i++)
00581 for (int j=i; j < 3; j++)
00582 C[i][j]=(C[i][j]/(double) nneigh)-mean[i]*mean[j];
00583 for (int i=0; i < 3; i++)
00584 for (int j=0; j < i; j++) C[i][j]=C[j][i];
00585
00586
00587
00588 compute_pca3(C, ValPs, VecPs);
00589
00590 Rcm=(float) mean[0];
00591 Gcm=(float) mean[1];
00592 Bcm=(float) mean[2];
00593
00594
00595 uu[0]=(float) VecPs[0][0];
00596 uu[1]=(float) VecPs[1][0];
00597 uu[2]=(float) VecPs[2][0];
00598 vv[0]=(float) VecPs[0][1];
00599 vv[1]=(float) VecPs[1][1];
00600 vv[2]=(float) VecPs[2][1];
00601 normalize_vector(uu);
00602 normalize_vector(vv);
00603
00604 projection_type=0;
00605 if ((option == 2) && (ValPs[1] != 0)) {
00606
00607
00608
00609 vectorial_product(uu, vv, ww);
00610 normalize_vector(ww);
00611
00612 infoproj->A=ww[0];
00613 infoproj->B=ww[1];
00614 infoproj->C=ww[2];
00615 infoproj->D=-(infoproj->A*Rcm+infoproj->B*Gcm+infoproj->C*Bcm);
00616 infoproj->Rcm=Rcm;
00617 infoproj->Gcm=Gcm;
00618 infoproj->Bcm=Bcm;
00619
00620
00621 project_point(R0, G0, B0, newR, newG, newB, Rcm, Gcm, Bcm,
00622 infoproj->A, infoproj->B, infoproj->C, (unsigned char) 2);
00623 projection_type=2;
00624 } else {
00625
00626 project_point(R0, G0, B0, newR, newG, newB, Rcm, Gcm, Bcm,
00627 uu[0], uu[1], uu[2], (unsigned char) 1);
00628 infoproj->A=uu[0];
00629 infoproj->B=uu[1];
00630 infoproj->C=uu[2];
00631 infoproj->Rcm=Rcm;
00632 infoproj->Gcm=Gcm;
00633 infoproj->Bcm=Bcm;
00634 projection_type=1;
00635 }
00636
00637 infoproj->Rp=newR;
00638 infoproj->Gp=newG;
00639 infoproj->Bp=newB;
00640
00641 return projection_type;
00642 }
00643
00674 unsigned char find_projectionRGB(float R0, float G0, float B0,
00675 struct RGBbin ***check,
00676 struct infoProjection *infoproj,
00677 int rneigh, int nneighmin,
00678 unsigned char option)
00679 {
00680 int nneigh, nneighdiff;
00681 struct RGBpoint *firstneigh;
00682 unsigned char validprojection;
00683
00684
00685 nneigh=0;
00686 firstneigh=find_neighboursRGB(R0, G0, B0, check, rneigh, -1, nneigh,
00687 nneighdiff);
00688
00689 if (nneighdiff >= nneighmin) {
00690
00691 validprojection=get_projectionRGB(R0, G0, B0, firstneigh, infoproj,
00692 option);
00693 } else validprojection=0;
00694
00695 return validprojection;
00696 }
00697
00698
00699
00721 void process_RGBpoint(float R0, float G0, float B0,
00722 unsigned char validprojection,
00723 struct RGBbin ***check, struct infoPixel *infopix,
00724 struct infoPixel *infopixB,
00725 struct infoProjection *infoproj,
00726 int rsim)
00727 {
00728 int iR, iG, iB, iRmin, iRmax, iGmin , iGmax, iBmin, iBmax;
00729 struct RGBpoint *point;
00730
00731
00732 iRmin=(int) (R0-rsim);
00733 iRmax=(int) (R0+rsim);
00734 iGmin=(int) (G0-rsim);
00735 iGmax=(int) (G0+rsim);
00736 iBmin=(int) (B0-rsim);
00737 iBmax=(int) (B0+rsim);
00738
00739
00740 if (iRmin < 0) iRmin=0;
00741 if (iRmin > 255) iRmin=255;
00742 if (iRmax < 0) iRmax=0;
00743 if (iRmax > 255) iRmax=255;
00744 if (iGmin < 0) iGmin=0;
00745 if (iGmin > 255) iGmin=255;
00746 if (iGmax < 0) iGmax=0;
00747 if (iGmax > 255) iGmax=255;
00748 if (iBmin < 0) iBmin=0;
00749 if (iBmin > 255) iBmin=255;
00750 if (iBmax < 0) iBmax=0;
00751 if (iBmax > 255) iBmax=255;
00752
00753
00754 for (iR=iRmin; iR <= iRmax; iR++)
00755 for (iG=iGmin; iG <= iGmax; iG++)
00756 for (iB=iBmin; iB <= iBmax; iB++) {
00757
00758 for (point=check[iR][iG][iB].first; point; point=point->next) {
00759 if ((fabs(point->R-R0) <= rsim) && (fabs(point->G-G0) <= rsim)
00760 && (fabs(point->B-B0) <= rsim)) {
00761 infopix[point->idpix].processed=1;
00762 if (validprojection > 0) {
00763
00764
00765 project_point(point->R, point->G, point->B,
00766 infopixB[point->idpix].R,
00767 infopixB[point->idpix].G,
00768 infopixB[point->idpix].B,
00769 infoproj->Rcm, infoproj->Gcm, infoproj->Bcm,
00770 infoproj->A, infoproj->B, infoproj->C,
00771 validprojection);
00772 infopixB[point->idpix].AA=infoproj->A;
00773 infopixB[point->idpix].BB=infoproj->B;
00774 infopixB[point->idpix].CC=infoproj->C;
00775 infopixB[point->idpix].DD=infoproj->D;
00776 infopixB[point->idpix].Rcm=infoproj->Rcm;
00777 infopixB[point->idpix].Gcm=infoproj->Gcm;
00778 infopixB[point->idpix].Bcm=infoproj->Bcm;
00779 infopixB[point->idpix].projected=validprojection;
00780 } else {
00781
00782 infopixB[point->idpix].R=R0;
00783 infopixB[point->idpix].G=G0;
00784 infopixB[point->idpix].B=B0;
00785 infopixB[point->idpix].AA=0;
00786 infopixB[point->idpix].BB=0;
00787 infopixB[point->idpix].CC=0;
00788 infopixB[point->idpix].DD=0;
00789 infopixB[point->idpix].Rcm=0;
00790 infopixB[point->idpix].Gcm=0;
00791 infopixB[point->idpix].Bcm=0;
00792 infopixB[point->idpix].projected=0;
00793 }
00794 }
00795 }
00796
00797 }
00798
00799 }
00800
00809 void reset_color_info(struct RGBbin ***check)
00810 {
00811 int iR, iG, iB;
00812 struct RGBpoint *point, *pointnext;
00813
00814 for (iR=0; iR < 256; iR++)
00815 for (iG=0; iG < 256; iG++)
00816 for (iB=0; iB < 256; iB++) {
00817 if (check[iR][iG][iB].first) {
00818 for (point=check[iR][iG][iB].first; point; point=pointnext) {
00819 pointnext=point->next;
00820 delete point;
00821 }
00822 check[iR][iG][iB].first=check[iR][iG][iB].last=NULL;
00823 }
00824 }
00825 }
00826
00845 void compute_errors_it(struct infoPixel *infopix,
00846 struct infoPixel *infopixPrev,
00847 int w, int h, float &dprev, int *repeatedRGB)
00848 {
00849 float dp;
00850
00851 dprev=0;
00852 int ndiff=0;
00853 for (int n=0; n < w*h; n++) {
00854 if (repeatedRGB[n] > 0) {
00855
00856 ndiff++;
00857
00858
00859 dp=sqrt((infopixPrev[n].R-infopix[n].R)*(infopixPrev[n].R-infopix[n].R)+
00860 (infopixPrev[n].G-infopix[n].G)*(infopixPrev[n].G-infopix[n].G)+
00861 (infopixPrev[n].B-infopix[n].B)*(infopixPrev[n].B-infopix[n].B));
00862 dprev+=dp;
00863 }
00864 }
00865
00866
00867
00868
00869
00870
00871 if (ndiff > 0) dprev/=(float) ndiff;
00872 }
00873
00884 void update_color_info(struct RGBbin ***check, struct infoPixel *infopix,
00885 int w, int h)
00886 {
00887 int n, nRGB, iR, iG, iB;
00888 struct RGBpoint *point, *pointB;
00889 unsigned char isrepeated;
00890
00891 nRGB=0;
00892 for (n=0; n < w*h; n++) {
00893 if (!infopix[n].ignore) {
00894 infopix[n].processed=0;
00895
00896 point=new struct RGBpoint;
00897 point->R=infopix[n].R;
00898 point->G=infopix[n].G;
00899 point->B=infopix[n].B;
00900 point->idpix=n;
00901 point->next=NULL;
00902
00903 iR=(int) infopix[n].R;
00904 iG=(int) infopix[n].G;
00905 iB=(int) infopix[n].B;
00906 if (iR < 0) iR=0;
00907 if (iR > 255) iR=255;
00908 if (iG < 0) iG=0;
00909 if (iG > 255) iG=255;
00910 if (iB < 0) iB=0;
00911 if (iB > 255) iB=255;
00912 if (check[iR][iG][iB].first == NULL) nRGB++;
00913 else {
00914 isrepeated=0;
00915 for (pointB=check[iR][iG][iB].first; pointB && !isrepeated;
00916 pointB=pointB->next) {
00917 isrepeated=(pointB->R == point->R) && (pointB->G == point->G)
00918 && (pointB->B == point->B);
00919 }
00920
00921 if (!isrepeated) nRGB++;
00922 }
00923 if (check[iR][iG][iB].first == NULL) check[iR][iG][iB].first=point;
00924 else check[iR][iG][iB].last->next=point;
00925 check[iR][iG][iB].last=point;
00926 }
00927 }
00928 printf(" %i colors\n", nRGB);
00929 }
00930
00939 void get_output_image(unsigned char *outR, unsigned char *outG,
00940 unsigned char *outB, int w, int h,
00941 struct infoPixel *infopix)
00942 {
00943 int iR, iG, iB, n, nnoprojected=0, nignored=0;
00944
00945 for (n=0; n < w*h; n++) {
00946
00947 iR=(int) (infopix[n].R + 0.5f);
00948 iG=(int) (infopix[n].G + 0.5f);
00949 iB=(int) (infopix[n].B + 0.5f);
00950 if (iR < 0) iR=0;
00951 if (iR > 255) iR=255;
00952 if (iG < 0) iG=0;
00953 if (iG > 255) iG=255;
00954 if (iB < 0) iB=0;
00955 if (iB > 255) iB=255;
00956 if (infopix[n].ignore) nignored++;
00957 else {
00958 if (!infopix[n].projected) nnoprojected++;
00959 }
00960
00961
00962
00963 outR[n]=iR;
00964 outG[n]=iG;
00965 outB[n]=iB;
00966 }
00967 printf("%i (%2.2f) ignored\n",
00968 nignored, 100.0f* (float) nignored/(float) (w*h));
00969 printf("%i (%2.2f) non-projected\n",
00970 nnoprojected, 100.0f* (float) nnoprojected/(float) (w*h));
00971 }
00972
00973
00974
00975
01017 int colorfiltering(unsigned char *R, unsigned char *G, unsigned char *B,
01018 unsigned char *outR, unsigned char *outG,
01019 unsigned char *outB,
01020 int w, int h, struct paramColorFilter *param)
01021 {
01022
01023 int rneigh, rsim, nneighmin;
01024 float eitmax;
01025 unsigned char option, ignore000;
01026
01027
01028 rneigh=param->rneigh;
01029 nneighmin=param->nneighmin;
01030 rsim=param->rsim;
01031 eitmax=param->eitmax;
01032 option=param->option;
01033 ignore000=param->ignore000;
01034
01035
01036 struct RGBbin ***check;
01037 struct infoPixel *infopix, *infopixB, *infopixAux;
01038 struct infoProjection infoproj;
01039 int n, it;
01040 float R0, G0, B0;
01041 unsigned char validprojection;
01042 float eit;
01043 int *repeatedRGB=NULL;
01044
01045
01046 initialize_colorfiltering_data(R, G, B, w, h, &check, &infopix, &infopixB,
01047 &repeatedRGB, ignore000);
01048
01049
01050 unsigned char stop;
01051 it=0;
01052 do {
01053 printf("it=%i\n", it);
01054 for (n=0; n < w*h; n++) {
01055 if (infopix[n].ignore) {
01056 infopixB[n].ignore=1;
01057 infopixB[n].R=infopix[n].R;
01058 infopixB[n].G=infopix[n].G;
01059 infopixB[n].B=infopix[n].B;
01060 } else {
01061 infopixB[n].ignore=0;
01062 if (!infopix[n].processed) {
01063 R0=infopix[n].R;
01064 G0=infopix[n].G;
01065 B0=infopix[n].B;
01066
01067
01068 validprojection=find_projectionRGB(R0, G0, B0, check, &infoproj,
01069 rneigh, nneighmin, option);
01070
01071
01072 process_RGBpoint(R0, G0, B0, validprojection, check, infopix,
01073 infopixB, &infoproj, rsim);
01074
01075 }
01076 }
01077 }
01078
01079
01080 compute_errors_it(infopixB, infopix, w, h, eit, repeatedRGB);
01081 printf(" eit=%2.4f\n", eit);
01082
01083
01084 infopixAux=infopix;
01085 infopix=infopixB;
01086 infopixB=infopixAux;
01087
01088
01089 reset_color_info(check);
01090
01091
01092 update_color_info(check, infopix, w, h);
01093
01094 it++;
01095 stop=(eit < eitmax);
01096 } while (!stop);
01097
01098
01099 get_output_image(outR, outG, outB, w, h, infopix);
01100
01101
01102 delete_colorfiltering_data(check, infopix, infopixB);
01103 delete[] repeatedRGB;
01104
01105 return it;
01106 }
01107
01129 struct paramColorFilter *new_colorfiltering_parameters(int rneigh, int rsim,
01130 int nneighmin,
01131 float eitmax,
01132 unsigned char option,
01133 unsigned char ignore000)
01134 {
01135 struct paramColorFilter *param=new struct paramColorFilter;
01136 param->rneigh=rneigh;
01137 param->rsim=rsim;
01138 param->nneighmin=nneighmin;
01139 param->eitmax=eitmax;
01140 param->option=option;
01141 param->ignore000=ignore000;
01142
01143 return param;
01144 }
01145
01151 void delete_colorfiltering_parameters(struct paramColorFilter *param)
01152 {
01153 delete param;
01154 }
01155
01156
01186 float ***RGBdensities(unsigned char *R, unsigned char *G, unsigned char *B,
01187 int w, int h, int rdst, float hdst, float &maxdst)
01188 {
01189 struct RGBbin ***check;
01190 struct infoPixel *infopix;
01191 struct RGBpoint *firstneigh, *neigh, *point;
01192 int iR, iG, iB, nneigh, nneighdiff;
01193 float ***dsts=NULL;
01194 float dR, dG, dB, d2, h2, dst;
01195
01196
01197 initialize_colorfiltering_data(R, G, B, w, h, &check, &infopix,
01198 NULL, NULL, 1);
01199 dsts=new float**[256];
01200 for (iR=0; iR < 256; iR++) {
01201 dsts[iR]=new float*[256];
01202 for (iG=0; iG < 256; iG++) {
01203 dsts[iR][iG]=new float[256];
01204 memset(dsts[iR][iG], 0, 256*sizeof(float));
01205 }
01206 }
01207
01208
01209 h2=hdst*hdst;
01210 maxdst=0;
01211 for (int n=0; n < w*h; n++) {
01212 if (!infopix[n].ignore && !infopix[n].processed) {
01213
01214 firstneigh=find_neighboursRGB(infopix[n].R, infopix[n].G, infopix[n].B,
01215 check, rdst, -1, nneigh, nneighdiff);
01216
01217 dst=0;
01218 for (neigh=firstneigh; neigh; neigh=neigh->nextneigh) {
01219 dR=infopix[n].R-neigh->R;
01220 dG=infopix[n].G-neigh->G;
01221 dB=infopix[n].B-neigh->B;
01222 d2=dR*dR+dG*dG+dB*dB;
01223 dst+=exp(-d2/h2);
01224 }
01225
01226 iR=(int) infopix[n].R;
01227 iG=(int) infopix[n].G;
01228 iB=(int) infopix[n].B;
01229 dsts[iR][iG][iB]=dst;
01230
01231 if (dst > maxdst) maxdst=dst;
01232 for (point=check[iR][iG][iB].first; point; point=point->next)
01233 infopix[point->idpix].processed=1;
01234 }
01235 }
01236
01237
01238 delete_colorfiltering_data(check, infopix, NULL);
01239
01240 return dsts;
01241 }
01242
01247 void delete_RGBdensities(float ***dsts)
01248 {
01249 int iR, iG;
01250
01251 for (iR=0; iR < 256; iR++) {
01252 for (iG=0; iG < 256; iG++) {
01253 delete[] dsts[iR][iG];
01254 }
01255 delete[] dsts[iR];
01256 }
01257 delete[] dsts;
01258 }
01259
01260
01284 void removeisolatedRGB(unsigned char *R, unsigned char *G, unsigned char *B,
01285 unsigned char *outR, unsigned char *outG,
01286 unsigned char *outB,
01287 int w, int h, int r, int nmin, int &nRGB,
01288 int &nisolatedRGB,
01289 int &nisolatedpixels)
01290 {
01291 struct RGBbin ***check;
01292 struct infoPixel *infopix;
01293 struct RGBpoint *firstneigh, *point;
01294 int iR, iG, iB, nneigh, nneighdiff;
01295
01296 nRGB=0;
01297 nisolatedRGB=0;
01298 nisolatedpixels=0;
01299
01300 memcpy(outR, R, w*h);
01301 memcpy(outG, G, w*h);
01302 memcpy(outB, B, w*h);
01303
01304
01305 nRGB=initialize_colorfiltering_data(R, G, B, w, h, &check, &infopix,
01306 NULL, NULL, 1);
01307
01308
01309 for (int n=0; n < w*h; n++) {
01310 if (!infopix[n].ignore && !infopix[n].processed) {
01311
01312 firstneigh=find_neighboursRGB(infopix[n].R, infopix[n].G, infopix[n].B,
01313 check, r, nmin, nneigh, nneighdiff);
01314 iR=(int) infopix[n].R;
01315 iG=(int) infopix[n].G;
01316 iB=(int) infopix[n].B;
01317
01318 if (nneighdiff < nmin) nisolatedRGB++;
01319 for (point=check[iR][iG][iB].first; point; point=point->next) {
01320 infopix[point->idpix].processed=1;
01321 if (nneighdiff < nmin) {
01322 outR[point->idpix]=0;
01323 outG[point->idpix]=0;
01324 outB[point->idpix]=0;
01325 nisolatedpixels++;
01326 }
01327 }
01328 }
01329 }
01330
01331
01332 delete_colorfiltering_data(check, infopix, NULL);
01333
01334 printf("%i isolated colors (%2.2f%% of all colors) \n",
01335 nisolatedRGB, (100.0f*(float) nisolatedRGB)/((float) nRGB));
01336 printf("%i pixels with isolated colors (%2.2f%% of all pixels) \n",
01337 nisolatedpixels, (100.0f*(float) nisolatedpixels)/((float) (w*h)));
01338
01339 }
01340
01341