ผมไม่ขอกล่าวถึงว่า Homography คืออะไรนะครับ จะกล่าวถึงแค่ตัวอย่างการคำนวณหา Homography โดยใช้ OpenCV ในบล็อกนี้ ซึ่งค่อนข้างง่ายครับ เพราะ OpenCV นั้นมีฟังก์ชั่น cvFindHomography อยู่แล้ว งานของเราก็แค่ใส่ข้อมูลตามที่ฟังก์ชั่นนี้ต้องการ ซึ่งอย่างน้อยเราต้องให้ตัวแปรตามข้างล่างนี้กับฟังก์ชั่น
- จุดบนระนาบต้นฉบับ (srcPoints) อย่างน้อย 2 จุดขึ้นไป จำนวนจุดนี้ขึ้นอยู่กับแต่ละงานนะครับ
- จุดบนระนาบปลายทาง (destPoints) ซึ่งจำนวนจุดก็เท่ากับที่กำหนดไว้บนระนาบเริ่มต้น
- Homography เมทริกซ์ ขนาด 3x3 (เริ่มแรกก็คือเมทริกซ์ว่างๆ นั่นแหละ)
จริงๆ เราสามารถใส่ option เพิ่มได้ ไว้ไปลองกันเองนะครับ 🙂
เรามาเตรียมข้อมูลกันดีกว่า อย่างแรกคือจุดบนระนาบต้นฉบับ (ในที่นี้ผมใช้ 4 จุด โดยแต่ละจุดอยู่ใน homogeneous coordinate)
float X_data[] = { 200, 250, 210, 255, 150, 145, 170, 162, 1, 1, 1, 1 }; CvMat X = cvMat( 3, num_of_points, CV_32FC1, X_data ); |
และจุดบนระนาบปลายทาง
float Xprime_data[] = { 200, 250, 200, 250, 150, 150, 170, 170, 1, 1, 1, 1 }; CvMat Xprime = cvMat( 3, num_of_points, CV_32FC1, Xprime_data ); |
ที่ต้องใช้ CvMat นั้นก็เป็นเพราะว่าฟังก์ชั่น cvFindHomography ต้องการข้อมูลชนิดนี้นั่นเอง ตามที่บอกไว้ตามนี้
void cvFindHomography(const CvMat* srcPoints, const CvMat* dstPoints, CvMat* H int method=0, double ransacReprojThreshold=0, CvMat* status=NULL) |
สุดท้ายคือตัว Homography เมทริกซ์
CvMat *H = cvCreateMat( 3, 3, CV_32FC1 ); |
จากนั้นก็แค่สั่งไปว่า
cvFindHomography( &X, &Xprime, H ); |
เป็นอันเสร็จเรียบร้อย! ง่ายใช่ไหมครับ 🙂
ถ้าเรามีจุดใหม่บนระนาบต้นฉบับ เราก็สามารถย้ายจุดนี้ไปบนระนาบปลายทางได้ โดยใช้การคูณกันของเมทริกซ์ดังนี้
// a test point float Xtest_data[] = { 223, 111, 1 }; CvMat Xtest = cvMat( 3, 1, CV_32FC1, Xtest_data ); CvMat *Xtestprime = cvCreateMat( 3, 1, CV_32FC1 ); // transfer the test point cvMatMul( H, &Xtest, Xtestprime ); |
ค่าของจุดใหม่จะถูกเก็บอยู่ใน Xtestprime ครับ ซึ่งมีค่าตามนี้
112.071 56.5092 0.480151 |
ใครอยากลองเล่นก็เชิญโหลดโค้ดข้างล่างนี้เลยครับ
Source code (C++): compute_homography.cc
Source code (Matlab/Octave): compute_homography.m (Thanks to Dr. Dailey for the code.)
Ref: OpenCV 2.0 Reference
Which was sort of inspiring! Completely unforeseen. Now I know what I am going to perform tomorrow