ลองเทียบดูกับโจทย์ image negative ในตัวอย่างที่แล้ว เราต้องการคำนวณพิกเซลใหม่ โดย 255 - พิกเซลเก่า ซึ่งต้องทำทุกๆพิกเซล แต่เนื่องจากว่าพิกเซลมีค่าแค่ 256 ค่า คือจาก 0-255 ดังนั้น ถ้าสร้าง lookup table ไว้แบบนี้
index : 0 1 2 3 ... 255
value : 255 254 253 252 ... 0
ถ้าพิกเซลต้นฉบับมีค่าเป็น 0 ก็เอาไปเทียบในตารางข้างต้น จะได้ผลลัพธ์เป็น 255 ทันทีโดยไม่ต้องคำนวณ
สมมติว่ารูปมีขนาด 256x256 พิกเซล หรือทั้งหมด 65536 พิกเซล แทนที่จะคำนวณทุกพิกเซล ก็เหลือแค่การคำนวณเฉพาะ 256 พิกเซลใน lookup table ที่เหลือก็แค่เปรียบเทียบ ซึ่งจะประหยัดเวลาไปได้มาก
ดังนั้น โค้ดการใช้ lookup table กับปัญหา image negative ก็จะประมาณนี้
//need to convert original matrix to have the same type of output matrix mat1.convertTo(mat1, CvType.CV_8UC3); //create lookup matrix 1 row 256 columns (index 0-255) Mat lookup = Mat.zeros(1, 256, CvType.CV_8UC1); //an array of 256 members, index 0 is for pixel value 0 double[] temp = new double[256]; //loop to assign inverse to array for(int i=0;i<256;i++) { temp[i] = 255-i; } //put array to lookup matrix lookup.put(0, 0, temp); //perform lookup table processing for all channels of mat1 and put result into mat2 Core.LUT(mat1, lookup, mat2);
แล้วเราจะทราบได้อย่างไรว่ามันใช้เวลาประมาณเท่าไหร่
หลักการก็ง่ายๆ วัดเวลาก่อน process กับหลัง process เสร็จ แล้วหาความต่างของเวลา ด้วยโค้ด
long tstart = System.nanoTime(); //------------------------ //our algorithm here //------------------------ long tend = System.nanoTime(); double elapse = (tend-tstart)/1000000000.0; Log.i("time", "Processing time = "+elapse+" seconds");
ผมลองวัดเวลาโดยประมาณของแต่ละวิธีในการทำ image negative ในมือถือที่ใช้ทดสอบ ได้ประมาณนี้ครับ
1. ใช้คำสั่ง
Core.bitwise_not(mat1, mat2);
ใช้เวลาเฉลี่ย 0.0072 วินาที2. ใช้คำสั่ง
mat1.convertTo(mat2, CvType.CV_8UC3, -1, 255);
ใช้เวลาเฉลี่ย 0.027 วินาที3. ใช้การวนลูปแถวและคอลัมน์ ใช้เวลาเฉลี่ย 3.35 วินาที
4. ใช้การ dump ไปประมวลผลใน array ใช้เวลาเฉลี่ย 0.142 วินาที
5. ใช้ lookup table ข้างต้น ใช้เวลาเฉลี่ย 0.0103 วินาที
เรียงตามลำดับความเร็ว คือ วิธีที่ 1 5 2 4 3
ลองพิจารณาดูแต่ละวิธี แล้วเลือกใช้งานตามความชอบเลยครับ ส่วนถ้าให้ผมเลือก ผมคงเลือกคำสั่งที่ OpenCV มีให้ก่อน เช่น วิธีที่ 1 หรือ 2 ถ้าใช้ไม่ได้ค่อยลองวิธี 5 4 และ 3 ตามลำดับครับ
No comments:
Post a Comment