31 สิงหาคม 2553

ทดลองการว๊าบครั้งที่ 5

ข้อดี

Warp ตำแหน่งได้ถูกต้องทั้ง แกน X และ แกน y

ต้องปรับปรุง

การใช้ wiimote 2 ตัวตอบสนองได้ช้าลง

อาจแก้ไขการคำนวณการ Warp ใหม่ให้เร็วขึ้น โดยตัดแกนที่ไม่ได้ใช้ออกไป

แยกการอ่านค่าออกเป็น 2 Thread สำหรับ wiimote แต่ละตัว

ทดลองการว๊าบครั้งที่ 4

ทดสอบการว๊าบโดยเลื่อนกล้องกับโปรเจคเตอร์ในแกน Y

จะทำให้ตำแหน่งในแกน X ได้ถูกต้อง

งานที่จะทำต่อ

ใช้ wiimote 2 ตัวทำการว๊าบทั้ง 2 แกนจะทำให้

คำนวนตำแหน่งได้ถูกต้องในขณะที่เลื่อนระยะเข้าใกล้โปรเจคเตอร์

28 สิงหาคม 2553

ทดลองการว๊าบครั้งที่ 3

เปลี่ยน

1. เปลี่ยนอัลกอรึทึมที่ใช้ว๊าบ มีความเที่ยงตรงแต่ช้ากว่าแบบที่ใช้ในการทดลองครั้งที่

ปัญหาเดิมที่ยังไม่ได้แก้ไข

1.ติดปัญหาเรื่องการตอบสนอง ที่ยังช้าอยู่

แนวทางการแก้ไข

1. ใช้ 1 Thread ในการอ่านค่าจาก wiimote

2. ใช้ 1 Thread ในการ display ทางจอภาพ

 

แก้ปัญหาเรื่องมุม FOV ของ wiimote และโปรเจคเตอร์ ด้วยฐานตั้ง Wiimote และ โปรเจคเตอร์

ฐานตั้งนี้สามารถปรับมุมเอียงระหว่าง wiimote กับ โปรเจคเตอร์ได้

โดยด้านล่างมีไม้แผ่นใหญ่ติดแทปตีนตุ๊กแกไว้

และด้านล่างของwiimote และ  โปรเจคเตอร์ ก็ติดแทปตีนตุ๊กแกไว้เหมือนกัน


ทดลองการว๊าบครั้งที่ 2

พัฒนา

1.แก้มุม FOV ระหว่าง Wiimote กับ โปรเจคเตอร์ ด้วยฐานตั้งปรับมุมได้

ปัญหาใหม่

1.ติดปัญหาเรื่องการตอบสนอง

2.การวาบไม่ตรงในแนวแกน x ประมาณ 3 เซนติเมตร

27 สิงหาคม 2553

หามุม FOV ของ wiimote

 

ทดสอบทั้งหมด 2 ครั้ง

ได้ค่าต่างๆนำไปคำนวณด้วย Matlab ดังนี้

clc; clear all; close all;
%% Data 1
% fovy height
height = (28.0 + 30.0)/2;
Zprp = 0;
Zvp = 57;
fovyH = rad2deg(atan(height/2/Zvp))*2

% fovy width
width = (43.0 + 42.0)/2;
Zprp = 0;
Zvp = 57;
fovyW = rad2deg(atan(width/2/Zvp))*2

%% Data 1
% fovy height
height = (23.0 + 22.5 )/2;
Zprp = 0;
Zvp = 40;
fovyH = [fovyH rad2deg(atan(height/2/Zvp))*2]

% fovy width
width = (30.2 + 30.0)/2;
Zprp = 0;
Zvp = 40;
fovyW = [fovyW rad2deg(atan(width/2/Zvp))*2]

%% Fovy Average
mean(fovyH)
mean(fovyW)

FOV ด้าน Height = 30 องศา

FOV ด้าน Width = 41 องศา

จึงสรุปได้ว่า FOV ไม่ใช่ปัญหาที่ทำให้การว๊าบไม่สำเร็จ

