คลังเก็บหมวดหมู่: Linux

Deep Learning กับ nvidia jetson nano ตอนที่ 1

ตอนนี้ เราจะมาทดลองรันโปรแกรมบน jetbot กัน โดยจะเป็น examples ที่มากับตัว install 2 ตัวอย่างแรกจะเป็นการแนะนำการเขียนโปรแกรมเพื่อควบคุม jetbot ทั้งด้วย widgets และจอย

โปรแกรมตัวอย่างเขียนด้วย jupyter notebook และระบบที่รัน jetbot ก็ลงมาให้เรียบร้อยแล้ว เราสามารถรันแบบรีโมทผ่านบราวเซอร์จากเครื่องคอมเราได้เลย โดยเราก็รัน jetbot ด้วย power bank ทีติดตั้งไว้แล้ว เพื่อไม่ให้เป็นอุปสรรคในการเคลื่อนที่ของ jetbot การทดลองรันก็เพียงแค่เปิดไฟล์ ขึ้นมาแล้วให้มันรัน จะทีละส่วน(เค้าเรียกว่า cell)เพื่อทำความเข้าใจ หรือสั่งรันทั้งหมดเลยก็ได้ แต่ไม่แนะนำ เพราะ cell ท้ายๆ อาจจะเป็นการสั่งหยุดการทำงาน

ตัวอย่างถัดมา เริ่มน่าตื้นเต้นและปวดหัวขึ้นมาบ้างแล้ว เพราะจะเริ่มใช้งาน deep learning โดยตัวอย่างนี้จะเป็นการทำให้เคลื่อนที่หลบสิ่งกีดขวางได้ โดยจะแบ่งโค้ดเป็น 3 ไฟล์ 3 ขั้นตอน โดย

1. ขั้นตอนแรก จะเป็นการเก็บ samples โดยโค้ดจะทำการเก็บภาพและให้เราแยกว่าภาพไหนคือ blocked หุ่นจะไปต่อไม่ได้ หรือ ภาพไหนคือ free หุ่นสามารถเคลื่อนที่ไปได้ เพื่อจะนำไป train
2. ทำการ train ขั้นตอนนี้ยุ่งยากหน่อย ผมพบว่า หากเก็บ samples จำนวนมาก (> 100) จะทำการ train บน jetbot ไม่สำเร็จ มีอาการดับไปซะเฉยๆ (เรื่องนี้ เดี๋ยวว่ากันอีกที) ดังนั้นจึงต้องทำการ train บนเครื่อง pc แทน ซึ่งใช้เป็น ubuntu 18.04 ก็ต้องไปทำการ install โปรแกรมที่จำเป็นทั้งหมด เรียกว่า ก็ต้องให้เหมือนบน jetbot นั่นเอง
หลังจากงมอยู่นาน จึงได้ขั้นตอนการ install ดังนี้

  • ลง anaconda ก็จะได้ python มาด้วย
  • ลง pytorch โดยเลือกได้ว่าจะใช้ cuda หรือไม่ ซึ่งบางคนใช้การ์ดจอ nvidia อาจอยากใช้ gpu ในการคำนวณ ก็ต้องไปลง driver cuda ก่อนนะ
  • ลง jupyter (อันนี้ไม่แน่ใจว่าตอนลง anaconda มันลงให้เลยอัตโนมัติแล้วหรือเปล่า)

*** ข้อที่ต้องระวังคือ เวอร์ชั่นของ pytorch บนเครื่องที่ใช้เทรนกับบน jetbot จะต้องเหมือนกัน ไม่งั้นจะโหลดโมเดลที่เทรนมาไม่ได้ ของผมใช้วิธีอัพเกรด jetpack เป็น เวอร์ชั่น 4.4 และอัพเกรด pytorch ไปเป็นเวอร์ชั่น 1.6

3. คือการนำ model ที่เทรนได้มาใช้งาน ซึ่งตอนนี้เจอปัญหาว่า แค่ออกตัวก็ดับตายสนิท ฮ่าๆ จากที่ลองหาข้อมูลในฟอรั่มดู น่าจะเป็นจังหวะมอเตอร์เริ่มหมุน พร้อมๆกับการที่กล้องทำงานจับภาพ น่าจะกินกระแสแบบพุ่งขึ้นทันทีทันใดก็เลยดับไป ลองใช้วิธีเขียนโค้ดให้มอเตอร์หมุนไปสักแป๊บนึงก่อนค่อยเริ่มจับภาพ ก็ใช้ได้ผลนะ

