Monday, November 26, 2012

การประมวลผลรูปและแสดงผลในหน้าต่าง

จากบทความที่แล้ว เราได้ลองเขียนคลาสที่มี constructor สำหรับอ่านและแสดงผลรูป ซึ่งได้ผลลัพธ์ดังนี้


ก่อนที่จะประมวลผลรูป น่าจะเป็นการดีที่เราแยกหน้าที่เหล่านี้ออกจากกันโดยใช้ method ใหม่แทน นั่นคือ เราจะแยกเป็น 3 method

1. constructor ทำหน้าที่รับหน้าต่างหลักมา แล้วกำหนด title ของหน้าต่าง
2. loadImage ทำหน้าที่อ่านไฟล์รูปมาเก็บไว้ในตัวแปรของคลาส
3. showImage ทำหน้าที่แสดงผลรูปในหน้าต่าง

เพื่อที่จะให้ตัวแปรใช้ร่วมกันในแต่ละ method ได้ ใน python จึงต้องสร้างให้เป็นตัวแปรของคลาส คือ มีคำว่า self นำหน้า

โค้ดที่ปรับปรุงใหม่ แต่ให้ผลลัพธ์เหมือนบทความที่แล้วก็จะเป็นดังนี้
from Tkinter import Tk, Label
from PIL import Image, ImageTk

class mainApp:
    #constructor
    def __init__(self,mainwindow):
        #assign class variable to input parameter
        self.mainwindow = mainwindow
        #set title
        self.mainwindow.title("Image Label")

    def loadImage(self):
        #load image
        self.im = Image.open("lena.jpg")

    def showImage(self):
        #convert image to Tk format
        self.imTk = ImageTk.PhotoImage(self.im)
        #create a label on main window with image
        lbl = Label(self.mainwindow, image=self.imTk)
        #pack window to label and display
        lbl.pack()

#---Main app starts here---
root = Tk()
app = mainApp(root)
#load image
app.loadImage()
#show image
app.showImage()
root.mainloop()

สังเกตว่าคราวนี้เราอ่านรูปและแสดงผลด้วย method ใหม่ ซึ่งถูกเรียกใช้งานผ่าน object

ต่อไปเราจะลองเขียน method เพื่อประมวลผลรูป เช่น เปลี่ยนรูปสี ให้เป็นรูปสีเทา
หมายเหตุ ใน PIL รูปสีปกติจะเรียกว่า RGB และรูปสีเทาจะเรียกว่า L



โค้ดของโปรแกรมก็จะเพิ่ม method ใหม่สั้นๆแค่
 #----------------------------------------------
    #method to convert image to grayscale
    def imgGray(self):
        self.im = self.im.convert("L")
        self.showImage()
#----------------------------------------------

ถ้าเป็นโค้ดเต็มๆ ก็ตามนี้ครับ
from Tkinter import Tk, Label
from PIL import Image, ImageTk

class mainApp:
    #constructor
    def __init__(self,mainwindow):
        #assign class variable to input parameter
        self.mainwindow = mainwindow
        #set title
        self.mainwindow.title("Image Label")

    def loadImage(self):
        #load image
        self.im = Image.open("lena.jpg")

    def showImage(self):
        #convert image to Tk format
        self.imTk = ImageTk.PhotoImage(self.im)
        #create a label on main window with image
        lbl = Label(self.mainwindow, image=self.imTk)
        #pack window to label and display
        lbl.pack()

    #method to convert image to grayscale
    def imgGray(self):
        self.im = self.im.convert("L")
        self.showImage()

#---Main app starts here---
root = Tk()
app = mainApp(root)
#load image
app.loadImage()
#convert to grayscale image
app.imgGray()
root.mainloop()

Sunday, November 25, 2012

การอ่านรูปและแสดงผลบน UI

คราวที่แล้วเราลองสร้าง UI อย่างง่าย ซึ่งจะนำมาใช้ต่อในบทความนี้ครับ

ก่อนอื่น เราจะลองนำข้อความไปวางบนหน้าต่างของ UI ให้ได้ผลลัพธ์ตามนี้ครับ

โดยใช้โค้ดต่อไปนี้
from Tkinter import Tk, Label
from PIL import Image, ImageTk

class mainApp:
    #constructor
    def __init__(self,mainwindow):
        #set title
        mainwindow.title("Text Label")
        #create a label on main window with text
        lbl = Label(mainwindow, text="Hello world!")
        #pack window to label and display
        lbl.pack()

#Main app starts here
root = Tk()
app = mainApp(root)
root.mainloop()


ต่อไปเราจะลองอ่านรูป แล้วแสดงผลบนหน้าต่าง โดยใช้ Label เป็นตัวเก็บรูป (เนื่องจากหน้าต่างหลักเก็บรูปไม่ได้ครับ)

ผลลัพธ์ที่ต้องการ


แก้ไขโค้ดใหม่ดังนี้ครับ
from Tkinter import Tk, Label
from PIL import Image, ImageTk

class mainApp:
    #constructor
    def __init__(self,mainwindow):
        #set title
        mainwindow.title("Image Label")
        #load image
        im = Image.open("lena.jpg")
        #convert image to Tk format
        #self is used to set the image to class variable
        #to prevent garbage collector to destroy image
        self.imTk = ImageTk.PhotoImage(im)
        #create a label on main window with image
        lbl = Label(mainwindow, image=self.imTk)
        #pack window to label and display
        lbl.pack()

#Main app starts here
root = Tk()
app = mainApp(root)
root.mainloop() 

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

การสร้าง User Interface (UI) ขั้นต้น

ในบทความนี้เราจะลองสร้าง UI ใน python เพื่อเตรียมสำหรับแสดงผลรูปกันครับ

