Wednesday, October 23, 2013

Phonegap + jQuery Mobile + Android

ช่วงนี้ Mobile Application กำลังมาแรง เค้าว่ากันว่าจะสร้าง app พวกนี้ น่าจะทำได้ประมาณ 3 แบบคือ
1. Native app เขียนโค้ดโดยตรงสำหรับ Android iOS WP8 ไปเลย
2. Web app เขียนเป็นเว็บโดยใช้ HTML+CSS+JavaScript ไง เร็วดี
3. Hybrid app เขียนเแบบ 2 แต่ wrap ให้เป็นแบบ 1 โดยใช้เครื่องมือช่วยเช่น Phonegap

ข้อดีข้อเสียก็ว่ากันไป แต่บทความนี้เราจะลองพูดถึงแบบที่ 3 ดูครับ โดยเน้นไปที่ Android อย่างไรก็ตาม วิธีนี้ถ้าใช้ phonegap อย่าลืมไปเช็ค Platform Support ก่อนที่ http://docs.phonegap.com/en/edge/guide_support_index.md.html#Platform%20Support ว่ามันทำได้อย่างที่เราต้องการหรือเปล่า

สิ่งที่เราต้องการในบทความนี้
1. phonegap (http://phonegap.com/install/) ผมลองเวอร์ชัน 3 แล้วงงพอควร แนะนำให้ใช้ 2.9.0 ซึ่งดาวน์โหลดได้โดยตรงที่ https://github.com/phonegap/phonegap/archive/2.9.0.zip
2. jquery Mobile เอามาเขียนเว็บให้ดูหน้าตาเข้าที ให้ touch ได้ swipe ได้นะ (http://jquerymobile.com/)
3. Genymotion ตัวนี้จะใช้หรือไม่ใช่ก็ได้ เอาไว้เป็น android emulator เพราะตัวที่มากับ ADT Bundle นั้นช้าที่สุดในจักรวาลลลลล ตัวนี้เร็วกว่าแบบเทียบกันไม่ได้ เหมาะกับโปรแกรมเมอร์ที่จะทดสอบโค้ดบน android emulator (http://genymotion.com/)
4. ADT Bundle สำหรับเขียนโค้ด build และรัน app (http://developer.android.com/sdk/installing/bundle.html)
5. ถ้าอยากลอง ตัวนี้จะใช้หรือไม่ก็ได้ Netbeans 7.4 Beta (http://download.netbeans.org/netbeans/7.4/beta/) ย้ำว่าควรเป็นตัวนี้เท่านั้น ตัวเต็มเวอร์ชัน 7.4 ดันเป็นตัวที่ใช้กับ phonegap ยากซะงั้น เลือกโหลดที่เป็น php เวอร์ชันก็พอครับ

วิธีการใช้งาน (เลือกเอาครับว่าจะใช้แบบไหน)
แบบที่ 1 ใช้ Netbeans
กลายเป็นว่า Netbeans เป็น IDE ที่สนับสนุนการใช้ phonegap เต็มที่ สำเร็จรูปมากกกก แต่ดันทำไม่สุด เวอร์ชัน Beta สามารถกำหนดว่า phonegap อยู่ที่ไดเรกทอรีไหน แต่เวอร์ชันจริงมันกลับไปเช็ค path การติดตั้ง phonegap ซึ่งผมไม่ต้องการ ผมอยากได้ IDE ที่มันเป็น portable ก๊อบใส่ USB drive ได้ง่ายๆ เลยถอยมาใช้ตัว Beta ดู
ปล. แนะนำให้โหลด Netbeans php ตัว zip มาใช้แบบไม่ต้องติดตั้ง
ปล.2 เว็บดาวน์โหลด Netbeans มันประหลาดมาก โหลดแล้วหลุดตลอดจนเซ็ง

หลังจากดาวน์โหลด แตกไฟล์ต่างๆเรียบร้อยแล้วก็เปิด Netbeans เลยครับ
-เลือกเมนู Tools/Options แล้วกำหนดไดเรกทอรีต่างๆ เช่น


-สร้าง New Project มันจะมีให้เลือก Phonegap Application หรือ Cordova Application ให้เลย พร้อมทั้งสำเนาไฟล์ต่างๆมาหมด สุดยอดดดด
-ลองรันรูปแบบต่างๆได้โดย


-สามารถ Build เป็น Native app ผ่าน phonegap แบบง่ายๆ โดยคลิกขวาที่ Project แล้วเลือก Build ก็จะได้ไฟล์ apk ที่เป็น debug เวอร์ชันในไดเรกทอรีชื่อ platforms/android/bin

เห็นไหมครับ ง่ายกว่านี้ไม่มีแล้ว แต่ๆๆๆๆ มันไม่สามารถเลือก emulator ตัวอื่น เช่นจาก genymotion ได้ครับ ต้อง build ออกมาก่อนเป็นไฟล์ apk แล้วใช้ adb ติดตั้งไปบน emulator ด้วยคำสั่งเช่น adb install -r xxx.apk ครับ รวมถึงมีข้อจำกัดอีกอย่างคือไฟล์ apk จะเป็น debug เวอร์ชันเท่านั้น ถ้าจะทำเป็น release หรือ sign เวอร์ชันก็จะมีขั้นตอนอีก

แบบที่ 2 ผ่าน Eclipse
อ้างอิงจากที่นี่เลยครับ http://www.adobe.com/devnet/html5/articles/getting-started-with-phonegap-in-eclipse-for-android.html
ทำตามเค้าเป๊ะ ขั้นตอนเยอะพอสมควร จนถึงขั้นตอนการกำหนด user permission หลังจากนั้นก็ไม่จำเป็นแล้วมั้ง
อย่าลืมก๊อบไดเรกทอรีของ jquery mobile ไปให้ครบด้วย
ตอนกำหนดสิทธิ์ในไฟล์ AndroidManifest.xml ถ้าไม่ได้ใช้อะไร ก็กำหนดแค่
uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
ตัวเดียวก่อน ส่วนจะต้องกำหนด permission อะไรบ้าง ขึ้นอยู่กับ module ที่ใช้ ซึ่งสามารถอ้างอิงได้จากคู่มือ http://docs.phonegap.com/en/2.9.0/index.html ในส่วนของ API reference ครับ

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

Saturday, October 12, 2013

JavaScript Gauge

วันนี้ลองหาโค้ด JavaScript Gauge เจอสองเว็บที่น่าสนใจครับ
http://justgage.com/

แสดงผลเป็นเวกเตอร์ทำให้รูปชัดเจนแม้ย่อหรือขยาย ดูแล้วเข้าใจง่าย แต่ยังมีข้อจำกัดหลายอย่างที่กำลังพัฒนาอยู่ เวอร์ชันที่เป็น demo อยู่มีฟังก์ชันที่น่าสนใจมาก http://justgage.com/demos/

ตัวอย่างโค้ดโดยใช้เวอร์ชันที่กำลังพัฒนาอยู่ครับ ดาวน์โหลดได้ที่ http://justgage.com/justgage.js
<!doctype html>
<html>
<head>
 <title>Auto-adjust</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />   
 <script src="raphael.2.1.0.min.js"></script>
 <script src="justgage.js"></script>
 <script>   
   window.onload = function(){
  var g1 = new JustGage({
    id: "g1", 
    value: 150, 
    min: 0,
    max: 200,
    title: "PPM10",
    label: "ug/m3",
    customSectors: [{
     color : "#00ff00",
     lo : 0,
     hi : 120
   }, {
     color : "#ff0000",
     lo : 121,
     hi : 300
    }]
  });
   };
 </script>
</head>

<body>
 <div id="g1" style="width:200px; height:160px; display:inline-block;"></div>
</body>
</html>

และอีกตัวหนึ่งครับ
https://github.com/Mikhus/canv-gauge
ตัวนี้สามารถกำหนดค่าได้ค่อนข้างมาก และสามารถระบุค่าเป็นแบบ tag ของ html หรือเขียนเป็นโค้ดของ JavaScript ก็ได้
ตัวอย่างโค้ดแบบ html
<!doctype html>
<html>
<head>
 <title>Canv-gauge</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />   
 <script src="gauge.min.js"></script>
</head>

<body>
 <canvas width="200" height="200"
  data-type="canv-gauge"
  data-title="PPM10"
  data-value="100"
  data-units="ug/m3"
  data-max-value="300"
  data-major-ticks="0 100 200 300"
  data-highlights="0 120 #0f0, 120 300 #f00"
 ></canvas>
</body>
</html>

ลองเลือกใช้กันดูครับ

Saturday, August 10, 2013

Histogram

เราลองมาคำนวณ Histogram ของรูปกันครับ



import cv2
import numpy as np

img = cv2.imread("lena.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#compute histogram
#create zero array for histogram, 255 bins
hist = np.zeros(256)
#for each pixel
for p in gray.flat:
    hist[p]+=1

#normalize histogram to display in 256x256 image
hist = hist/hist.max()*255
hist = np.uint8(hist)

#create a new image for displaying histogram
#note that the image origin is at top-left corner
out = np.zeros((256,256,3),dtype=np.uint8)
for r in range(256):
    cv2.line(out,(r,255),(r,255-hist[r]),(0,0,255))

cv2.imshow("Original",gray)
cv2.imshow("Histogram",out)
cv2.waitKey()
cv2.destroyAllWindows()

Thursday, August 8, 2013

OpenCV กับ Video

เมื่อเราต้องการเปิดไฟล์วิดีโอด้วย OpenCV เพื่อนำเฟรมมาประมวลผล จะต้องทำอย่างไรบ้าง

วิธีที่ 1
  • ถ้าไม่ต้องการติดตั้ง video codec เพิ่มเติม หรือไม่สามารถติดตั้งได้ อาจจะจำเป็นต้องแปลงไฟล์วิดีโอให้อยู่ในรูปแบบ raw นั่นคือ ไฟล์วิดีโอที่ไม่ได้เข้ารหัส ดังข้อแนะนำ จาก http://opencv.willowgarage.com/wiki/VideoCodecs ซึ่งจะมีหลายวิธี เช่นวิธีนี้
    1. ดาวน์โหลด mencoder จาก http://oss.netfarm.it/mplayer-win32.php
    2. แตกไฟล์เฉพาะ mencoder.exe ออกมา
    3. ใช้คำสั่ง mencoder in.mp4 -ovc raw -nosound -o out.avi เพื่อแปลงไฟล์ in.mp4 ให้เป็น raw format ชื่อ out.avi
วิธีที่ 2
  • ตรวจสอบว่าเครื่องคอมพิวเตอร์ของเราสามารถเล่นไฟล์นั้นได้ โดยใช้โปรแกรมทั่วไปเช่น media player ถ้าเล่นได้ แสดงว่าเครื่องของเรามี codec ที่ใช้ถอดรหัสของวิดีโอนั้นแล้ว ถ้าเล่นไม่ได้ ให้ลองติดตั้ง video codec เช่น k-lite codec pack เสียก่อน จากนั้นจึงทดสอบอีกครั้ง
  • ให้เปิดไฟล์ OpenCV (ดาวน์โหลดได้ที่ opencv.org) ด้วยโปรแกรมเช่น 7zip สมมติว่าชื่อ OpenCV-2.4.6.0.exe
  • แตกไฟล์ชื่อ \opencv\build\x86\vc11\bin\opencv_ffmpeg246.dll ออกมา
  • คัดลอกไฟล์ดังกล่าว ไปไว้ที่เดียวกัน source code
  • ถ้า python ทำงานอยู่ ให้ปิดและเปิดใหม่อีกครััง
ไม่ว่าจะใช้วิธีที่ 1 หรือ 2 ก็ตาม จะใช้รหัสโปรแกรมเพื่อทดสอบดังนี้
import cv2
import sys

#open video file
cap = cv2.VideoCapture('video.mp4')

#check if connected
if cap.isOpened():
    print "Open"
else:
    print "Close"
    sys.exit(-1)

#loop to capture each frame and display
#until press ESC
key = 0
ret = True
fps = int(cap.get(5))   #get video FPS

while key!=27:
    ret,im = cap.read()
    if ret==False:
        break
    #display image
    cv2.imshow('video test',im)
    #wait for input key every 1000/fps ms
    key = cv2.waitKey(1000/fps)

#close capture device
cap.release()
#destroy all ui windows
cv2.destroyAllWindows()

ก็ควรที่จะอ่านไฟล์วิดีโอที่เข้ารหัสนี้ได้

ถ้าจะต่อกับกล้อง webcam ปกติที่มีมาพร้อมคอมพิวเตอร์ หรือเป็นแบบ USB สามารถใช้
cap = cv2.VideoCapture(0)

สำหรับภาพจาก ip webcam ที่ส่งข้อมูลไฟล์มาเป็น mjpeg เราสามารถใช้
cap = cv2.VideoCapture('http://admin:admin@192.168.1.3/img/video.mjpeg')

ทั้งนี้ขึ้นอยู่กับ API ของ ip webcam นั้นด้วยนะครับ แต่ละยี่ห้ออาจจะใช้คำสั่งต่างกัน

Saturday, March 2, 2013

หาขอบที่เป็นเส้นตรงด้วย Probabilistic Hough Transform

นอกจาก Hough Transform แล้ว OpenCV ยังมีอีกคำสั่งหนึ่งในการหาขอบเส้นตรง นั่นคือ HoughLinesP ซึ่งสามารถศึกษาวิธีการได้จาก [1]

คำสั่ง HoughLinesP จะให้ผลลัพธ์เป็นจุดสองจุดที่เป็นต้น (x1,y1) และปลาย (x2,y2) ของเส้นตรงที่คำนวณได้ การพลอตผลลัพธ์ก็จะทำได้ง่ายขึ้น

ลองดูตัวอย่าง เปรียบเทียบกับบทความก่อนหน้าครับ


import cv2
import numpy as np

img = cv2.imread("building.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#Appy Gaussian blur to remove some noises
inoise = cv2.GaussianBlur(gray,(3,3),sigmaX=0)

#Canny
lowThresh = 50
upThresh = 200
edge = cv2.Canny(inoise,lowThresh,upThresh)

#Probabilistic Hough Line Transform
lines = cv2.HoughLinesP(edge,rho=1,theta=np.pi/180,threshold=120,minLineLength=30,maxLineGap=10)

img2 = img.copy()
#Plot detected lines
for x1,y1,x2,y2 in lines[0]:
    cv2.line(img2,(x1,y1),(x2,y2),(0,255,0),2)

cv2.imshow("Probabilistic Hough Lines",img2)
cv2.waitKey()
cv2.destroyAllWindows()

อ้างอิง
[1] Matas, J. and Galambos, C. and Kittler, J.V., Robust Detection of Lines Using the Progressive Probabilistic
Hough Transform. CVIU 78 1, pp 119-137 (2000)