*เดี๋ยวจะลองเปลี่ยนไปใช้กล้อง USB ดูบ้างว่าอาการจะแตกต่างกันมั้ย

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

Deep Learning กับ nvidia jetson nano ตอนที่ 0

ตั้งใจจะเขียนเป็นซีรียส์ หนึ่งเพื่อเป็นการสรุปข้อมูลที่ได้เรียนรู้ สองก็เพื่อเป็นประโยชน์แก่ผู้ที่สนใจ

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

คำถาม คือ ทำไมต้อง jetbot ทำไมต้อง nvidia jetson nano
– เพราะมันฮอต และมันง่าย เนื่องจากมีเครื่องมือ มีซอฟแวร์ มีไกด์ไลน์ ให้เราทำตามไปก่อน ทำให้เริ่มต้นได้ง่าย ตัวบอร์ดถึงแม้จะราคาสูงกว่า raspberry pi ไปพอสมควร แต่ผมว่าคุ้มนะ
– ตัว hardware อุปกรณ์ไม่เยอะ ประกอบง่าย บัดกรี ไม่กี่จุด ก็เล่นได้ละ

เพิ่มเติมอีกหน่อย
nvidia ไม่ได้มีเพียงแค่โปรเจ็ค jetbot เท่านั้น ยังมีโปรเจ็คอื่นๆ ซึ่งใช้ซอฟแวร์ ISAAC SDK เช่น Kaya robot ก็จะมีอุปกรณ์ที่ต้องประกอบมากขึ้น
หรือถ้าไม่ใช้ SDK จาก nvidia จะไปใช้ ROS ก็ได้ ก็จะมีโปรเจ็คอย่างเช่น racecar ซึ่งแตกย่อยไปอีกหลายโปรเจ็คจากหลากหลายนักพัฒนา มีรายละเอียดที่แตกต่างกันในเรื่องของการใช้ hardware บางตัว

คำถามต่อมา แล้วเกี่ยวอะไรกับ deep learning
– deep learning มันก็คือเรื่องของ AI กรณีศึกษาในเรื่องนี้มักเกี่ยวข้องกับ vision system เกี่ยวข้องกับภาพ เช่น รู้จำป้ายทะเบียน รู้จำสิ่งกีดขวาง การนำทาง ดังนั้น jetbot หุ่นที่มีล้อ และติดกล้อง มันจึงเป็นอะไรที่เหมาะมากในการเอามาเรียนรู้ แถมสนุกด้วย

เริ่มต้นยังงัย
– อย่างน้อย ก็ต้องมีความรู้ มีประสบการณ์ ทั้ง hardware และ software สักหน่อย ใครที่ไม่เคยประกอบหุ่นเล่นเลย ก็ไปหาชุดคิทประกอบหุ่นยนต์มาลองเล่นก่อน ลองดูที่ www.ioteshop.com ร้านของผมเองก็มี อิอิ ให้รู้จักส่วนประกอบต่างๆของตัวหุ่นยนต์ หลักการไฟฟ้า อิเล็กทรอนิกส์เบื้องต้น อาจจะต้องมีเครื่องมือสำหรับงานประกอบ งานบัดกรี ต่างๆ
– ส่วน software ก็ต้องรู้เรื่อง linux เคยใช้งานมาบ้าง อ่านภาษาอังกฤษพอได้ เพราะต้องไป download และอ่านข้อมูลจากเว็บของ nvidia ส่วนภาษาที่ใช้เขียน สำหรับ jetbot นี้เป็น python ก็มีพื้นฐานสักหน่อย ภาษาอื่นก็ได้แต่เข้าใจหลักการเขียนโปรแกรม ก็โอเค

