2012-05-30 26 views
2

編輯:在Windows平臺上工作。將矩陣應用於圖像,尋求性能改進

問題:問題較少,更多關於建議。我目前對低級程序並不熟悉,但我試圖優化下面的代碼,試圖提高整體代碼的性能。此應用程序取決於極高速度的圖像處理。

當前性能:在我的電腦上,目前計算512x512圖像的時間大約是4-6ms。如果可能的話,我試圖減少一半。

限制:由於此項目規模巨大,對應用程序根本的變化是非常困難的事,這樣的事情,如移植到DirectX或其它GPU方法並不多一種選擇。該項目目前有效,我只是想弄清楚如何讓它工作得更快。

我的這種用途的具體信息:圖片進入這個方法總是會正好廣場和128 (最有可能的512×512)一些增量,他們總是會出來一樣大小。除此之外,沒有其他的東西了。矩陣是在其他地方計算的,所以這只是將矩陣應用於我的圖像。原始圖像和新圖像都正在使用,因此需要複製圖像。

這是我目前的執行:

void ReprojectRectangle(double *mpProjMatrix, unsigned char *pDstScan0, unsigned char *pSrcScan0, 
     int NewBitmapDataStride, int SrcBitmapDataStride, int YOffset, double InversedAspect, int RectX, int RectY, int RectW, int RectH) 
     { 
      int  i, j; 
      double Xnorm, Ynorm; 
      double Ynorm_X_ProjMatrix4, Ynorm_X_ProjMatrix5, Ynorm_X_ProjMatrix7;;   
      double SrcX, SrcY, T; 
      int  SrcXnt, SrcYnt; 
      int  SrcXec, SrcYec, SrcYnvDec; 
      unsigned char *pNewPtr, *pSrcPtr1, *pSrcPtr2, *pSrcPtr3, *pSrcPtr4; 
      int  RectX2, RectY2; 

      /* Compensate (or re-center) the Y-coordinate regarding the aspect ratio */ 
      RectY -= YOffset; 

      /* Compute the second point of the rectangle for the loops */ 
      RectX2 = RectX + RectW; 
      RectY2 = RectY + RectH; 

      /* Clamp values (be careful with aspect ratio */ 
      if (RectY < 0) RectY = 0; 
      if (RectY2 < 0) RectY2 = 0; 
      if ((double)RectY > (InversedAspect * 512.0)) RectY = (int)(InversedAspect * 512.0); 
      if ((double)RectY2 > (InversedAspect * 512.0)) RectY2 = (int)(InversedAspect * 512.0); 

      /* Iterate through each pixel of the scaled re-Proj */ 
      for (i=RectY; i<RectY2; i++) 
      {  
      /* Normalize Y-coordinate and take the ratio into account */ 
      Ynorm = InversedAspect - (double)i/512.0; 

      /* Pre-compute some matrix coefficients */ 
      Ynorm_X_ProjMatrix4 = Ynorm * mpProjMatrix[4] + mpProjMatrix[12]; 
      Ynorm_X_ProjMatrix5 = Ynorm * mpProjMatrix[5] + mpProjMatrix[13]; 
      Ynorm_X_ProjMatrix7 = Ynorm * mpProjMatrix[7] + mpProjMatrix[15]; 

      for (j=RectX; j<RectX2; j++) 
      { 
       /* Get a pointer to the pixel on (i,j) */ 
       pNewPtr = pDstScan0 + ((i+YOffset) * NewBitmapDataStride) + j; 

       /* Normalize X-coordinates */ 
       Xnorm = (double)j/512.0;     

       /* Compute the corresponding coordinates in the source image, before Proj and normalize source coordinates*/ 
       T = (Xnorm * mpProjMatrix[3] + Ynorm_X_ProjMatrix7); 
       SrcY = (Xnorm * mpProjMatrix[0] + Ynorm_X_ProjMatrix4)/T; 
       SrcX = (Xnorm * mpProjMatrix[1] + Ynorm_X_ProjMatrix5)/T; 

       // Compute the integer and decimal values of the coordinates in the sources image      
       SrcXnt = (int) SrcX; 
       SrcYnt = (int) SrcY; 
       SrcXec = 64 - (int) ((SrcX - (double) SrcXnt) * 64); 
       SrcYec = 64 - (int) ((SrcY - (double) SrcYnt) * 64); 

       // Get the values of the four pixels up down right left 
       pSrcPtr1 = pSrcScan0 + (SrcXnt * SrcBitmapDataStride) + SrcYnt; 
       pSrcPtr2 = pSrcPtr1 + 1; 
       pSrcPtr3 = pSrcScan0 + ((SrcXnt+1) * SrcBitmapDataStride) + SrcYnt; 
       pSrcPtr4 = pSrcPtr3 + 1; 

       SrcYnvDec = (64-SrcYec); 

       (*pNewPtr) = (unsigned char)(((SrcYec * (*pSrcPtr1) + SrcYnvDec * (*pSrcPtr2)) * SrcXec + 
             (SrcYec * (*pSrcPtr3) + SrcYnvDec * (*pSrcPtr4)) * (64 - SrcXec)) >> 12); 
      } 
     } 
    } 

回答

1

兩件事情,可以幫助:多和SIMD。使用多處理功能,您可以將輸出圖像分解爲多個圖塊,並讓每個處理器在下一個可用圖塊上工作。您可以使用SIMD指令(如SSE,AVX,AltiVec等)來同時計算多個事物,例如同時對多個座標進行相同的矩陣運算。您甚至可以將運行SIMD指令的兩用多處理器結合起來,儘可能地完成更多的工作。你沒有提到你在做什麼平臺。

+0

在Windows上工作。感謝提示,我會研究這些。多處理似乎需要更多時間來解析圖像並將其發送到每個進程。但我可能是錯的。 – Corylulu