ข้อดี
Warp ตำแหน่งได้ถูกต้องทั้ง แกน X และ แกน y
ต้องปรับปรุง
การใช้ wiimote 2 ตัวตอบสนองได้ช้าลง
อาจแก้ไขการคำนวณการ Warp ใหม่ให้เร็วขึ้น โดยตัดแกนที่ไม่ได้ใช้ออกไป
แยกการอ่านค่าออกเป็น 2 Thread สำหรับ wiimote แต่ละตัว
เนมินทร์ ไลฟ์สไตล์ ทุกอย่างสนใจ เช่น การเขียนโปรแกรมคอมพิวเตอร์ ข่าววงการไอที กิจกรรมยามว่าง ฯลฯ
ข้อดี
Warp ตำแหน่งได้ถูกต้องทั้ง แกน X และ แกน y
ต้องปรับปรุง
การใช้ wiimote 2 ตัวตอบสนองได้ช้าลง
อาจแก้ไขการคำนวณการ Warp ใหม่ให้เร็วขึ้น โดยตัดแกนที่ไม่ได้ใช้ออกไป
แยกการอ่านค่าออกเป็น 2 Thread สำหรับ wiimote แต่ละตัว
ทดสอบการว๊าบโดยเลื่อนกล้องกับโปรเจคเตอร์ในแกน Y
จะทำให้ตำแหน่งในแกน X ได้ถูกต้อง
งานที่จะทำต่อ
ใช้ wiimote 2 ตัวทำการว๊าบทั้ง 2 แกนจะทำให้
คำนวนตำแหน่งได้ถูกต้องในขณะที่เลื่อนระยะเข้าใกล้โปรเจคเตอร์
เปลี่ยน
1. เปลี่ยนอัลกอรึทึมที่ใช้ว๊าบ มีความเที่ยงตรงแต่ช้ากว่าแบบที่ใช้ในการทดลองครั้งที่
ปัญหาเดิมที่ยังไม่ได้แก้ไข
1.ติดปัญหาเรื่องการตอบสนอง ที่ยังช้าอยู่
แนวทางการแก้ไข
1. ใช้ 1 Thread ในการอ่านค่าจาก wiimote
2. ใช้ 1 Thread ในการ display ทางจอภาพ
ฐานตั้งนี้สามารถปรับมุมเอียงระหว่าง wiimote กับ โปรเจคเตอร์ได้
โดยด้านล่างมีไม้แผ่นใหญ่ติดแทปตีนตุ๊กแกไว้
และด้านล่างของwiimote และ โปรเจคเตอร์ ก็ติดแทปตีนตุ๊กแกไว้เหมือนกัน
พัฒนา
1.แก้มุม FOV ระหว่าง Wiimote กับ โปรเจคเตอร์ ด้วยฐานตั้งปรับมุมได้
ปัญหาใหม่
1.ติดปัญหาเรื่องการตอบสนอง
2.การวาบไม่ตรงในแนวแกน x ประมาณ 3 เซนติเมตร
ทดสอบทั้งหมด 2 ครั้ง
ได้ค่าต่างๆนำไปคำนวณด้วย Matlab ดังนี้
clc; clear all; close all; % fovy width %% Data 1 % fovy width %% Fovy Average |
FOV ด้าน Height = 30 องศา
FOV ด้าน Width = 41 องศา
จึงสรุปได้ว่า FOV ไม่ใช่ปัญหาที่ทำให้การว๊าบไม่สำเร็จ
คาดว่าสาเหตุน่าจะมาจากการที่มุม FOV ของ Wiimote น้อยกว่ามุม FOV ของ โปรเจคเตอร์
ภาพที่ได้จึงไม่ครอบคลุม
เพื่อทดสอบสมมติฐานนี้ จึงต้องทำการหา มุม FOV ของ Wiimote
การคำนวณพิกัด 2D หรือระนาบ เมื่อกำลังใช้งานพิกัด 3D ใน OpenGL แบบ Perspective
เมื่อเราตั้งค่า Projection Matrix เป็น 3D แบบ Perspective แล้ว
เรายังสามารถใช้การวาดรูปแบบ 2D ได้โดยสามารถคำนวณหา
ความกว้าง ความสูง และ พิกัดของ 2D ได้จาก Code การ Projection
glMatrixMode (GL_PROJECTION); //set the matrix to projection |
และอีกค่าหนึ่งที่นำมาคิดคือ มุมมองของกล้อง
/* |
จาก Code ข้างบนเราจะได้คำนวนหา
ขอบเขตความกว้าง [XWmin, XWmax]
ขอบเขตความยาว [YWmin, YWmax]
ได้ดังนี้
fovyH = 30.32; height = 2 * Zvp * tan(deg2rad(fovyH/2)); width = aspect * height; |
สูตรในการคำนวณมุม หามาจากหนังสือ Computer Graphics with OpenGL ของ Hearn Baker สำนักพิมพ์ Pearson Prentice Hall
หน้า 375
tan(theta/2) = (height/2) / (Zprp – Zvp) |
theta คือ fovy angle นั่นเอง
height คือ ความสูงของภาพที่ฉายออกไป
Zprp คือ ค่า Z ของกล้อง
Zvp คือ ค่า Z ของ View Plane
ดังนั้น Zprp – Zvp ก็คือ ระยะห่างระหว่างกล้องกับ View Plane นั่นเอง
ในที่นี้กล้องคือโปรเจคเตอร์
ผลการวัด ครั้งที่ 1
height ทั้งสองข้างของภาพ = 35.5 cm และ 36.13 cm
Zprp – Zvp = 72.4 cm
fovy angle = 27.6550
ผลการวัด ครั้งที่ 2
height ทั้งสองข้างของภาพ = 15.4 cm และ 15.5 cm
Zprp – Zvp = 30.4 cm
fovy angle = 28.5155
ดังนั้นมุม Fovy โดยเฉลี่ยคือ 28 องศา
คลาสวาบจากสีเหลี่ยมด้านไม่เท่า ไปยังสีเหลี่ยมด้านไม่เท่า Nemin c++ warping class
เขียนขึ้นมาจากหลัก Inferring Projective Mappings ในหนังสือ Fundamentals of Texture Mapping and Image Warping
อ่านเรื่องการ Warp ได้เพื่อจะได้เข้าใจมากขึ้น
ในที่นี้คือการเขียนโค้ดด้วยภาษา C++ หลังจากที่มีเวอร์ชั่น Matlab ไปแล้ว
ตัวอย่างการเรียกใช้งาน
/* source quadrilateral /* destination quadrilateral |
ประสิทธิภาพการ Warp ใกล้เคียงกับเวอร์ชัน Matlab แต่ทำงานได้ไวกว่ามาก
ใครสนใจดาวน์โหลดไปทดสอบกันได้ครับ
อัพบล็อกง่ายๆด้วย Windows Live Writer Beta
ดาวน์โหลด โปรแกรม
ทดสอบใส่รูป
ทดสอบใส่ video จาก youtube
ทดสอบใส่ตาราง
นอกจากนี้สามารถเขียนบลฺ็อกครั้งเดียว และอัพไปหลายๆที่ได้เลย เพราะผมเขียนบล็อกอยู่ 2 ที่
มี ภาพ Preview ให้ดูด้วย
ใครโปรเรื่อง HTML ยังแก้ไขได้โดยตรงด้วย
ลองเอาไปใช้กันดูนะครับ
ทดสอบการสร้างโปรเจคที่ใช้งาน wiiuse, OpenGL, OpenCV ร่วมกัน
โค้ดที่ใช้ทดสอบ wiiuse
/* Test wiimote /* |
โค้ดที่ใช้ทดสอบ OpenCV
/* test OpenCV |
โค้ดที่ใช้ทดสอบ OpenGL
/* test OpenGL glutKeyboardFunc (keyboard); //check the keyboard |
การคอมไพล์ไลบารี wiiuse ด้วย Visual Studio 2008
ผมนำเอาไลบารี wiiuse ที่คอมไฟล์มาแล้ว แต่ดันใช้ไม่ได้
จึงต้องคอมไพล์มันใหม่ แต่มีขั้นตอนยุ่งยากเหมือนกันเลยจะเอาวิธีที่ใช้แล้ว Work มาบรรยายให้ฟัง
ผมใช้ wiiuse ผ่าน ไลบารี ของ FWiine หรืออยากโหลดอันที่ผมใช้ไปเลยก็ได้
ได้มาจากป้อฝาแฝดผมเอง โหลดได้ที่นี่
และต้องใช้ Windows Driver Kit: WDK เป็นไลบารีที่ wiiuse เรียกใช้ตัว Bluetooth อีกที
1. Config Visual Studio
ไปที่ Tools > Options… > Projects and Solutions > VC++ Directories
เปลี่ยน Show directories for : Library files
เพิ่ม Directory ของ WDK ตัวอย่าง C:\WinDDK\7600.16385.1\lib\win7\i386
คลิก OK
2. ปรับ wiiuse project property
คลิกขวาที่ project wiiuse เลือก property
ไปที่ Confuguration Properties > C/C++ > General
ที่ Additional Include Directorties คลิก …
เพิ่ม Path ของ VC Standard Include ตัวอย่าง C:\Program Files\Microsoft Visual Studio 9.0\VC\include
และ Path ของ WDK API ตัวอย่าง C:\WinDDK\7600.16385.1\inc\api
คลิก OK
ไปที่ Confuguration Properties > Linker > Input
ที่ Additional Include Directorties คลิก …
เพิ่ม Link ไฟล์ odbc32.lib odbccp32.lib Ws2_32.lib hid.lib setupapi.lib
3. ปรับ wiiuseexample property
คลิกขวาที่ wiiuserexample เลือก Property
ไปที่ Confuguration Properties > C/C++ > General ใส่ ..\..\src
ไปที่ Confuguration Properties > Linker > Input
ที่ Additional Dependencies ใส่ wiiuse.lib คลิก OK
แค่นี้เป็นอันเสร็จคอมไพล์ได้แน่นอน งานนี้ขอขอบคุณ ป้อฝาแฝดที่ช่วยทำและให้คำแนะนำ
using AForge.Robotics.Lego; |
// NXT brick private NXTBrick nxt = new NXTBrick(); private NXTBrick.MotorRunState[] runStates = new NXTBrick.MotorRunState[] { NXTBrick.MotorRunState.Idle, NXTBrick.MotorRunState.RampUp, NXTBrick.MotorRunState.Running, NXTBrick.MotorRunState.RampDown }; |
// NXT brick private NXTBrick nxt = new NXTBrick(); private NXTBrick.MotorRunState[] runStates = new NXTBrick.MotorRunState[] { NXTBrick.MotorRunState.Idle, NXTBrick.MotorRunState.RampUp, NXTBrick.MotorRunState.Running, NXTBrick.MotorRunState.RampDown }; |
// walk bool walkOn = true; bool legLeft = true; System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); public void Walk(object sender, EventArgs eArgs) { NXTBrick.MotorState motorStateGo = new NXTBrick.MotorState(); motorStateGo.Power = (sbyte)127; motorStateGo.TurnRatio = (sbyte)50; motorStateGo.Mode = NXTBrick.MotorMode.On;// NXTBrick.MotorMode.Brake, NXTBrick.MotorMode.None, NXTBrick.MotorMode.Regulated motorStateGo.RunState = runStates[2]; //0:Idle, 1:RampUp, 2:Running, 3:RampDown legLeft = !legLeft; if (legLeft) { //left leg forward // set motor's state if (nxt.SetMotorState(NXTBrick.Motor.C, motorStateGo) != true) { System.Diagnostics.Debug.WriteLine("Failed setting motor state"); } } else { //Right leg forward if (nxt.SetMotorState(NXTBrick.Motor.B, motorStateGo) != true) { System.Diagnostics.Debug.WriteLine("Failed setting motor state"); } } } |
if (ws.ButtonState.Up) { // your code when Press Up Buttom } |
% test wraping function % By Nemin Suksen % Thanks Navakung Seibung for sample data % source quadrilateral u0 = 7; v0 = 171; u1 = 294; v1 = 168; u2 = 307; v2 = 2; u3 = 1; v3 = 2; %destination qudrilateral x0 = 10; y0 = 190; x1 = 310; y1 = 190; x2 = 310; y2 = 10; x3 = 10; y3 = 10; %Tranformation T = warpq2q(u0, v0, u1, v1, u2, v2, u3, v3, x0, y0, x1, y1, x2, y2, x3, y3) %Test point u = 294; v = 168; point = T*[u v 1]'; point = point./point(3) |
% Unit Square to Quadrilateral % By Nemin Suksen % Master Degree FIBO, KMUTT, Thailand % Reference: pages 17-21 of Fundamentals of Texture Mapping and Image Warping, Paul Heckbert, % Master’s thesis, UCB/CSD 89/516, CS Division, U.C. Berkeley, June 1989, % URL=http://www.cs.cmu.edu/?ph. % Thank Nung Navakun Sebang for paper sample data and suggestion clc; clear all; close all; %% Source Quadrilateral % 4 Point of Quadrilateral = (x0,y0), (x1,y1), (x2,y2), (x3,y3) s0 = 7; t0 = 171; s1 = 294; t1 = 168; s2 = 307; t2 = 2; s3 = 1; t3 = 2; %% Destination Quadrilateral % 4 Point of unit squre = (u0,v0), (u1,v1), (u2,v2), (u3,v3) u0 = 0; v0 = 1; u1 = 1; v1 = 0; u2 = 1; v2 = 1; u3 = 0; v3 = 1; %% Forward wrap T = warps2q(s0, t0, s1, t1, s2, t2, s3, t3); %% invert wrap iT = iwarp(T); %% testing wrap s = 154; t = 154; point = iwarp(T)*[s t 1]'; point = point./point(3) |
% Unit Square to Quadrilateral % By Nemin Suksen % Master Degree FIBO, KMUTT, Thailand % Reference: pages 17-21 of Fundamentals of Texture Mapping and Image Warping, Paul Heckbert, % Master’s thesis, UCB/CSD 89/516, CS Division, U.C. Berkeley, June 1989, % URL=http://www.cs.cmu.edu/?ph. % Thank Nung Navakun Sebang for paper sample data and suggestion clc; clear all; close all; %% Source Quadrilateral % 4 Point of unit squre = (u0,v0), (u1,v1), (u2,v2), (u3,v3) u0 = 0; v0 = 1; u1 = 1; v1 = 0; u2 = 1; v2 = 1; u3 = 0; v3 = 1; %% Destination Quadrilateral % 4 Point of Quadrilateral = (x0,y0), (x1,y1), (x2,y2), (x3,y3) x0 = 10; y0 = 190; x1 = 310; y1 = 190; x2 = 310; y2 = 10; x3 = 10; y3 = 10; %% additional define for faster computaion dx1 = x1 - x2; dx2 = x3 - x2; sx = x0 - x1 + x2 -x3; dy1 = y1 - y2; dy2 = y3 - y2; sy = y0 - y1 + y2 - y3; if (sx == 0) && (sy ==0) % xy polygon is a parallelogram a = x1 - x0; b = x2 - x1; c = x0; d = y1 - y0; e = y2 - y1; f = y0; g = 0; h = 0; else den = dx1*dy2 - dx2*dy1; g = (sx*dy2 - dx2*sy)/den; h = (dx1*sy - sx-dy1)/den; a = x1 - x0 - g*x1; b = x3 - x0 - h*x3; c = x0; d = y1 - y0 + g*y1; e = y3 - y0 + h*y3; f = y0; end %% test point u = 0.5288; v = 0.0924; w = g*u + h*v + 1; x = (a*u + b*v + c) / w y = (d*u + e*v + f) / w |
%% inverse simple % map destination quadrilater to source qudrilater iTf = inv(Tf); A = iTf(1,1); B = iTf(1,2); C = iTf(1,3); D = iTf(2,1); E = iTf(2,2); F = iTf(2,3); G = iTf(3,1); H = iTf(3,2); I = iTf(3,3); % Ex sample % use point from previous step (x,y) % if inverse correct (u,v) must close to (154,154) W = G*x + H*y + I; u = (A*x + B*y + C) / W v = (D*x + E*y + F) / W |
%% inverse faster but have a little error % Reference Mapping to Polygon Mesh Object % invF = (1/ae-bd)*[ ei?fh ch?bi bf?ec ] % | fg?di ai?cg dc?af | % [ dg?eg bg?ah ae?bd ] A = e*i - f*h; B = c*h - b*i; C = b*f - e*c; D = f*g - d*i; E = a*i - c*g; F = d*c - a*f; G = d*g - e*g; H = b*g - a*h; I = a*e - b*d; iTf = (1/(a*e - b*d))* [A B C; D E F; G H I]; A = iTf(1,1); B = iTf(1,2); C = iTf(1,3); D = iTf(2,1); E = iTf(2,2); F = iTf(2,3); G = iTf(3,1); H = iTf(3,2); I = iTf(3,3); % Ex sample % use point from previous step (x,y) % if inverse correct (u,v) must close to (154,154) W = G*x + H*y + I; u = (A*x + B*y + C) / W v = (D*x + E*y + F) / W |
% Quadrilateral to Quadrilateral % By Nemin Suksen % Master Degree FIBO, KMUTT, Thailand % Reference: pages 17-21 of Fundamentals of Texture Mapping and Image Warping, Paul Heckbert, % Master’s thesis, UCB/CSD 89/516, CS Division, U.C. Berkeley, June 1989, % URL=http://www.cs.cmu.edu/˜ph. % Thank Nung Navakun Sebang for paper sample data and suggestion clc; clear all; close all; %% Source Quadrilateral % 4 Point of Quadrilateral = (u0,v0), (u1,v1), (u2,v2), (u3,v3) u0 = 7; v0 = 171; u1 = 294; v1 = 168; u2 = 307; v2 = 2; u3 = 1; v3 = 2; %% Destination Quadrilateral % 4 Point of Quadrilateral = (x0,y0), (x1,y1), (x2,y2), (x3,y3) x0 = 10; y0 = 190; x1 = 310; y1 = 190; x2 = 310; y2 = 10; x3 = 10; y3 = 10; %% slove 8 equation to find 8 unknowns a-h C =[ u0 v0 1 0 0 0 -u0*x0 -v0*x0 u1 v1 1 0 0 0 -u1*x1 -v1*x1 u2 v2 1 0 0 0 -u2*x2 -v2*x2 u3 v3 1 0 0 0 -u3*x3 -v3*x3 0 0 0 u0 v0 1 -u0*y0 -v0*y0 0 0 0 u1 v1 1 -u1*y1 -v1*y1 0 0 0 u2 v2 1 -u2*y2 -v2*y2 0 0 0 u3 v3 1 -u3*y3 -v3*y3]; % [C] * [unknow] = [Destination 4 point] % slove to fine unknow matrix by invert C method D4p= [x0; x1; x2; x3; y0; y1; y2; y3]; Unknown = inv(C) * D4p a = Unknown(1); b = Unknown(2); c = Unknown(3); d = Unknown(4); e = Unknown(5); f = Unknown(6); g = Unknown(7); h = Unknown(8); i = 1; Tf = [a b c; d e f; g h i]; %% Ex sample %point in source quadrilateral = (154,154) u = 154; v = 154; % point in destination qudrilateral % w = gu+hv+1 % x = (au+bv+c)/w % y = (du+ev+f)/w w = g*u + h*v + 1; x = (a*u + b*v + c) / w y = (d*u + e*v + f) / w |
การทำแปลงจาก รูปสีเหลี่ยมจัตุรัสเป็นสีเหลี่ยมด้านไม่เท่ากัน หรือ การว๊าบ image wraping
Paper ที่ได้มาจาก พี่หนี่ง ขอบคุณมานะที่นี้