Hardware
1. nvidia jetson nano
ตัวบอร์ด jetson nano จริงๆประกอบด้วย 2 ส่วน คือ core module ที่มี CPU กับส่วนที่เรียกว่า carrier board ก็เป็นบอร์ดขยาย ที่ทำให้เราสามารถต่ออุปกรณ์อื่นๆได้ผ่านทางพอร์ทต่างๆ รวมทั้งจ่ายไฟให้มันด้วย
การจ่ายไฟให้ jetson nano ทำได้สองทาง คือผ่านทาง micro USB port และ jack DC เป็น 5V ทั้งคู่ เลือกเอาอย่างใดอย่างหนึ่ง โดยการใช้ jumper
ความแตกต่างนั้น ตามความเข้าใจของผม USB port นั้นสามารถรับ-จ่ายกระแสได้น้อยกว่า อย่าง jetbot นี้ ตอนรันใช้ไฟจาก power bank ผ่าน USB port ระบบจะถูกกำหนดให้ทำงานในโหมดกินพลังงานต่ำ
ส่วน jack DC คงไม่มีปัญหานี้ จัดเต็มได้เลย บริโภคไฟกันได้สุดๆ ดังนั้น adapter ที่ใช้ ก็น่าจะเป็น 5V 4A ขึ้นไป ก็เผื่อคุณภาพและประสิทธิภาพการทำงานของตัว adapter ไว้ด้วย

2. ชุดคิท jetbot
ประกอบไปด้วย 3D printed โครงหุ่นและล้อ ส่วนที่เป็นอุปกรณ์อิเล็กทรอนิกส์ ก็มีเพียง มอเตอร์ บอร์ดขับมอเตอร์ featherwing และกล้อง raspberry pi camera แค่นั้นเอง อ้อแล้วก็ power bank อีกอย่างนึง

เรื่องการประกอบ ใน github ของ jetbot มีอธิบายไว้ชัดเจนพอสมควร ผมคงไม่เขียนถึง

ก็ไปเตรียมหุ่นกันไว้นะ แล้วในตอนหน้า มาเริ่มใช้งานกันดีกว่า

Node.js กับ ARM device และ ubuntu 12.04

zigbee-meshลองเอา z-stack linux gateway ขึ้นมา ด้วยความที่ ไม่มีบอร์ด beaglebone มองซ้ายขวา มี pandaboard เก่าอยู่ cpu พี่น้องกันน่าจะใช้แทนกันได้ ก็ปรากฏว่า ได้จริงๆ แต่ดันมาเจอปัญหาใหม่

พยายามลง node.js เพื่อใช้งานทำ web server app สำหรับ IoT อย่างที่เค้านิยมทำกัน เลยลองลงจาก repository ปกติ แต่ไม่สามารถทำงานได้ cpu 100% ตลอดเวลา พยายามลง ppa ที่เค้าแนะนำกัน ก็ไม่ได้อีก หาจนเจอว่า เวอร์ชั่นใหม่ๆนั้น ไม่สามารถทำงานได้กับ ubuntu version เก่าๆ สืบเนื่องจาก javascript V8

ก็ต้องเอา version เก่าที่ support ARMV7 มาลงถึงจะใช้งานได้ ต่อมาก็มาติดปัญหาเรื่อง cyclic dependencies อีก (ด้วยความที่ลองแก้ปัญหาหลายวิธีมาก เลยสรุปไม่ได้ว่า สุดท้ายแล้วแก้ได้อย่างไร ทำทั้ง clear cache ลบ module ออกไปทั้ง folder เองเลยก็ทำ) แต่เรียกได้ว่า ลองใช้งาน node.js ครั้งแรก ก็เจอสารพัดปัญหา

นี่ก็เป็นอย่างนึง ที่คิดว่า ถ้าเราเอาสารพัดเทคนิคมายำรวมๆกัน ให้เป็น solution ขึ้นมา ก็จะสร้าง dependency problem ขึ้นมาเยอะมาก ไม่สนุกที่ต้องมานั่งหา root cause และจัดการกับผลกระทบที่เกิดกับส่วนอื่นๆ

C++ อย่างเดียวจบเลยดีกว่ามั้ย อย่างที่นำเสนอในตอนที่ผ่านๆมา

Qt5.6/OpenCV compilation on Raspbian Jessie

ยังไม่ได้ลอง Raspberry Pi 3 ตัวใหม่เลยครับ แต่วันนี้จะมาเล่าเรื่องการคอมไพล์ Qt และ OpenCV ให้ฟัง