ทดลองการว๊าบครั้งที่ 1

 

คาดว่าสาเหตุน่าจะมาจากการที่มุม FOV ของ Wiimote น้อยกว่ามุม FOV ของ โปรเจคเตอร์

ภาพที่ได้จึงไม่ครอบคลุม

 

เพื่อทดสอบสมมติฐานนี้ จึงต้องทำการหา มุม FOV ของ Wiimote

26 สิงหาคม 2553

YAMOROBOCON2010

ขอประชาสัมพันธ์โครงการและขอเชิญสมัครเข้าร่วมแข่งขันหุ่นยนต์ YAMOROBOCON2010

ทั้งนี้ สามารถติดตามรายละเอียดข่าวสารและสมัครเข้าร่วมการแข่งขันได้ที่

http://www.yamorobocon.com

การคำนวณพิกัด 2D หรือระนาบ เมื่อกำลังใช้งานพิกัด 3D ใน OpenGL แบบ Perspective Projection

การคำนวณพิกัด 2D หรือระนาบ เมื่อกำลังใช้งานพิกัด 3D ใน OpenGL แบบ Perspective

เมื่อเราตั้งค่า Projection Matrix เป็น 3D แบบ Perspective แล้ว

เรายังสามารถใช้การวาดรูปแบบ 2D ได้โดยสามารถคำนวณหา

ความกว้าง ความสูง และ พิกัดของ 2D ได้จาก Code การ Projection

glMatrixMode (GL_PROJECTION);                                    //set the matrix to projection
    glLoadIdentity ();
    gluPerspective (30.32, 4.0/3.0, 50.0, 300.0);               //set the perspective (angle of sight, width/height, near, far   )

และอีกค่าหนึ่งที่นำมาคิดคือ มุมมองของกล้อง

/*
* camera position, x,y,z, looking at x,y,z, Up Positions of the camera
*/
gluLookAt
(
    0.0, 0.0, 110.0,/* camera */
    0.0, 0.0, 0.0,    /* lens towards */
    0.0, 1.0, 0.0   /* up-vector */
);

จาก Code ข้างบนเราจะได้คำนวนหา

ขอบเขตความกว้าง [XWmin, XWmax]

ขอบเขตความยาว [YWmin, YWmax]

ได้ดังนี้

fovyH = 30.32;
aspect = 4/3;
Zvp = 110;
Zprp = 0;

height = 2 * Zvp * tan(deg2rad(fovyH/2));
YWmin = Zprp - height/2
YWmax = Zprp + height/2

width = aspect * height;
XWmin = Zprp - width/2
XWmax = Zprp + width/2

การคำนวณหามุม Fovy ของ 3M Projector Parameter

สูตรในการคำนวณมุม หามาจากหนังสือ 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 องศา

 

21 สิงหาคม 2553

คลาสวาบจากสีเหลี่ยมด้านไม่เท่า ไปยังสีเหลี่ยมด้านไม่เท่า Nemin c++ warping class

คลาสวาบจากสีเหลี่ยมด้านไม่เท่า ไปยังสีเหลี่ยมด้านไม่เท่า Nemin c++ warping class
เขียนขึ้นมาจากหลัก Inferring Projective Mappings
ในหนังสือ Fundamentals of Texture Mapping and Image Warping
อ่านเรื่องการ Warp ได้เพื่อจะได้เข้าใจมากขึ้น
ในที่นี้คือการเขียนโค้ดด้วยภาษา C++ หลังจากที่มี
เวอร์ชั่น Matlab ไปแล้ว
ตัวอย่างการเรียกใช้งาน

        /* source quadrilateral
         */
        int u0, u1, u2, u3, v0, v1, v2, v3;
        u0 = 7;
        v0 = 171;
        u1 = 294;
        v1 = 168;
        u2 = 307;
        v2 = 2;
        u3 = 1;
        v3 = 2;

        /* destination quadrilateral
         */
        int x0, x1, x2, x3, y0, y1, y2, y3;
        x0 = 10;
        y0 = 190;
        x1 = 310;
        y1 = 190;
        x2 = 310;
        y2 = 10;
        x3 = 10;
        y3 = 10;
       
        /* Set Warp parameter
         * for making transformation matrix
         */
        CWarp tr(u0, u1, u2, u3, v0, v1, v2, v3, x0, x1, x2, x3, y0, y1, y2, y3);
       
        /* warping point (u0,v0) in source quadrilateral
         * to point(x,y) in destination quadrilateral
         */
        int x,y;
        tr.warp(u0, v0, &x, &y);

