2012-02-13 33 views
1

Im'試圖用最接近的可用RGB替換輸入圖像的所有像素。我有一個數組包含顏色和輸入圖像。這裏是我的代碼,它給我一個預期的輸出圖像,但它需要非常長的時間(大約一分鐘)來處理一個圖像。任何人都可以幫助我改進代碼嗎?或者如果您有任何其他建議,請幫助。如何優化這個圖像處理用最接近的可用RGB替換圖像上的所有像素?

UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGImageGetWidth(sourceImage),CGImageGetHeight(sourceImage)), NO, 0.0f); 
//Context size I keep as same as original input image size 

//Otherwise, the output will be only a partial image 
CGContextRef context; 
context = UIGraphicsGetCurrentContext(); 

//This is for flipping up sidedown 
CGContextTranslateCTM(context, 0, self.imageViewArea.image.size.height); 
CGContextScaleCTM(context, 1.0, -1.0); 



     // init vars 
     float d = 0;       // squared error 
     int idx = 0;        // index of palette color 
     int min = 1000000;      // min difference 
     UIColor *oneRGB;       // color at a pixel 
     UIColor *paletteRGB;      // palette color 



     // visit each output color and determine closest color from palette 
     for(int y=0; y<sizeY; y++) { 
      for(int x=0; x<sizeX; x++) { 
       // desired (avg) color is one pixel of scaled image 
       oneRGB = [inputImgAvg colorAtPixel:CGPointMake(x,y)]; 


       // find closest color match in palette: init idx with index 
       // of closest match; keep track of min to find idx 
       min = 1000000; 
       idx = 0; 

       CGContextDrawImage(context,CGRectMake(xx, yy, 1, 1),img); 
      } 
     } 

     UIImage *output = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
     self.imageViewArea.image = output; 
+1

你的代碼的哪個部分需要最長的時間(循環,'UIGraphics'或'CGContext'函數等)?剖析你的代碼。 – Jacob 2012-02-13 15:23:44

+0

'ColorDiff'的代碼是什麼?另外,慣例是用小寫字母初始化方法,例如:'[self colorDiffWithPalette:paletteRGB forRGB:oneRGB]' – zaph 2012-02-13 15:27:55

+0

@Jacob:我認爲循環大部分時間都在使用中。 – user1139699 2012-02-13 15:47:01

回答

1

這是一個類似的問題(沒有明確的答案),但答案有直接訪問圖像像素的代碼。

Quantize Image, Save List of Remaining Colors

你應該做的,而不是針對每個get和set像素使用CG功能。將圖像的1個像素繪製到另一個圖像上比在數組中更改3個字節要慢很多。

另外,ColorDiff中有什麼 - 只要最近的像素具有最小的差異,就不需要完美的差異。預處理此列表可能有空間,因此對於每個調色板條目,您都有最小差異到最近的其他調色板條目。然後,在循環顯示像素的同時,我可以快速檢查下一個像素是否在剛剛找到的顏色的一半範圍內(因爲照片傾向於具有彼此相近的常見顏色)。

如果這不匹配,那麼在循環調色板時,如果我在距離任何條目的一半距離內,則無需進一步檢查。

基本上,這會在每個調色板條目周圍放置一個區域,您可以確定這個區域是最接近的。

+0

針對早期退出的不錯優化,特別是在針對之前找到的調色板條目使用時。對於線性搜索,它只會將搜索時間平均縮短一半,可能不足以成爲自己可行的解決方案。請注意,比較距離的平方時,您要使用1/4的值,而不是一半。 – 2012-02-13 18:44:55

+0

我認爲你會獲得超過一半的好處,因爲在實際圖像中經常發生幾乎相同顏色的顏色運行。我認爲真正的解決方案是使用對像素的直接內存訪問 - 另一個想法可能不會有效。 – 2012-02-13 19:44:05

+0

我剛開始測試它與RGB數組的工作與否。然後我的目標是通過輸入圖像的像素讀取並找到所有最接近的平鋪圖像來替換。這意味着我不能只改變RGB。 – user1139699 2012-02-13 19:53:57

1

通常的答案是使用k-d tree或其他一些Octree結構來減少必須在每個像素完成的計算和比較次數。

我也成功地將顏色空間分區爲一個規則網格,並保留了網格各部分可能的最接近匹配列表。例如,你可以將R,G,B的(0-255)值除以16,最後得到(16,16,16)或4096個元素的網格。最好的情況是,對於特定的網格元素,列表中只有一個成員,並且根本不需要遍歷列表。

+0

我明白你在說什麼。這就是爲什麼我縮小處理圖像以降低分辨率,然後進行處理 – user1139699 2012-02-13 19:41:51

相關問題