สืบเนื่องจากการใช้งาน Qt บน Wheezy จากการทำ cross compilation ตาม http://www.ics.com/blog/building-qt-5-raspberry-pi ไปใช้งานคราวก่อน มีปัญหากับ qml/UI ไม่ทราบว่าเป็นเพราะอะไรเหมือนกัน พอต้องพัฒนาโปรแกรมต่อก็เลยตัดสินใจย้ายมา Jessie ตัวล่าสุด นี่อาจเป็นการตัดสินใจที่พลาดอีกครั้ง อย่างไรก็ดี ปัญหามีไว้ให้แก้ครับ ก็เลยตัดสินใจเปลี่ยนมาใช้ Qt5.6 ซะเลย ซึ่งก็นั่งคอมไพล์ใหม่เนื่องจาก ไม่อยากใช้งานแพคเกจ Qt/x11 ซึ่งทำให้การบูทช้า ก็เลยทำตาม https://wiki.qt.io/RaspberryPi2EGLFS ทำให้ได้ใช้ Qt แบบ cross platform development กะเค้ามั่ง ทดสอบ QML/UI แล้วไม่มีปัญหา

ต่อมาก็มาถึงเรื่องการใช้งาน OpenCV แน่นอนว่าก็ต้องใช้กับ RaspiCam เพื่อดีงภาพจากกล้อง ปัญหามันอยู่ตรงนี้ละฮะท่านผู้ชมฮะ เกิดปัญหาว่า compiler ของ cross กับบน jessie เวอร์ชั่นไม่ตรงกัน ซึ่งของ cross จะเก่ากว่าบน jessie ทำให้การคอมไพล์โปรแกรมไม่สำเร็จ หลังจากที่หาทางแก้อยู่สองวันสองคืน ก็สรุปได้ว่า ต้องกลับไปใช้ gcc4.8 สำหรับ jessie แล้วคอมไพล์ OpenCV ใหม่ รวมถึง dependency หรือ 3rd party ของมันด้วย จึงจะสามารถทำงานต่อได้

Screenshot from 2016-03-25 12:03:22การเขียนโปรแกรมจึงไม่ใช่แค่การเขียนโปรแกรมนะครับ …

ทดลองทำ OCR บน Raspberry Pi 2

วันก่อนได้ทดลองทำงานต้นแบบอ่านตัวเลข  หรือการทำ OCR ด้วย tesseract โดยเริ่มจากขั้นตอนที่ขาดไม่ได้ คือ การปรับปรุงภาพให้สามารถทำการอ่านได้ดีที่สุด โดยการใช้ OpenCV และทำการแสดงผลบนจอ LCD โดยเขียนโปรแกรมบน Qt รันบน Linux และใช้ Raspberry Pi 2

ก็เป็นการหยิบ r-pi 2 มาใช้เป็นครั้งแรกเลย ตอนแรกว่าจะเอามาลอง Windows 10 ซะหน่อย แต่จนแล้วจนรอดก็ยังไม่มีโอกาสเลยครับ เลยเอามาลองกับงานนี้ก่อน ขั้นตอนการทำงานของผม เป็นดังนี้ครับ

1. ทดสอบการเก็บภาพก่อน ว่าต้องใช้แหล่งกำเนิดแสง ช่วยมั้ย ต้องใช้เลนส์ขนาดเท่าไร ระยะติดตั้งควรเป็นเท่าไร เสร็จแล้วก็ลองทำออกมา
2. จากนั้น ก็เริ่มหาขั้นตอนการทำ image processing ตรงนี้โปรแกรมอย่าง gimp ช่วยได้มากเลยครับ ทดลองปรับปรุงภาพด้วย filter แบบต่างๆ จดบันทึกขั้นตอนเอาไว้ แล้วก็ลองเขียนด้วย OpenCV และลองเอาไปทำ OCR ด้วย tesseract เมื่อได้ผลลัพธ์ที่ต้องการแล้วก็ เขียนโปรแกรมด้วย Qt
3. เดี๋ยวนี้ผมไม่ค่อยอยากเขียน UI ด้วย widget ละ ใช้ QML เป็นหลัก ก็เลยใช้ Qt ซึ่งเวลามีน้อย ก็เลยไม่ได้ build Qt เอง ไป download จากคนที่เค้า build มาแล้วเอามาเผยแพร่ แต่ก็เจอปัญหาคือ เค้า build มาแบบ cross platfom ตัว utility ของ Qt เช่น qmake moc ก็จะอยู่บน PC ทางแก้คือ ต้องหัดใช้ cmake เพื่อ build โปรแกรม แทน
4. จากนั้นจึงใส่ sensor และ LED RGB เข้าไปโดยควบคุมผ่าน library ชื่อ WiringPi ซึ่งก็ใช้งานง่ายดีครับ ยกเว้นต้องรัน โปรแกรมด้วย sudo

