Wednesday, December 21, 2011

OpenCV 2.31 + QT support

ลอง compile ซอร์สโค้ด OpenCV 2.31 ให้ support QT+OpenGL ครับ เห็นอินเตอร์เฟสที่โชว์ในเว็บแล้วสวยดี

แต่ๆๆๆ ผลลัพธ์ที่ได้




มีข้อความว่า ตอนนี้ไม่สามารถใช้ OpenGL rendering กับการกำหนดสัดส่วนของหน้าต่างได้ ขนาดของรูปที่เล็กกว่า menu bar ด้านบน จึงทำได้รูปเบี้ยวไม่ได้สเกล :( ถ้ารูปกว้างกว่าแถบ menu ก็จะไม่เบี้ยว

ข้อดี
มีเมนูบาร์ สำหรับการ pan ซ้ายขวา บนล่าง ซูมเข้าออก เซฟผลลัพธ์ รวมถึงถ้าวางเมาส์บนรูป จะแสดงพิกัด x y และค่าพิกเซล

ข้อควรปรับปรุง
บักที่ทำให้รูปที่เล็กกว่าเมนูบาร์เบี้ยว

Visual C++ Express 2010 กับ OpenCV 2.31

ถึงเวลาที่ต้องมาใช้ VC++ จนได้ เพราะอยากเอาโค้ดไปเชื่อมกับ Matlab ผ่าน mex file และต้องเชื่อมกับ OpenCV ต่อไป

วิธีการติดตั้ง VC++ เพื่อให้ใช้ได้กับ OpenCV ดูตาม http://opencv.willowgarage.com/wiki/VisualC%2B%2B_VS2010_CMake ได้ครับ ถ้ามีเวลาคงมาสรุปเป็นภาษาไทยอีกครั้ง

ผลการทำพบว่า คอมไพล์ซอร์สโค้ดก็ไม่ยากครับ แต่ไม่สามารถสร้างตัวไบนารีแบบ install ได้ ผมเข้าใจว่ามี bug เล็กน้อยใน makefile ตอนกำหนดไดเรกทอรี อย่างไรก็ตามถ้าก๊อปไฟล์เองก็ใช้งานได้

ปัญหาถัดมา เมื่อทดสอบกับซอร์สโค้ด OpenCV ทำการ build ผ่านไม่มีปัญหาครับ แต่ว่าตอน Debug ไม่ผ่าน ต้องไปรันไฟล์ต่างหากเอง ไม่รู้ว่าเพราะอะไร เซิร์ชหาก็ยังไม่เจอวิธีแก้ครับ คงต้องหลับหูหลับตาผ่านไปก่อน

ข้อดีของ Visual C++ กับ OpenCV
-ตัว auto complete ของ IDE VC++ นี่ดีจริงๆ แต่อืดเหมือนกัน
-Build ง่าย เลือก Debug หรือ Release เวอร์ชันก็ง่าย ขนาดไฟล์ผลลัพธ์เล็ก
-มีคนใช้เยอะ พอเจอปัญหาน่าจะหาทางแก้ง่าย

ปัญหาที่เจอ
-ทำตามคู่มือแล้วแต่คอมไพล์แบบ install ยังไม่สมบูรณ์
-Debug ไม่ผ่าน :( สงสัยผมจะลืมขั้นตอนอะไรไป


Thursday, December 15, 2011

งงกับการ link ของ g++

ทดลองคอมไพล์ซอร์สโค้ดของคนอื่น ด้วย g++ (mingw) บนวินโดวส์

Makefile ของเจ้าของเป็นบน unix

ส่วนของการคอมไพล์ไม่มีปัญหา พอมาลิงก์ แสดงผลว่า undefined reference xxx

อะไรเนี่ย นั่งงมเปิดนั่น โหลดนี่ เซิร์ชหาคำตอบทั่วเน็ต ยอมแม้กระทั่งคอมไพล์ไลบรารีตัวอื่นที่เกี่ยวข้องใหม่หมด

สุดท้าย คำตอบอยู่ที่การเรียงลำดับคำสั่งของ g++

คอมไพล์
g++ -Ixxx -c input.cpp -o output.o 
เหมือนกันทั้ง unix และ windows (xxx คือตำแหน่งของ include files)

ลิงก์ (สมมติว่าสร้าง dynamic library)
-unix
g++ -Lyyy -lzzz -shared output.o -o libxyz.so
-windows
g++ -shared output.o -o libxyz.so -Lyyy -lzzz
(yyy คือตำแหน่งของ library file, zzz คือชื่อ library)

ต่างกันแค่เนี้ยยยย งมไปงมมาจนมึน
สุดท้ายใช้การได้ แต่เจ้าของโค้ดดันออกแบบให้ได้เฉพาะแบบของเขาซะอีก ต้องไปแก้โค้ดอีกเยอะเลย เฮ้อ
ไม่ใช้ซะดีไหมเนี่ย

Saturday, November 26, 2011

Speed Test

วันนี้ว่างๆเลยลองมาทดสอบความเร็ว (แบบบ้านๆ) กับการเข้าถึงพิกเซลของสามโปรแกรม คือ MATLAB, OpenCV (C++) และ ImageJ (JAVA) โดยใช้รูปขนาด 256x256 pixels มาทำ image negative (inverse) ด้วยโค้ดปกติของแต่ละอัน นั่นคือ
  • MATLAB ใช้ J = 255-I;
  • OpenCV และ ImageJ ใช้ลูป 1 ชั้น ประมวลผลรูปแบบเวกเตอร์
เวลาที่ใช้ (โดยประมาณจากโค้ดในการวัด กับดูที่โปรแกรมแสดง) เป็น 0.000075, 0.00062, 0.0030 วินาทีตามลำดับ

ต่อมา ทดลองเพิ่มขนาดรูปเป็น 2550x1900 พิกเซล เวลาโดยประมาณเป็น 0.006, 0.05, 0.12 วินาทีตามลำดับ

เห็นตัวเลขแล้วแปลกๆ ทำไม MATLAB ถึงได้เร็วขนาดนี้ แสดงว่าถ้าประมวลผลทีละพิกเซล MATLAB มีการ optimize โค้ดแบบเมตริกซ์ที่ดีมาก

โอกาสต่อไปจะลองทำการ convolution แล้วมาเทียบกันดูครับ

Saturday, October 1, 2011

Flip image & display

วันนี้ลองมาใช้ฟังก์ชันง่ายๆ เพื่อ flip รูปกันครับ

ผลลัพธ์ที่ต้องการ

เช่นเดียวกันครับ ถือว่ารูปอยู่ที่เดียวกับไฟล์ output
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;

int main()
{
 //Read file and load to variable
 Mat image = imread("lenag.jpg"); 
 //If read failure
 if(!image.data)
 {
  return -1;
 } 
 //Create a window to display the image 
 namedWindow("Original image");
 //Show the image
 imshow("Original image",image);

 //Create another image for result
 Mat result;
 flip(image, result, 1); //1=horizontal, 0=vertical, -1=both
 //Create a window to display the image 
 namedWindow("Output image");
 //Show the image
 imshow("Output image",result);

 //Wait for user to press any key
 waitKey(0);
 return 0;
}

สังเกตว่ามีการสร้าง 2 หน้าต่างเพื่อแสดง input และ output

มีการตรวจสอบว่าอ่านรูปได้หรือไม่ โดย if(!image.data)

และมีการกลับรูปโดยใช้คำสั่ง flip(image, result, 1);     //1=horizontal, 0=vertical, -1=both

จะเห็นว่า OpenCV2 พยายามทำให้รูปแบบการใช้งานคำสั่งต่างๆ ดูง่ายขึ้นกว่ารุ่นก่อนๆครับ