我想優化我的圖像處理代碼,因爲對於大圖像,使用Java進行處理需要很長時間。如何爲RenderScript輸出分配一個布爾數組?
我做了一些DDMS方法分析,發現這個方法吃了近50%的CPU時間:
private int getBrightness(int color) {
// returns an int from 0-255 where zero is pure black and 255 is pure white,
// weighted to correspond to perceived brightness
// http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx
int red = Color.red(color);
int blue = Color.blue(color);
int green = Color.green(color);
int brightness = (int) Math.round(Math.sqrt((0.241 * red * red) + (0.691 * green * green) + (0.068 * blue * blue)));
return brightness;
}
具體來說,要Math.sqrt()和Math.round)的調用(是真正的這裏的罪魁禍首。這與它可以並行完成時連續計算的事實相結合意味着我的處理時間過長。
有人指向我的RenderScript。我認爲這聽起來很適合我想要做的事情。我知道C++而不是C,而我正在努力完成自己想要完成的任務。
基本上,在處理時,我不需要知道每個像素的實際亮度,只是它是高於還是低於閾值(在此對象的生命週期內不會改變)。因此,我可以簡單地創建一個布爾值數組,告訴我像素是否≥閾值(true)或閾值(false)。所以我可以將亮度計算移動到renderscript中的C代碼。
我想直接返回一個真或假的值到輸出分配。這是我遇到的麻煩。
這裏是我的renderScript的C代碼:
#pragma version(1)
#pragma rs java_package_name(com.mushroomhouse.pixelbomb)
#pragma rs_fp_relaxed
int threshold = 160;
bool __attribute__((kernel)) generate(uchar4 in) {
int r = (int) (255*sqrt((float)((0.241 * in.r * in.r) + (0.691 * in.g * in.g) + (0.068 * in.b * in.b))));
return (r>threshold);
}
這裏是從我的處理類的相關代碼:
(Member variables)
...
RenderScript myRS;
ScriptC_brightness_map script;
Allocation allocIn, allocOut;
boolean[][] truthMap;
(Public Constructor) {
...
myRS = RenderScript.create(context);
script = new ScriptC_brightness_map(myRS);
}
(Initialization before processing is done)
...
truthMap = new boolean[width][height];
allocIn = Allocation.createFromBitmap(myRS, product);
allocOut = ????
script.set_threshold(brightnessValue);
script.forEach_generate(allocIn, allocOut);
...
(Processing)
所以,
我怎麼初始化allocOut ,我需要一個可以複製到boolean [] []的分配。
我可以立即將allocOut複製到我的boolean [] [] truthMap還是需要使用某種回調?我讀過RenderScript是異步的,所以這會導致問題嗎?
處理是通過IntentService在後臺完成的,所以等待RenderScript不會成爲問題。
另一種選擇是讓Renderscript簡單地返回計算出的亮度值,然後我可以在Java代碼中進行比較。可能會慢一點,但如果這是唯一的方法,我可以忍受這一點。但我仍然完全失去了如何做這樣的事情。有很多關於如何讓inAlloc和outAlloc成爲相同尺寸的位圖的教程,但並非我可以找到關於不同輸出分配的任何東西。
感謝您的幫助!
感謝關於浮筒的提示。我改變了我的方法,我非常接近它的工作。我在我的問題結尾處做了我的建議,讓RenderScript返回一個int foreach並將其複製到int [] brightnessMap中。現在我遇到了運行時錯誤:輸入和輸出參數之間的尺寸不匹配。 'allocOut = Allocation.createSized(myRS,Element.I32(myRS),brightnessMap.length);' 所以我想我必須做一個2D分配。現在看看。感謝您的見解。 – Eric 2014-09-13 00:10:05
是的,輸入和輸出分配必須具有相同的尺寸(x和y),但我認爲2D分配可以複製到1D Java數組中。 – 2014-09-13 00:24:41