ก็ประมาณนี้ละครับ ผมไม่ค่อยได้ใส่โค้ดเข้ามาในบล็อก เพราะสามารถหาเอาจากที่อื่นได้อยู่แล้ว ส่วนที่สำคัญคือการเรียนรู้ ไม่ใช่ผลลัพธ์ครับ

เกริ่น QML animations & transitions

Screenshot from 2015-08-06 23:05:48 Screenshot from 2015-08-06 16:59:47

เคยเขียนไปเมื่อนานมาแล้วว่า สิ่งที่น่าสนใจของ QML อีกอย่างหนึ่งที่สำคัญก็คือ animation & transitions วันนี้ก็ได้มีโอกาสลองเล่นและเรียนรู้ ก็ต้องทำความเข้าใจกับมันพอสมควรเมื่อเริ่มต้น ตอนนี้ผมก็ยังงูๆปลาๆอยู่เลยครับ อิอิ

ด้วยความตั้งใจแต่เริ่มแรกคือ คำถามที่ค้างคาใจมานานว่า ไม่มีอะไรมาแทน flash และ action script เลยเหรอ สำหรับการทำ cg บน tv เพราะโปรแกรมอย่าง CasparCG นั้นก็ใช้ flash ที่นี้ถ้าเราต้องการทำระบบ live streaming เองละ จะใส่กราฟิกและอนิเมชั่นลงไปได้ยังงัย

คราวก่อนผมลอง cairo overlay ลงบน gstreamer element แค่ใช้เวลาเอา svg ขึ้นเนี่ยก็นานแล้วครับ และถ้าต้องโหลดเยอะๆ ดูเหมือนก็จะมีผลต่อ performance เหมือนกัน

คราวนี้เลยลองใหม่ ใช้วิธีเขียน QML application เลย แล้วค่อยทำ screencast เฉพาะส่วน ผมลองเอาไปถ่ายทอดสดลงบน youtube ก็ได้ดังที่เห็น

อ่าว หมดแรงเล่าซะละ ต่อคราวหน้าครับ

credit : กราฟิกสนาม Designed by Freepik.com

QR code generator and Printing

หลังจากที่ได้เขียนตัวอ่าน QR code ไปแล้ว ก็ถึงคราวต้องทำ ตัว generator ละครับ สร้างขึ้นมาอย่างเดียวไม่พอ ก็ต้องปรินท์ออกมาได้ด้วยถึงจะนำไปใช้ประโยชน์ได้ครับ

ผมใช้ libPrison ในการสร้าง QR ก็สะดวกง่ายดายดีครับ ในส่วนของการปรินท์ Qt ก็ให้ API มาให้ค่อนข้างดีทีเดียว การเรียกใช้ print preview dialog การเพิ่มจำนวนหน้า ทำได้ไม่ยากเลย

เหลือที่จุกจิกกวนใจก็ตรงการกำหนดขนาดและทำการ resize สิ่งที่เราจะวาดให้ตรงกับขนาดของกระดาษที่เราจะพิมพ์นั่นละครับ ผมใช้วิธี resize และ render widget เอาเลย โดยทำ widget ที่มีส่วนประกอบและวาง layout ดังรูป กำหนดขนาดและจำนวนที่จะ render ให้พอดีกับขนาดของกระดาษโดยประมาณเอา

10872676_564210363713443_2086052009_n1

ทำระบบคาราโอเกะ Karaoke with PCDuino3 Nano

เมื่อทำการทดสอบ 2d/3d ไปแล้ว ทีนี้มาลองทดสอบ multimedia กันบ้างครับ โดยข้อมูลจาก linux-sunxi เค้าบอกว่า เราสามารถเล่นไฟล์มัลติมีเดียได้โดยอาศัย vdpau ผ่านทางโปรแกรม mplayer

