Tuesday, March 30, 2010

โปรแกรมแรกกับ OpenCV

ทดลองโหลดรูปและแสดงผลด้วย OpenCV ตามโค้ดต่อไปนี้ครับ  สมมติว่าเรามีรูปชื่อ lena.jpg ในไดเรกทอรีเดียวกับโค้ดนี้ครับ



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

แสดงรหัสโปรแกรมบนบล็อก (Syntax Highlight on Blog)

สำหรับผู้ที่ใช้บล็อก เช่น blogspot และต้องการแสดงผลรหัสโปรแกรมให้สวยงาม สามารถทำได้ดังนี้ครับ
วิธีแรก
ใช้บริการของ http://hilite.me/ แค่แปะโค้ดของเรา เลือกภาษาที่ต้องการ แล้วก๊อป HTML โค้ดมาแปะ เรียบร้อยสวยงามครับ เช่น จากเดิม
#include<iostream>
using namespace std;

int main()
{
    cout<<"Hello World!";
    system("PAUSE");
    return 0;
}

เป็น
#include<iostream>
using namespace std;

int main()
{
    cout<<"Hello World!";
    system("PAUSE");
    return 0;
}


วิธีที่สอง
ใช้ Syntax highlighter
1. แก้ไข template ของบล็อก โดยเพิ่มคำสั่งต่อไปนี้ ในส่วนของ head แท็ก (ต้นๆ เลยก็ดีครับ)
 <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'></script>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
ให้เลือกเฉพาะภาษาโปรแกรมที่ต้องการ hilight ครับ ส่วนที่ไม่ต้องการก็ลบออกได้

2. จากนั้น ในส่วนของเนื้อหาที่ต้องการ hilight ก็เข้าไปแก้ไข html โดยใช้คำสั่งต่อไปนี้
<script type="syntaxhighlighter" class="brush: cpp"><![CDATA[
รหัสโปรแกรม
]]></script>
ให้สังเกตว่าในที่นี้ใช้ภาษาซีพลัสพลัสครับ

>
ปล. อย่าลืม เปิดจาวาสคริปต์ให้เว็บ http://alexgorbatchev.com และเว็บ http://amazonaws.com ด้วยนะครับ

ที่มา:
1. http://alexgorbatchev.com/wiki/SyntaxHighlighter
2. http://blog.cartercole.com/2009/10/awesome-syntax-highlighting-made-easy.html
3. http://geektalkin.blogspot.com/2009/11/embed-code-syntax-highlighting-in-blog.html

สรุป FIS