ประสิทธิภาพการ Warp ใกล้เคียงกับเวอร์ชัน Matlab แต่ทำงานได้ไวกว่ามาก
Capture 

ใครสนใจดาวน์โหลดไปทดสอบกันได้ครับ

อัพบล็อกง่ายๆด้วย Windows Live Writer Beta

อัพบล็อกง่ายๆด้วย Windows Live Writer Beta
ดาวน์โหลด โปรแกรม
ทดสอบใส่รูป

ทดสอบใส่ video จาก youtube

ทดสอบใส่ตาราง

     
     
     

 

นอกจากนี้สามารถเขียนบลฺ็อกครั้งเดียว และอัพไปหลายๆที่ได้เลย เพราะผมเขียนบล็อกอยู่ 2 ที่

มี ภาพ Preview ให้ดูด้วย

image

ใครโปรเรื่อง HTML ยังแก้ไขได้โดยตรงด้วย

image

ลองเอาไปใช้กันดูนะครับ

ทดสอบการสร้างโปรเจคที่ใช้งาน wiiuse, OpenGL, OpenCV ร่วมกัน

ทดสอบการสร้างโปรเจคที่ใช้งาน wiiuse, OpenGL, OpenCV ร่วมกัน

ดาวน์โหลด

โค้ดที่ใช้ทดสอบ wiiuse

       /* Test wiimote
         */
        wiimote** wiimotes;
        int found, connected;

        /*
         *    Initialize an array of wiimote objects.
         *
         *    The parameter is the number of wiimotes I want to create.
         */
        wiimotes =  wiiuse_init(MAX_WIIMOTES);
        found = wiiuse_find(wiimotes, MAX_WIIMOTES, 5);
        if (!found) {
            printf ("No wiimotes found.");
            return 0;
        }
        wiiuse_rumble(wiimotes[0], 0);
        /*
         *    Disconnect the wiimotes
         */
        wiiuse_cleanup(wiimotes, MAX_WIIMOTES);

โค้ดที่ใช้ทดสอบ OpenCV

       /* test OpenCV
         */
        IplImage *img = cvLoadImage(".\\image.jpg");
        cv::namedWindow("Image:",1);
       
        IplImage *dst = cvCreateImage(cvGetSize(img),IPL_DEPTH_16S,3);
        IplImage *dst2 = cvCreateImage(cvGetSize(img),IPL_DEPTH_16S,3);
        cvLaplace(img, dst, 3);
        //cvLaplace(dst, dst2, 3);
        cv::imshow("Image:", dst);
        cvWaitKey();
        cvDestroyWindow("Image:");
        cvReleaseImage(&img);

 


โค้ดที่ใช้ทดสอบ OpenGL

       /* test OpenGL
         */
        char *targv[] = {""};
        glutInit (&argc, targv);
        glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH); //set the display to Double buffer, with depth
        glutGameModeString( "1024x768:32@30" ); //the settings for fullscreen mode
        glutEnterGameMode(); //set glut to fullscreen using the settings in the line above
        init (); //call the init function
        glutDisplayFunc (display); //use the display function to draw everything
        glutIdleFunc (display); //update any variables in display, display can be changed to anyhing, as long as you move the variables to be updated, in this case, angle++;
        glutReshapeFunc (reshape); //reshape the window accordingly

        glutKeyboardFunc (keyboard); //check the keyboard
        glutMainLoop (); //call the main loop}

20 สิงหาคม 2553

การคอมไพล์ไลบารี wiiuse ด้วย Visual Studio 2008