แต่เมื่อทดลองใช้งานแล้วปรากฎว่า ตัวที่ทางผู้ผลิต install มาให้นั้น น่าจะเป็นเวอร์ชั่นเก่าครับ ต้องลง mplayer2 จาก repository แทนมันถึงจะไปเรียกใช้ vdpau ได้ แต่ก็ดูเหมือนจะมีปัญหาอีก ตรงนี้คงต้องหาข้อมูลต่อ เพราะหลายๆคนแนะนำให้ไปใช้ mpv ซึ่ง fork มาจาก mplayer แทน

พอดีถนัดใช้งาน gstreamer เลยตัดสินใจลง gstreamer 0.10 และทดสอบใช้งานดู ปรากฎว่าเล่นได้ครับ

ผมทดลองเล่นไฟล์ h.264 1080p โดยไม่ใช้ความสามารถของ hardware decoder ช่วย ก็ไม่สามารถเล่นได้อย่างราบรื่นนะครับ แถมกิน cpu ไปหมดทั้งสองคอร์ เมื่อเปลี่ยนมาใช้ vdpau ช่วย ก็สามารถเล่นได้สบายๆครับ

เมื่อผ่านขั้นตอนทดสอบความสามารถก็มาถึงขั้นตอนการพัฒนาอะไรขึ้นมาบ้าง โดยมีโจทย์มาให้ทำระบบเล่นคาราโอเกะ ครับโดยมีความสามารถในการตัดเสียงร้องออกได้ (กรณีที่ไฟล์ต้นฉบับ ใส่เสียงร้องไว้ channel หนึ่งนะครับ) ก็เลยลองทำโดยการใช้วิธี ตัดเสียงจาก channel เดิม ออก แล้วใส่ เสียงจากอีก channel เข้าไปแทน จึงกลายเป็น mono 2 channels ( LR -> LL or RR )  ทำให้เสียงยังคงออกลำโพงทั้งสองข้างได้

20141027142125-s

ก็ทดลองทำให้มันสลับไปมาได้ กว่าจะทำเสร็จก็ร้องเล่นเองไปหลายรอบๆ อิอิ

อันนี้ก็เป็นตัวอย่างหนึ่งในการใช้งานบอร์ดนี้นะครับ ข้อดีอย่างที่บอกไป ลดการใช้พลังงาน ลดต้นทุน ได้หลายๆครับ

QR decoder app on Android

Screenshot_2014-09-23-18-27-55

คราวก่อน เขียนโปรแกรม QR decoder บน pc ไปแล้ว วันนี้เป็นการทดสอบเอาโปรแกรมไปรันบนเครื่องแอนดรอยด์ จุดที่น่าสนใจคือ การคอมไพล์ zbar library ด้วย ndk ส่วนหนึ่งผมทำตามแนะนำจากเว็บนี้ http://www.blackdogfoundry.com/blog/zbar-bar-code-qr-code-reader-android/ เพื่อให้ได้ libzbar.so และ ฟังก์ชั่นการ decode ภาพออกมา

ส่วนต่อมาคือการเอาไปใช้ ผมเขียนด้วย QML ดัดแปลงจาก https://www.ics.com/blog/qt-5-multimedia-qml-elements#.VCFtHdazCfg ซึ่งจริงๆก็คล้ายๆกับ ใน document ของ Qt เองครับ จุดที่น่าสนใจอีกจุดคือการทำให้ QML สามารถเรียกฟังก์ชั่น decode ใน C++ ได้

และส่วนสุดท้ายครับ คือการ deploy หรือการนำโปรแกรมขึ้นไปรันบนอุปกรณ์ที่เป็น Android จริงๆ ซึ่งประเด็นอยู่ที่การนำเอา libzbar.so ใส่เข้าไปด้วย ก็ศึกษาได้จาก http://www.kdab.com/qt-android-episode-3/

การเขียนโปรแกรมครั้งเดียวแล้วสามารถรันได้หลายๆแพลตฟอร์มด้วย Qt เป็นอะไรที่เจ๋งจริงๆเลยครับ อิอิ

Machine Vision

วันก่อนได้มีโอกาสทำชุดเดโม machine vision ด้วย Linux, Qt, OpenCV ครับ เลยมีโอกาสได้เปรียบเทียบการใช้งานระหว่างกล้อง usb webcam ธรรมดา กับ กล้องที่ใช้ในงานอุตสาหกรรม