จากบทความที่ผ่านมาเรื่อง Fuzzy Inference System
หากจะสรุปขั้นตอนโดยย่อ สามารถสรุปได้ดังภาพต่อไปนี้ครับ (ที่มา: fuzzy logic toolbox user's guide, www.mathworks.com) ซึ่งภาพนี้อธิบายหลักการทั้งหมดได้ดีและเข้าใจได้ง่ายด้วยครับ

Monday, March 29, 2010

Fuzzy Inference System

Fuzzy Inference System หรือ FIS คือระบบที่ทำการหาข้อสรุป ผลลัพธ์ โดยใช้กระบวนการทาง Fuzzy logic
เช่น จะต้องการตอบโจทย์ที่ว่า

"ควรจะให้ทิปพนักงานร้านอาหารเท่าใด ถ้าหากว่าปริมาณทิปขึ้นอยู่กับคุณภาพการบริการของพนักงาน และรสชาติของอาหาร"

โดยทั่วไป FIS จะมีสองแบบคือ แบบ Mamdini และ แบบ Sugeno ซึ่งหลักการใกล้เคียงกัน แต่ต่างกันที่ขั้นตอนการได้มาซึ่งผลลัพธ์ (Defuzzification)

ขั้นตอนการหาข้อสรุปโดยใช้ FIS จะเป็นดังนี้
1. กำหนด Input และ Output
Input:
1. คุณภาพการบริการ (Service) แบ่งเป็น 3 ระดับ แย่ (poor)  ดี (good) ดีมาก (excellent) อยู่ในช่วง 0-10
2. รสชาติของอาหาร (Food) แบ่งเป็น 2 ระดับ แย่ (poor)  ดีมาก (excellent) อยู่ในช่วง 0-10
Output:
ทิป แบ่งเป็น 3 ระดับ น้อย (small) ปานกลาง (normal) มาก (large) อยู่ในช่วง 0-30%

สมมติว่า ในโจทย์ข้อนี้ เราต้องการหาค่าทิป เมื่อ คุณภาพการบริการอยู่ที่ 3 และ รสชาติของอาหารอยู่ที่ 8

2. กำหนดดีกรีของ Input และ Output ให้สัมพันธ์กับระดับที่กำหนดไว้
ขั้นตอนนี้ก็คือการกำหนดรูปร่างของ membership function นั่นเอง ซึ่งมีหลายรูปแบบเช่น สามเหลี่ยม คางหมู gaussian ฯลฯ และมักจะถูกกำหนดโดยอาศัยประสบการณ์ หรือแบบสอบถามจากผู้เชี่ยวชาญต่างๆ

สมมติว่าเรากำหนดดังนี้
Input:
1. Service เป็นแบบ gaussian



2. Food เป็นแบบ trapezoid

Output:
Tip เป็นแบบ triangle


3. กำหนดกฎ (Rules) ของการตัดสินใจ
Rule 1: ถ้าบริการแย่ หรือ รสชาติแย่ จะทิปน้อย
Rule 2: ถ้าบริการดี จะทิปปานกลาง
Rule 3: ถ้าบริการดีมาก หรือ รสชาติดีมาก จะทิปมาก

4. ทำการ Fuzzy Input นั่นคือหาว่า ถ้า Input เป็นเท่านี้ จะได้ดีกรีเท่าใด โดยดูจากกราฟของ membership function ในข้อ 2 และกฎที่ตั้งไว้ในข้อ 3 ตัวอย่างเช่น
Rule 1: ถ้าบริการแย่ หรือ รสชาติแย่ จะทิปน้อย
จากโจทย์ ตอนนี้ Input คือ service = 3, food =  8

สนใจข้อความแรก ถ้าบริการแย่ จะได้ดีกรีเท่าใด
ดังนั้น เราจะเลือกกราฟของ bad service แล้วหาค่าดีกรี เมื่อ service = 3 (เส้นสีแดง) ซึ่งจะได้ ดีกรีประมาณ 0.2 (ค่าตามแกน y)
เช่นเดียวกัน สำหรับข้อความที่สอง ถ้ารสชาติแย่ จะได้ดีกรีเท่าใด
ดังนั้น เราจะเลือกกราฟของ bad food แล้วหาค่าดีกรี เมื่อ food = 8
จะได้ดีกรีเป็น 0 เพราะไม่ตัดกราฟเลย ตามรูป
จากกฎข้อแรกนี้ คือ "ถ้าบริการแย่ หรือ รสชาติแย่ จะทิปน้อย" สังเกตว่าเราเชื่อมต่อทั้งสองกรณีด้วยคำว่า หรือ ซึ่งก็คือ OR หรือค่า max ตามหลักการของ fuzzy logic นั่นเอง 

ดังนั้น จะได้ว่าดีกรีของกฎที่ 1 จะเท่ากับ max(0.2, 0) = 0.2

เมื่อพิจารณาทุกกฎตามหลักการนี้แล้ว ก็จะได้ผลลัพธ์ดังภาพต่อไปนี้



นั่นคือ
จากกฎข้อ 1 ได้ดีกรีประมาณ 0.2
จากกฎข้อ 2 ได้ดีกรีประมาณ 0.5
จากกฎข้อ 1 ได้ดีกรีประมาณ 0.5

5. ทำการ implication เพื่อหาผลลัพธ์ของแต่ละกฎ
เมื่อได้ดีกรีตามแต่ละกฎแล้ว ขั้นตอนต่อไปคือการเอาไปเปรียบเทียบกับ membership function ของผลลัพธ์ที่คาดการณ์ไว้ ซึ่งจะมีการใช้โอเปอร์เรเตอร์ได้หลายรูปแบบ ที่นิยมกันก็ืคือ ค่าต่ำสุด (min) นั่นคือ เมื่อเอาดีกรีไปเทียบกับกราฟผลลัพธ์ทางขวามือ ผลลัพธ์คือพื้นที่กราฟที่อยู่ใต้ค่าดีกรีนั้น ดังรูปต่อไปนี้ซึ่งแสดงผลลัพธ์ของกฎแรก

Rule 1: ถ้าบริการแย่ หรือ รสชาติแย่ จะทิปน้อย

ให้สังเกตว่า เราจะต้องเลือกกราฟให้สอดคล้องกับกฎด้วย เช่น กราฟผลลัพธ์ก็ต้องเลือกส่วนที่เป็น "ทิปน้อย" มาพิจารณา ไม่ได้เอามาทั้งหมด

เมื่อพิจารณาทุกกฎแล้ว จะได้ผลลัพธ์ดังนี้



6. รวมผลลัพธ์ทั้งหมดเข้าด้วยกัน (aggregation)
จากขั้นตอนที่ 5 เราจะได้ผลลัพธ์ของแต่ละกฎในรูปของ fuzzy set (ค่าประมาณในแต่ละกฎว่าผลลัพธ์จะอยู่ในช่วงใด) จากนั้นเราจะรวมผลลัพธ์ทั้งหมดเข้าด้วยกัน ซึ่งก็จะต้องมีวิธีการรวม ว่าจะใช้โอเปอร์เรเตอร์แบบใดอีก ซึ่งในที่นี้จะใช้การรวมแบบ max คือเอาค่าสูงสุดที่เป็นไปได้จากผลรวม

ผลลัพธ์จากการรวมแบบหาค่าสูงสุด


7. ทำการ Defuzzification เพื่อหาผลลัพธ์สุดท้าย
ผลลัพธ์ของขั้นตอนที่ 6 ยังอยู่ในรูปแบบของ fuzzy set นั่นคือ คำตอบที่ได้ควรจะอยู่ในพื้นที่ของกราฟที่กำหนด เืพื่อที่จะให้ได้ผลลัพธ์ที่ออกมาชัดเจนเป็นตัวเลข เช่น ทิปจะเป็นกี่เปอร์เซนต์ จำเป็นต้องแปลงค่า fuzzy set ให้เป็นเลขตัวเดียว ขั้นตอนนี้เรียกว่า Defuzzification ซึ่งทำได้หลายแบบ เช่น การหาค่า centroid ของพื้นที่, การหาค่าสูงสุดของทั้งหมด, การหาค่าต่ำสุดของค่าสูงสุดทั้งหมด ฯลฯ ในที่นี้จะใช้การหาค่า centroid ซึ่งจะได้ผลลัพธ์ดังเส้นสีแดงในรูปต่อไปนี้ ซึ่งจะได้ว่าค่าทิปควรจะเป็น 18% โดยประมาณ



โดยสรุป ขั้นตอนทั้งหมดของ FIS จะสามารถแสดงได้ดังรูป

 

เสร็จเรียบร้อยแล้วครับ การแก้ปัญหาโดยใช้ Fuzzy Inference System

Saturday, March 27, 2010

ติดตั้ง OpenCV 2.0 กับ Dev-C++

ขั้นตอน


1. ดาวน์โหลด Dev-C++ จาก http://www.bloodshed.net/dev/devcpp.html และติดตั้งให้เรียบร้อย 


2. ดาวน์โหลด OpenCV 2.0 จาก http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.0/ 


3. ติดตั้ง OpenCV โดยสมมติว่าติดตั้งที่ c:\OpenCV2.0

4. เรียกใช้งาน Dev-C++ เลือกเมนู Tools/ Compiler Options
สร้างโปรไฟล์ของคอมไพเลอร์ใหม่ให้ชื่อว่า OpenCV (ขั้นตอนนี้อาจจะไม่ต้องทำก็ได้) จากนั้นกำหนดพารามิเตอร์ของ linker ดังนี้
-llibcxcore200 -llibcv200 -llibcvaux200 -llibhighgui200 -llibml200
ดังรูปต่อไปนี้ 


5. คลิกเลือกแทบ Directories เพิ่มรายละเอียดในหัวข้อ Binaries ดังนี้ 


6. เพิ่มรายละเอียดในหัวข้อง Libraries และ C++ Includes ดังนี้
7. เข้าไปที่ include ไดเรกทอรีของ OpenCV 2.0 เช่น c:\OpenCV2.0\include\opencv แล้วแก้ไขไฟล์ชื่อ cxoperations.hpp แถวๆบรรทัดที่ 68 จากเดิม

#if __GNUC__ >= 4
เปลี่ยนเป็น
#if __GNUC__ >= 4 || __MINGW32__
บันทึกไฟล์นี้
8. ทดสอบโปรแกรมกันง่ายๆ ตามนี้ครับ สมมติว่ามีรูปชื่อ lena.jpg ในไดเรกทอรีเดียวกับตัวโค้ดนะครับ

9. จากนั้นก็คอมไพล์ แล้วรันดูผลลัพธ์ครับ

ขอบคุณข้อมูลต้นฉบับจาก
1. http://n2.nabble.com/Configuration-help-OpenCV-2-0-with-Dev-Cpp-td3943011.html
2. http://opencv.willowgarage.com/wiki/InstallGuide