การคอมไพล์ไลบารี 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
image

2. ปรับ wiiuse project property
คลิกขวาที่ project wiiuse เลือก property
ไปที่ Confuguration Properties > C/C++ > General
ที่ Additional Include Directorties คลิก …
image
เพิ่ม 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
image

ไปที่ Confuguration Properties > Linker > Input
ที่ Additional Include Directorties คลิก …
image

เพิ่ม Link ไฟล์ odbc32.lib odbccp32.lib Ws2_32.lib hid.lib setupapi.lib
image

3. ปรับ wiiuseexample property
คลิกขวาที่ wiiuserexample เลือก Property
ไปที่ Confuguration Properties > C/C++ > General ใส่ ..\..\src
image

ไปที่ Confuguration Properties > Linker > Input
ที่ Additional Dependencies ใส่ wiiuse.lib  คลิก OK

image

แค่นี้เป็นอันเสร็จคอมไพล์ได้แน่นอน งานนี้ขอขอบคุณ ป้อฝาแฝดที่ช่วยทำและให้คำแนะนำ

11 สิงหาคม 2553

การใช้งาน Wiimote ควบคุม Lego NXT

การใช้งาน Wiimote ควบคุม Lego NXT

แนะนำการใช้งาน Wiimote เป็นรีโมทของเครื่องเล่นเกม wii

และชุดฝึกทักษะหุ่นยนต์ LegoNXT ร่วมกัน
สิ่งที่ต้องเตรียม
1. wiimote
2. คอมพิวเตอร์ที่มีบลูทูธ 2.0+EDR
3. Lego NXT

โปรแกรม
1. Visual Studio C# 2008 ถ้าไม่มีแนะนำ Version ฟรี
2. Managed Library for Nintendo's Wiimote สำหรับติดต่อกับ wiimote
3. LogoAForge.NET Framework สำหรับติดต่อกับ Lego NXT ติดตั้งให้เรียบร้อย

เริ่มกันเลย
เปิดโปรเจ็ค ที่อยู่ใน samples\WiimoteTestCS ของ WiimoteLib เพื่อเปิด VS
เพิ่ม library

ให้เพิ่ม Reference ของ AForge.Robotics.Lego จะของในที่ๆติดตั้ง AForge \AForge.NET\Framework\Release


เปิด code ของ Form1.cs


ในส่วนของ Header ด้านบนเพิ่ม
using AForge.Robotics.Lego;


ในส่วนของ Constructor เพิ่ม
// 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
        };
เพิ่ม object ของ Lego NXT


        // 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");
                }    
            }
        }


เพิ่ม Method สำหรับการเดิน

Link เมื่อกดปุ่ม Wiimote แล้วสั่งให้มอเตอร์ทำงาน หุ่นยนต์ก็จะเดิน
ภายใน Method UpdateWiimoteState จะมีตัวแปร ws ของ wiimote อยู่

ซึ่งเราจะใช้คำสั่ง if เช็คว่ามีการกดปุ่มนั้นๆหรือไม่ ถ้ามีเราจะสั่งให้หุ่นยนต์ เคลื่อนที่
โค๊ดตัวอย่างการกดปุ่มขึ้น
            if (ws.ButtonState.Up)
            {
                // your code when Press Up Buttom
            }

 เพียงเท่านั้นเราก็เชื่อมต่อ Wiimote กับ Lego NXT ได้แล้ว
อ่อ มันต้องเชื่อมต่อกันผ่านคอมนะครับ เชื่อมกันโดยตรงไม่ได้

ดาวน์โหลดซอร์สโค๊ด ไปศึกษาดูนะครับ
ติดอะไรก็เมลมาถามได้




09 สิงหาคม 2553

โค๊ดตัวอย่างการ warp Quadrilateral to Quadrilateralโดยใช้ Go Wrap

