Wie machen Sie den folgenden code, der die Bilineare interpolation effizienter?

Dem folgenden code wird zum vergrößern der Bilder mit der bilinearen interpolation.

Wo kann geändert werden, in der Funktion der slow_rescale effizienter zu machen?

Erwarte ich, um es zu ändern aus der Sicht der Grundsätze der Computer-Organisation.

Freue mich auf Eure Antworten!

Dank!

unsigned char *slow_rescale(unsigned char *src, int src_x, int src_y, int dest_x, int dest_y)
{
 double step_x,step_y;          //Step increase as per instructions above
 unsigned char R1,R2,R3,R4;     //Colours at the four neighbours
 unsigned char G1,G2,G3,G4;
 unsigned char B1,B2,B3,B4;
 double RT1, GT1, BT1;          //Interpolated colours at T1 and T2
 double RT2, GT2, BT2;
 unsigned char R,G,B;           //Final colour at a destination pixel
 unsigned char *dst;            //Destination image - must be allocated here! 
 int x,y;               //Coordinates on destination image
 double fx,fy;              //Corresponding coordinates on source image
 double dx,dy;              //Fractional component of source image    coordinates

 dst=(unsigned char *)calloc(dest_x*dest_y*3,sizeof(unsigned char));   //Allocate and clear   destination image
 if (!dst) return(NULL);                           //Unable to allocate image

 step_x=(double)(src_x-1)/(double)(dest_x-1);
 step_y=(double)(src_y-1)/(double)(dest_y-1);

 for (x=0;x<dest_x;x++)         //Loop over destination image
  for (y=0;y<dest_y;y++)
  {
    fx=x*step_x;
    fy=y*step_y;
    dx=fx-(int)fx;
    dy=fy-(int)fy;   
    getPixel(src,floor(fx),floor(fy),src_x,&R1,&G1,&B1);    //get N1 colours
    getPixel(src,ceil(fx),floor(fy),src_x,&R2,&G2,&B2); //get N2 colours
    getPixel(src,floor(fx),ceil(fy),src_x,&R3,&G3,&B3); //get N3 colours
    getPixel(src,ceil(fx),ceil(fy),src_x,&R4,&G4,&B4);  //get N4 colours
   //Interpolate to get T1 and T2 colours
   RT1=(dx*R2)+(1-dx)*R1;
   GT1=(dx*G2)+(1-dx)*G1;
   BT1=(dx*B2)+(1-dx)*B1;
   RT2=(dx*R4)+(1-dx)*R3;
   GT2=(dx*G4)+(1-dx)*G3;
   BT2=(dx*B4)+(1-dx)*B3;
   //Obtain final colour by interpolating between T1 and T2
   R=(unsigned char)((dy*RT2)+((1-dy)*RT1));
   G=(unsigned char)((dy*GT2)+((1-dy)*GT1));
   B=(unsigned char)((dy*BT2)+((1-dy)*BT1));
  //Store the final colour
  setPixel(dst,x,y,dest_x,R,G,B);
 }
  return(dst);
}
void getPixel(unsigned char *image, int x, int y, int sx, unsigned char *R, unsigned char *G, unsigned char *B)
{
 //Get the colour at pixel x,y in the image and return it using the provided RGB pointers
 //Requires the image size along the x direction!
 *(R)=*(image+((x+(y*sx))*3)+0);
 *(G)=*(image+((x+(y*sx))*3)+1);
 *(B)=*(image+((x+(y*sx))*3)+2);
}

void setPixel(unsigned char *image, int x, int y, int sx, unsigned char R, unsigned char G, unsigned char B)
{
 //Set the colour of the pixel at x,y in the image to the specified R,G,B
 //Requires the image size along the x direction!
 *(image+((x+(y*sx))*3)+0)=R;
 *(image+((x+(y*sx))*3)+1)=G;
 *(image+((x+(y*sx))*3)+2)=B;
}
  • Können Sie zeigen, getPixel() und setPixel()?
  • Ich habe gerade editiert und Hinzugefügt, die Funktionen getPixel() und setPixel().@selbst.
  • Gut, abgesehen von völlig verändern den Algorithmus, den Sie entfernen könnte einige redundante Multiplikationen. Bei getPixel: int x, int y, int sx pass ((x+(y*sx))*3)+0 an die Funktion statt.
  • Möchten Sie bitten, dies auf CodeReview, dass es angemessener wäre es.
  • -O3? vielleicht profiling? dann, wenn einige von diesen können verschwenderisch sein/unwirksam, weil der compiler-Optimierung: inline-get/setPixel; ändern Sie Sie so, dass ein 32-bit-Lesen/schreiben vom/mem fertig ist (Vorsicht vor endianness), möglicherweise 4/8 byte ausgerichtet sind (können Sie haben "R G B 0 R G B 0 L" statt "R G B R G B"?); einige weitere temporäre vars (z.B. für Boden(fx)) ...
  • btw, versucht, einige vorgeschlagen, "manuelle" Optimierungen, ohne compiler-optim ... es stellt sich heraus, dass -O3 übertrifft diese "manuelle" Optimierungen.

InformationsquelleAutor user2964454 | 2014-01-01
Schreibe einen Kommentar