UI ที่ใช้กับ python สามารถสร้างโดยใช้ส่วนเสริมหลายตัวครับ แต่ตัวที่เป็นพื้นฐานและมาตรฐานที่มาพร้อมกับภาษา (เฉพาะ windows ส่วน linux อาจต้องติดตั้งเพิ่ม) คือ Tkinter

การใช้งานไม่ยากครับ ตัวอย่างโค้ดเช่น
from Tkinter import *
#create a Tk root widget, a simple window
root = Tk()
#set window title
root.title("Hello Title")
#stay in the event loop until closing the window
root.mainloop()

ก็จะได้ผลลัพธ์เป็น


เราสามารถเขียนโค้ดดังกล่าว ให้อยู่ในรูปแบบของคลาส ได้ดังนี้
from Tkinter import *
class MainApp:
    #constructor
    def __init__(self,mainwindow):
        mainwindow.title("Hello Title")
    
#create a Tk root widget, a simple window
root = Tk()
#create an object from class App
app = MainApp(root)
#stay in the event loop until closing the window
root.mainloop()

ซึ่งก็จะได้ผลเช่นเดียวกันครับ


เอกสารอ้างอิง
An Introduction to Tkinter, http://www.pythonware.com/library/tkinter/introduction/

การอ่านไฟล์ภาพและแสดงผล

สมมติว่าเรามีรูปที่ต้องการอ่านและแสดงผลคือ "lena.jpg" ซึ่งอยู่ในโฟลเดอร์เดียวกับโปรแกรมที่เราจะเขียนนะครับ


วิธีการอ่านรูป ก็จะใช้โค้ดง่ายๆดังนี้ครับ
from PIL import Image
#open image
im = Image.open("lena.jpg")
#show image, loading temp image by default image viewer
im.show()

คำสั่ง im.show() จะบันทึกผลลัพธ์เป็นไฟล์ชั่วคราว และเรียกโปรแกรมดูภาพในเครื่องมาเปิดไฟล์รูปนี้ขึ้นมาแสดงครับ

เราลองทำการประมวลผลภาพอย่างง่าย เช่นการกลับรูปซ้ายขวา (Flip left-right) ด้วยโค้ด
from PIL import Image
#open image
im = Image.open("lena.jpg")
#flip image left-right
out = im.transpose(Image.FLIP_LEFT_RIGHT)
#show image, loading temp image by default image viewer
out.show() 

ผลลัพธ์ก็จะเป็น

บทความถัดไป เราจะลองสร้าง GUI เพื่อเตรียมไว้แสดงผลรูปครับ

 เอกสารอ้างอิง
Python Image Library Handbook, http://www.pythonware.com/library/pil/handbook/index.htm

Python กับการประมวลผลภาพเบื้องต้น

มีโอกาสได้ลองใช้ python ครับ เลยถือโอกาสศึกษาวิธีการใช้กับการประมวลผลภาพ พบว่า python เป็นภาษาที่มีทั้งข้อเด่นและข้อจำกัด แต่โดยรวมแล้วถือว่าเป็นภาษาที่มีประสิทธิภาพมาก โดยเฉพาะอย่างยิ่งมีส่วนเสริมที่สนับสนุนงานทางด้านการประมวลผลภาพได้ดี นอกจากนี้แล้วยังเป็น multi-platform ใช้งานได้บนหลายระบบปฏิบัติการ

สำหรับตัวอย่างที่เราจะลองสร้างกัน ต้องการซอฟต์แวร์ดังต่อไปนี้ครับ
1. python รุ่น 2.7
2. python-imaging (PIL) สำหรับการประมวลผลภาพ
3. python-tk สำหรับการสร้าง interface
4. python-imaging-tk สำหรับการเชื่อมต่อระหว่าง PIL และ python-tk

ซึ่งข้อ 1. ถึงข้อ 3. มักจะมีมากับ linux อยู่แล้ว ถ้าต้องการติดตั้งข้อ 4. เพิ่มก็สามารถทำได้ เช่น ใช้ Synaptic package manager แล้วเลือก python-imaging-tk

สำหรับ windows สามารถดาวน์โหลดข้อ 1. และ 2. มาติดตั้งก็น่าจะเพียงพอ หรือ จะใช้ portable python (http://www.portablepython.com/) ที่สามารถใช้งานผ่าน usb drive ได้เลย แต่ตอนแตกไฟล์ครั้งแรกให้เลือกส่วนเสริม PIL ด้วยครับ

ความต้องการอีกอย่างนึงคือ เราต้องเขียนโปรแกรมพื้นฐานด้วย python พอได้นะครับ

ลองมาทดสอบกันง่ายๆ ว่าเครื่องของเราใช้งาน python ได้แล้วหรือยัง ด้วยการเขียนโค้ดต่อไปนี้ครับ

print "hello"

(ใช้ IDE ตัวไหนก็ได้ตามใจชอบครับ ถ้าบน linux mint ที่ผมใช้อยู่จะมี Geany ส่วนบน windows ที่ใช้ portable python ก็จะมี PyScripter ซึ่งดีมากๆเช่นกัน)

จากนั้นบันทึกเป็นไฟล์ชื่อใดๆ เช่น hello.py
และรันโค้ดนี้ด้วยเมนู run หรือ execute ใน IDE ที่ใช้ ซึ่งมักจะ link ไปยัง python ที่ติดตั้งไว้โดยอัตโนมัติ
หรือ รันด้วยคำสั่งจาก terminal หรือ command prompt คือ
python hello.py

ถ้าเกิดผลลัพธ์ที่เป็นข้อความว่า hello แสดงว่าเครื่องคอมพิวเตอร์ของเราพร้อมสำหรับ python แล้วครับ