โค๊ดตัวอย่างการ warp Quadrilateral to Quadrilateralโดยใช้ Go Wrap Matlab
มีการใช้ Go Wrap Matlab Library ดาวน์โหลดที่นี่
keyword :warping Quadrilateral to Unit Square 
input : จุดมุมในสีเหลี่ยมใดๆปลายทาง 4 จุด คือ (u0,v0), (u1,v1), (u2,v2), (u3,v3)
output : Transformation matrix และการทดสอบwarp จุด
% 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)





โค๊ดตัวอย่างการ warp case 2

โค๊ดตัวอย่างการ warp case 2
มีการใช้ Go Wrap Matlab Library ดาวน์โหลดที่นี่
keyword :warping Quadrilateral to Unit Square 
input : จุดมุมในสีเหลี่ยมใดๆปลายทาง 4 จุด คือ (s0,t0), (s1,t1), (s2,t2), (s3,t3)
output : Transformation matrix และการทดสอบwarp จุด
% 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)



โค๊ดตัวอย่างการ warp case 1

โค๊ดตัวอย่างการ warp case 1
keyword :warping Unit Square to Quadrilateral
input : จุดมุมในสีเหลี่ยมใดๆปลายทาง 4 จุด คือ (x0,y0), (x1,y1), (x2,y2), (x3,y3)
output : Transformation matrix และการทดสอบwarp จุด

% 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

ทำ Image Wraping

ทำ Image Wraping
เริ่มต้นอ่าน Android ของพี่หนึ่ง ที่ Android
และได้อ่าน Paper ของ Paul Heckbert ในหนังสือ Fundamental of Texture Mapping and Image Wraping โหลดได้ ที่นี่
จึงค้นพบวิธี Wrap อีกวิธีหนึ่งซึ่งเร็วกว่าซึ่งจะมาดูว่าเร็วกว่าอย่างไร

การ Wrap จาก Quadrilateral to Quadrilateral แบ่งเป็น 2 แบบ
1. การแปลงแบบ Case 3 คือ แปลงจาก Quadrilateral to Quadrilateral โดยตรง
จะใช้ สมการ 8 สมการ เพื่อหา Unknown 8 ตัว a-h

สำหรับ map จุด (u,v) ใน Quadrilateral ต้นทางไปยัง จุด(x,y) ใน Quadrilateral ปลายทาง
โค๊ดตัวอย่างใน matlab

2. ทำ Case 2 แล้วตามด้วยการทำ Case 1
ซึ่งสูตรได้มาจากการแก้สมการเพื่อหา Case 1 ซึ่งเป็น Unit Square to Quadrilateral  โดยเริ่มหามาจาก
สมการในรูปทั่วไป Quadrilateral to Quadrilateral แบบ 8x8 symtem


นำมาแทนค่าในสมการด้วยค่าดังนี้

จะได้ 8 สมการดังนี้



จากใน Paper เค้าบอกว่า สามารถคำนวณเป็น Close Form ได้เลย
หากแทนเพิ่ม พจน์

จะได้ Close Form ดังนี้
ซึ่งทำให้คำนวน a-h พารามิเตอร์ของ case 1 ได้ วิธีนี้มีข้อดีที่ใช้เวลาในการคำนวนน้อยกว่าแบบแรกมาก
โค๊ดตัวอย่าง case 1 ใน matlab
ต่อจากนั้นคำนวนหา case 2 โดย คำนวนหา Unit Square to Quadrilateral (ทิศทางจะตรงข้ามกับลูกศรในภาพ)
เมื่อได้ a-h พารามิเตอร์แล้วค่อยนำมาทำ Inverse หา A-H แทน
ด้วยสมการ (สมการนี้ใช้อักษร s t เป็นจุดใน Unit Square แทน u v ตามลำดับ)

 
ดังนั้นหากเราต้องการหาว่า (x,y) ใน Quadrilateral to Quadrilateral สามารถใช้งานได้ดังนี้

จะได้ (s,t) ที่อยู่ใน Unit Square
โค๊ดตัวอย่าง case 2 ใน matlab

x' = (as + bt +c)/(gs + ht + i)
y' = (ds + et +f)/(gs + ht + i)
จะได้ (x',y') ที่อยู่ใน Quadrilateral ปลายทางที่เราต้องการ Wrap ไป
โค๊ดตัวอย่างการ warp Quadrilateral to Quadrilateralโดยใช้ Go Wrap Matlab