ผมคิดว่าส่วนที่แตกต่างกันมันก็คือเรื่องของ hardware นั่นละครับ เพื่อให้ได้ภาพที่ดีที่สุดเอาไปประมวลผล ซึ่งก็จะทำให้ลดเวลาในการทำ pre-processing ไปได้เยอะ ซึ่งตรงนี้สำคัญมากครับ เพราะแต่ละขั้นตอนหมายถึงเวลาที่ต้องใช้ cpu ประมวลผล ถ้าใช้ขั้นตอนมากก็เสียเวลามาก อาจชดเชยด้วยการใช้คอมสเป็คสูงๆ แต่ก็ไม่แน่ว่าจะช่วยได้เสมอไป ที่สำคัญงานส่วนใหญ่ต้องการความเร็วในการประมวลซะด้วยสิ ดูได้จากเสป็คของกล้องที่มีการรองรับ fps สูงๆ ระดับ 100 fps ขึ้นไป แต่ถามว่าจะทำยังงัยเพื่อให้ประมวลผลแล้วยังได้เฟรมเรทที่ระดับนี้อยู่ ซึ่งกล้องอุตสาหกรรมก็สามารถตอบโจทย์ตรงนี้ได้(ราคาก็สูงกว่ามาก) แต่ถ้าเพื่อการศึกษาหรือทดลอง OpenCV ผมว่าใช้กล้องธรรมดาก็พอได้ครับ

อีกเรื่องคือการ support Linux ของกล้องยี่ห้อต่างๆ มันไม่ใช่แค่ driver ยังต้องรวมถึง sdk ด้วย อย่างที่ผมได้ทดลองทำเดโม เป็นการใช้งานกล้อง Basler ที่มี interface แบบ GigE ก็จะมี pylon sdk มาให้ซึ่งเป็น c++ framework ก็ต้องนั่งศึกษากันไป หรืออย่างของ Imaging Source ก็ค่อนข้างจะสนับสนุนระบบพื้นฐานของ Linux โดยทั่วไปไม่ต้องลง driver ให้ยุ่งยาก เช่น interface USB ก็ใช้ uvc driver กับ v4l2 เนี่ยแหละ แถมยังมี gstreamer plugin ให้ใช้ด้วย ซึ่งส่วนตัวค่อนข้างประทับใจ

อย่างไรก็ดี หากเราได้ภาพมาแล้วเรื่อง api ของกล้องคงไม่ใช่ประเด็นแล้วครับ อย่างกล้องที่ผมได้มีโอกาสใช้งานทำเดโม ก็คือของ Basler ซึ่งใช้ interface แบบ GigE ก็เสียเวลาศึกษาและเขียนโมดูลเพื่อจะเอาภาพออกมาจากกล้องส่งต่อให้ OpenCV เพิ่มขึ้นนิดหน่อย

อีกส่วนหนึ่งก็คือ GUI ครับ เมื่อตะกี้เราพูดถึงการนำภาพจากกล้องผ่าน api ของมันมาส่งให้ OpenCv แน่นอนก็ต้องมีการ copy memory หรือก็อปปี้เฟรมมา ในระหว่างการทำ image processing เรายังอาจต้องมีการ copy ภาพทั้ง frame อีก รวมถึงเมื่อส่งต่อให้ GUI มาวาดทำการแสดงผล อย่างเช่นที่ผมทำไป อย่างน้อยก็มีการ copy จาก api ของกล้องมาเป็น cv::Mat และในขั้นตอนสุดท้ายอยากเอาไปแสดงผล ก็ต้อง copy เป็น QImage สำหรับ Qt อีกที จากที่ลองทำ ซึ่งใช้ thread และ buffer เพื่อแยกระหว่าง การรับภาพเข้ามา และ การประมวลผล ก็ยังดูว่าใช้ cpu มากพอควร

สิ่งที่อยากทำต่อไปคือ ทดลองเอา gpu เข้ามาช่วยทั้งในเรื่องของการแสดงผลและการทำ image processing เช่น OpenGL, cuda หรือ OpenCL ซึ่ง OpenCV ก็ดูจะ support ตรงนี้ด้วย คงต้องไปศึกษาเพิ่มเติมก่อนครับ

ก็ประมาณนี้ จากการที่ได้กลับมาทำ image processing อยู่สามสี่วัน หลังจากไม่ได้ทำมานานหลายปี