ทดสอบความคลาดเคลื่อนการ warp แบบ Case 3 เทียบ กับ Case 1 + Case 2
โดยใช้จุดมุมของสีเหลี่ยมต้นทางไปยังสีเหลี่ยมปลายทาง
แล้ววัดค่าความคาดเคลื่อนจากจุดมุมที่แท้จริงของสีเหลี่ยมปลายทาง
ได้ผลออกมาดังนี้
Go Wrap Matlab Library

หมายเหตุระยะทางหน่วยเป็น Pixel

จะสังเกตุได้ว่าค่าที่คลาดเคลื่อนเกิดขึ้นในแนวแกน x เท่านั้น และคลาดเคลื่อนอยู่ในระดับที่ยอมรับได้

ดาวน์โหลด Go Wrap Matlab Library










07 สิงหาคม 2553

ซอร์สโค้ด Matlab การทำอินเวอร์ส Transformation ของการแม็บ สีเหลี่

ซอร์สโค้ด Matlab การทำอินเวอร์ส Transformation ของการแม็บจุดใน สีเหลี่ยมใดๆ ไปสีเหลี่ยมใดๆ
Keyword: การแม็บจุดจากสี่เหลี่ยมใดๆไปยังสี่เหลียมใด, Quadrilateral to Quadrilateral mapping, inverse, matlab, Algorithm, Source Code

ถ้าหากเรามีพารามิเตอร์  a-h ที่แปลงจาก สีเหลี่ยมQ ไป สีเหลี่ยมR แล้ว
หากต้องการหาพารามิเตอร์ a-h ที่แปลงจาก สีเหลี่ยมR ไป สีเหลี่ยมQ
สามารถใช้วิธีการ Inverse ได้
การทำ Inverse มี 2 วิธี
1 หาอินเวอร์สเมตริกธรรมดาตรงๆ
ข้อดี ง่ายตรงไปตรงมาก ได้ค่าที่ถูกต้อง
ข้อเสีย ใช้เวลาในการคำนวณมาก
input: Transformation matrix ที่มีพารามิเตอร์ a-h
output: Transformation matrix ที่มีพารามิเตอร์ A-H
%% 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

2 หาอินเวอร์แบบใช้สูตรClose From(ไม่ทราบที่มาขออภัยด้วย search เจอในเน็ต)
ข้อดี ใช้เวลาคำนวนน้อย เขียนโปรแกรมง่าย
ข้อเสีย ได้ค่าที่ใกลเคียง มี Error เพียงเล็กน้อย
input: Transformation matrix ที่มีพารามิเตอร์ a-h
output: Transformation matrix ที่มีพารามิเตอร์ A-H
%% 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

ดาวน์โหลด Source Code

ข้อมูลอื่นๆที่เกี่ยวข้อง
การหา Transformation Matrix การแม็บจุดจากสี่เหลี่ยมใดๆไปยังสี่เหลียมใด

ซอรสโค้ด Matlab การแม็บจุดจากสีเหลี่ยมใดๆต้นทาง ไปยังจุดที่อยู่ใน

ซอรสโค้ด Matlab การแม็บจุดจากสีเหลี่ยมใดๆต้นทาง ไปยังจุดที่อยู่ในสี่เหลี่ยมใดๆปลายทาง
Keyword: การแม็บจุดจากสี่เหลี่ยมใดๆไปยังสี่เหลียมใด, Quadrilateral to Quadrilateral mapping, inverse, matlab, Algorithm, Source Code

input :
    จุดมุมในสีเหลี่ยมใดๆต้นทาง 4 จุด คือ (u0,v0), (u1,v1), (u2,v2), (u3,v3)
    จุดมุมในสีเหลี่ยมใดๆปลายทาง 4 จุด คือ (u0,v0), (u1,v1), (u2,v2), (u3,v3)
    จุดที่ต้องการแม็บ สีเหลี่ยมต้นทาง ไปยังสีเหลี่ยมปลายทาง (u,v)  
output:
    จุดที่อยู่บนสีเหลี่ยมปลายทาง
Source Code
% 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
ดาวน์โหลด Source Code

เกร็ดความรู้เรื่องอินเวอร์ส
 หากเรามีพารามิเตอร์  a-h ที่แปลงจาก สีเหลี่ยมQ ไป สีเหลี่ยมR แล้ว
หากต้องการหาพารามิเตอร์ a-h ที่แปลงจาก สีเหลี่ยมR ไป สีเหลี่ยมQ
สามารถใช้วิธีการ Inverse ได้

06 สิงหาคม 2553

การทำแปลงจาก รูปสีเหลี่ยมจัตุรัสเป็นสีเหลี่ยมด้านไม่เท่ากัน หรือ การว๊าบ image wraping

การทำแปลงจาก รูปสีเหลี่ยมจัตุรัสเป็นสีเหลี่ยมด้านไม่เท่ากัน หรือ การว๊าบ image wraping

Paper ที่ได้มาจาก พี่หนี่ง ขอบคุณมานะที่นี้
แต่ค่อนข้างยืดยาว
จึงต้อง Search แต่ keyword ว่า
image wraping จะเจออย่างอื่นที่ไม่ค่อยเกี่ยวซะส่วนใหญ่
จึงค้นพบว่าเราควรใช้
keyword : square to quadrilateral
เจอ สไลด์การสอนที่อ่านง่ายมากมาย
ลองโหลดไปอ่านกันดูได้ ที่นี่

01 สิงหาคม 2553

ใช้อากาศ เป็นฉากโปรเจคเตอร์

นอกจาก Hologram ที่เป็นการฉายภาพ 3 มิติ ในอากาศ
ยังมีการฉายภาพโดยโปรเจคเตอร์โดยใช้อากาศเป็นฉาก ซึ่งถ้ามองในมุมมองเดียว
จะได้ภาพที่ไม่แตกต่างจาก Hologram เลยทีเดียว นอกจากนี้ยังมีสีสันดีกว่าด้วย
แต่ฉากค่อนข้างจะพริ้วไหว ยังไม่คงที่เท่าที่ควร

ผมยังไม่ทราบหลักการที่แน่ชัด ว่ามันทำงานอย่างไร
อาศัยดูจากคลิป และการคาดคะเนจาก Hardware ว่าน่าจะใช้หลักการสร้างความแตกต่างของความหนาแน่น
ของอากาศ ทำให้เหมือนกับว่าแสงเดินทางผ่านตัวกลางที่มีดัชนีหักเห ไม่เท่ากัน
จึงน่าจะทำให้เกิดการกระเจิงออกมาเป็นภาพ http://numpang69.exteen.com/20060613/entry-8
เช่นเดียวกับที่ทำให้เราเห็นภาพขอบฟ้า

ตัวฉากเป็นที่เป่าลมขนาดใหญ่
เข้าไปดูรายละเอียด Hardware ที่ http://www.io2technology.com/specifications

ดุตัวอย่างการใช้งานได้ที่ http://www.io2technology.com/examples


ทำให้เกิดไอเดียขึ้นมาว่า ถ้าเราไม่สามารถทำการ Flow ของอากาศให้มีคุณสมบุติดีเท่าเค้าได้เราสามารถที่จะ
สร้างอากาศให้มีคุณสมบุติดังกล่าวโดยใช้ตัวกลางอื่นๆที่หาได้ง่ายกว่าแทนได้หรือไม่ เช่นที่เคยเห็นการฉายภาพของม่านน้ำพุ
เลยเห็นเจ้าเครื่องอโลม่าเทราปี้ น่าจะใช้ควันขาวๆนี่ได้เหมือนกัน ถ้ามีเวลาว่างต้องลองทำดูหน่อยละ

บริเวณที่เป็นแสงหลอดไฟที่โดนควัน ดูแล้วเห็นการกระเจิงชัดเจนเลย