| |
&theme=102)
บทความเรื่อง : อิมเมจโปรเซสซิ่งสำหรับผู้เริ่มต้น (ตอนจบ )
เขียนโดย อ.จักรกฤษณ์ แสงแก้ว สาขาสารสนเทศศาสตร์ คณะวิทยาการสารสนเทศ มหาวิทยาลัยมหาสารคาม
สำหรับวันนี้ผมเองตั้งเจตนาจะเขียนบทความ เรื่องอิมเมจโปรเซสซิ่งสำหรับผู้เริ่มต้นให้จบ
และขณะนี้เวลา 01.24 เช้าตรู่.. วันจันทร์ที่ 23 มกราคม 2549 มองไปนอกหน้าต่างบ้านเรือนต่างปิดไฟนอนหลับไหลกันหมด
เหลือไว้แต่คนกลางคืน คนขับรถสิบล้อ แม่ค้าขายอาหารที่ต้องนอนดึกดื่น และนกฮูกอย่างผม
เอาเป็นว่าเรื่องราวที่เหลือต่อจากบทความที่แล้วคือ การประมวลผลภาพเป็นพื้นที่รอบ
ๆ จุดสีหนึ่ง ๆ (Area Processing) ซึ่งเีรียกอีกอย่างว่า การทำคอนโวลูชั่น
(Convolution)
ถือเป็นหัวข้อที่ค้างจากตอนที่ผ่านมา นอกจากนั้นแล้วในบทความนี้จะปิดท้ายด้วยการประมวลผลด้านรูปร่างของภาพ
(Morphology Processing) ขอเริ่มใจความของบทความด้วยรายละเอียดต่อไปนี้
ก่อนจะกล่าวถึงรายละเอียดเหล่านั้น ขอให้พิจารณาภาพด้านล่างต่อไปนี้

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

ผลลัพธ์ คือ [0 x 2 ] + [-1 x 3] + [0 x 1] + [-1 x 4] + [9 x 6] + [-1 x
2] + [0 x 5] + [-1 x 2] + [0 x 3] = 43
แสดงได้ดังนี้
ขอให้ท่านโปรดระวังว่าผลลัพธ์จากการคำนวณขอให้นำไปเก็บใส่ภาพใหม่ อย่านำลงไปเก็บในตำแหน่งปัจจุบันของภาพเดิม
ผู้เขียนได้สร้างฟังก์ชั่นสำหรับคำนวณค่า Convolution แสดงได้ดังตัวอย่างต่อไปนี้
|
ตัวอย่าง สร้างฟังก์ชั่นสำหรับคำนวณหา
Mask Convolution
|
from __future__ import division
import Image
def Convolution(Coefficient, Raw_Data):
m =
[]
for
i in range(len(Coefficient)):
m.append(Coefficient[i]
* Raw_Data[i])
return
sum(m) |
หมายเหตุ : คำสั่ง from __future__ import division เป็นการบอกให้ไพธอนหารเลขโดยผลลัพธ์แสดงเป็นทศนิยม
รายละเอียดส่วนนี้ศึกษาเพิ่มเติมจากหนังสือไพธอนต่อไป
ฟังก์ชั่นสำหรับคำนวณแต่ละพิกเซลโดยรอบจุดที่กำลังพิจารณาชื่อฟังก์ชั่น gen()
แสดงรายละเอียดได้ดังนี้
|
ตัวอย่าง สร้างฟังก์ชั่นสำหรับคำนวณ
Low Pass Filter
|
def gen(im,mask):
img_output
= Image.new("RGB",(im.size[0],im.size[1]))
for
x in range(1,im.size[0]-1):
for
y in range(1,im.size[1]-1):
r
= []; g=[]; b=[]
for
i in range(-1,2):
for
j in range(-1,2):
tmp
= im.getpixel((x+i,y+i))
r.append(tmp[0])
g.append(tmp[1])
b.append(tmp[2])
Red
= Convolution(mask,r)
Green
= Convolution(mask,g)
Blue
= Convolution(mask,b)
RGB
= (Red,Green,Blue)
img_output.putpixel((x,y),RGB)
return
img_output
|
การปรับความคมชัดของภาพ
(Sharped Image)
การประมวลผลแบบ Area Processing เป็นการเปลี่ยนแปลงตัวเลขภายใน
Mask Coefficient ท่านจะพบว่าการทำภาพให้คมชัด หรือเบลอ หรือเป็นลักษณะนูน
ตลอดจนการคำนวณหาขอบเขตของภาพ สุดท้ายแล้วเป็นเพียงการเปลี่ยนแปลงค่า Mask
Coefficient เท่านั้น ส่วนวิธีการและหลักการจะยึดแนวเดียวกันทั้งหมดกล่าวคือ
วิ่งคำนวณจากพิเซลเริ่มต้นไปจนถึงพิกเซลสุดท้าย ฟังก์ชั่นที่ผมสร้างขึ้นมานี้
เขียนด้วยภาษาไพธอน ผมคิดว่าสำหรับผู้ที่เคยเขียนโปรแกรมมาแล้วจะสามารถอ่านโค๊ดที่ผมเขียนขึ้นได้ง่ายมาก
สุดท้ายท่านจะได้หลักการที่แท้จริงของอิมเมจโปรเซสซิ่ง และสามารถนำไปประยุกต์ได้กับภาษาต่าง
ๆ ที่ท่านต้องการ ขอให้ท่านพิจารณาการทำ High Pass โดยมีค่า Mask Coefficient
แสดงได้ดังรายละเอียดต่อไปนี้
หรือ
หรือ
เป็นต้น
ขอให้ท่านพิจารณาตัวอย่างต่อไปนี้
|
ภาพต้นฉบับ : prasriariyametri.bmp
พระศรีอาริยเมตไตย (วัดท่าซุง จังหวัดอุทัยธานี)
|
|
ตัวอย่าง การประมวลผลภาพด้วย
High Pass Filter
|
>> im = open("c:\\temp\\prasriariyametri.bmp")
>> mask = [0, -1, 0, -1,
5, -1, 0, -1, 0]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp")
>> mask = [0, -1, 0, -1,
9 , -1, 0, -1, 0]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output2.bmp") |
 |
 |
ผลลัพธ์
: ผ่านกระบวนการ High Pass Filter
โดยใช้ mask = [0, -1, 0, -1, 5, -1,
0, -1, 0] |
ผลลัพธ์ : ผ่านกระบวนการ High Pass
Filter
โดยใช้ mask = [0, -1, 0, -1, 9, -1,
0, -1, 0]
|
ค่า Mask Coefficient เป็นการประยุกต์ใช้ตัวแปร
List เพื่อเก็บค่าเหล่านั้น เมื่อผ่านการประมวลผลแล้วผลลัพธ์สามารถแสดงได้ดังภาพด้านบน
ภาพจะมีความคมชัดมากขึ้น
การทำภาพเบลอ
(Blued Image)
ในการทำภาพเบลอ เราใช้ฟิลเตอร์ซึ่งเรียกว่า Low Pass โดยค่าของ Mask Coefficient
ของ Low Pass แสดงได้ดังนี้
หรือ
เป็นต้น
ขอให้ท่านพิจารณาตัวอย่างการใช้งาน Low Pass Filter ดังต่อไปนี้
|
ภาพต้นฉบับ : พระเจ้าพรหมมหาราช
อนุสาวรีย์พระเจ้าพรหมมหาราช วัดท่าซุง
|
|
ตัวอย่าง การประมวลผลภาพด้วย
Low Pass Filter
|
>> im = open("c:\\temp\\promaharacha.bmp")
>> mask = [1/9, 1/9, 1/9, 1/9,1/9,1/9,1/9,1/9,1/9]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp")
>> mask = [1/16, 1/8, 1/16, 1/8,
1/4, 1/8, 1/16, 1/16, 1/16]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output2.bmp") |
 |
 |
ผลลัพธ์
: ผ่านกระบวนการ Low Pass Filter
โดยใช้ mask = [1/9, 1/9, 1/9,
1/9,1/9,1/9,1/9,1/9,1/9] |
ผลลัพธ์ : ผ่านกระบวนการ Low Pass
Filter
โดยใช้ mask = [1/16, 1/8, 1/16,
1/8, 1/4, 1/8, 1/16, 1/16, 1/16]
|
ผลลัพธ์จากการคำนวณการประมวลผลแบบ Low Pass Filter แสดงได้ดังภาพด้านบน
การทำภาพนูน
(Emboss Image)
การปรับภาพให้นูน (Emboss) เป็นการกำหนดค่า Mask Coefficient
แสดงได้ดังรายละเอียดต่อไปนี้
หรือ
เป็นต้น
|
ภาพต้นฉบับ : Input.BMP
ภาพถ่ายผู้เขียนขณะปฏิบัติธรรมในต้นธันวาคม 2548
ศาลาข้างกุฎิหลวงพี่สมปอง วัดท่าซุง จังหวัดอุทัยธานี
|
|
ตัวอย่าง สร้างฟังก์ชั่นสำหรับคำนวณหา
Mask Convolution สำหรับวิธี Emboss
|
import Image
def Convolution(Coefficient, Raw_Data):
m =
[]
for
i in range(len(Coefficient)):
m.append(Coefficient[i]
* Raw_Data[i])
return
sum(m) +127 |
เนื่องจากผลลัพธ์การคำนวณ Convolution จะต้องบวกด้วย 127 ดังนั้น ต้องปรับฟังก์ชั่น
Convolution ดังตัวอย่างด้านบน
|
ตัวอย่าง การประมวลผลภาพด้วย
Emboss
|
>> im = open("c:\\temp\\Input.BMP")
>> mask = [1,0,0,0,0,0,0,0,-1]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp")
>> mask = [0,1,0,0,0,0,0,-1,0]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output2.bmp") |
การเรียกใช้งานเปลี่ยนแปลงเพียงค่า Mask ในตัวอย่างนี้กำหนด Mask เป็น [1,0,0,0,0,0,0,0,-1]
และ [0,1,0,0,0,0,0,-1,0] ตามลำดับ
แสดงผลลัพธ์ได้ดังภาพต่อไปนี้
 |
 |
ผลลัพธ์
: ผ่านกระบวนการทำภาพนูน (Emboss)
โดยใช้ mask = [1,0,0,0,0,0,0,0,-1] |
ผลลัพธ์ : ผ่านกระบวนการทำภาพนูน
(Emboss)
โดยใช้ mask = [0,1,0,0,0,0,0,-1,0]
|
การตรวจหาขอบภาพ
(Edge Detector)
ในการหาขอบเขตของภาพประกอบด้วยอัลกอริทึม 4 แบบ
Sobel
Prewitt
Frei-Chen
Laplacian
สามารถแสดงรายละเอียดของแต่ละอัลกอริทึมด้วยค่า Mask Coefficient ดังต่อไปนี้
การตรวจหาขอบเขตวัตถุภายในภาพด้วยวิธี Sobel
การตรวจหาขอบภาพด้วยวิธี Sobel
ในทิศทางแนวนอนใช้ Mask Coefficient คือ
หรือ 
ในทิศทางแนวตั้งใช้ Mask Coefficient คือ
หรือ 
|
ภาพต้นฉบับ : People.bmp
ประชาชนผู้เข้าเสร็จสิ้นจากการฝึกมโนมยิทธิขั้นเต็มกำลัง
ในวันอาทิตย์ที่ 18 ธันวาคม 2548 วัดท่าซุง จ.อุทัยธานี
|
|
ตัวอย่าง การประมวลผลภาพด้วย
Sobel
|
>> im = open("c:\\temp\\People.bmp")
>> mask = [1,2,1,0,0,0,-1,-2,-1]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp") |
 |
ผลลัพธ์
: ผ่านกระบวนการทำภาพนูน (Emboss)
โดยใช้ mask = [1,2,1,0,0,0,-1,-2,-1] |
การตรวจหาขอบเขตวัตถุภายในภาพด้วยวิธี
Prewitt
การตรวจหาขอบภาพด้วยวิธี Prewitt ใช้ค่า Mask Coefficient ดังนี้
ในทิศทางแนวนอนใช้ Mask Coefficient คือ
หรือ 
ในทิศทางแนวตั้งใช้ Mask Coefficient คือ
หรือ 
|
ภาพต้นฉบับ : vihan.bmp
วิหารพระวิสุทธิเทพ วัดท่าซุง จังหวัดอุทัยธานี
|
|
ตัวอย่าง การประมวลผลภาพด้วย
Prewitt
|
>> im = open("c:\\temp\\vihan.bmp
")
>> mask = [1,1,1,0,0,0,-1,-1,-1]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp") |
 |
ผลลัพธ์
: ผ่านกระบวนการหาขอบภาพ (Prewitt)
โดยใช้ mask =[1,1,1,0,0,0,-1,-1,-1] |
การตรวจหาขอบเขตวัตถุภายในภาพด้วยวิธี
Frei-Chen
การตรวจหาขอบภาพด้วยวิธี Frei-Chen
ในทิศทางแนวนอนใช้ Mask Coefficient คือ
หรือ 
ในทิศทางแนวตั้งใช้ Mask Coefficient คือ
หรือ 
|
ตัวอย่าง การประมวลผลภาพด้วย
Low Pass Filter
|
>> im = open("c:\\temp\\budha.bmp
")
>> Root2 = math.sqrt(2)
>> mask = [1,Root2,1,0,0,0,-1,-Root2,-1]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output.bmp") |
 |
ผลลัพธ์
: ผ่านกระบวนการหาขอบภาพ
(Frei-Chen)
mask = [1,Root2,1,0,0,0,-1,-Root2,-1] |
การตรวจหาขอบเขตวัตถุภายในภาพด้วยวิธี
Laplacian
การตรวจหาขอบภาพด้วยวิธี Laplacian
ในทิศทางแนวนอนใช้ Mask Coefficient คือ
หรือ 
|
ภาพต้นฉบับ : vihara.bmp
วิหารทองคำ วัดท่าซุง จ.อุทัยธานี
|
|
ตัวอย่าง การประมวลผลภาพด้วย
Laplacian
|
>> im = open("c:\\temp\\vihara.bmp
")
>> mask = [-1,-1,-1,-1,8,-1,-1,-1,-1]
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp") |
 |
ผลลัพธ์
: ผ่านกระบวนการหาขอบภาพ
ด้วยวิธี Laplacian
โดยใช้ mask = [-1,-1,-1,-1,8,-1,-1,-1,-1] |
การประมวลผลแบบ
Morphology (Morphology Processing)
การประมวลผลแบบ Morphology คล้ายการทำ Convolution แต่จะเรียก Mask Coefficient
แทนด้วยคำว่า Structure Element (S.E.)
การประมวลผลแบบนี้ประกอบด้วยการขยายพิกเซล (Dilation) การลดขนาดพิกเซล (Erosion)
การเปิดพื้นที่ว่างภายในภาพ (Opening) และการปิดพื้นที่ว่างภายในภาพ (Closing)
เป็นต้น ท่านสามารถเปลี่ยนแปลงค่าตัวเลขต่าง ๆ ภายใน S.E. ไำด้ตามความพึงพอใจ
ค่าสูงสุดที่เป็นไปได้คือ 255 ขอให้พิจารณาการประยุกต์ใช้งานดังต่อไปนี้
การขยายพิกเซล (Dilation)
ในการทำ Dilation แทนที่จะเป็นการรวมผลคูณของค่า Mask Coefficient แต่จะเป็นการคำนวณหาค่าที่มากที่สุดของผลคูณเหล่านั้นแทน
ดังนั้น เขียนฟังก์ชั่นสำหรับคำนวณ Dilation ได้ดังนี้
|
ตัวอย่าง สร้างฟังก์ชั่นสำหรับคำนวณหา
Structure Element ของ Dilation
|
import Image
def Dilation_Structure_Element(Coefficient, Raw_Data):
m =
[]
for
i in range(len(Coefficient)):
m.append(Coefficient[i]
* Raw_Data[i])
return
max(m) |
|
ภาพต้นฉบับ : promaharacha.bmp
อนุสาวรีย์พระเจ้าพรหมมหาราช วัดท่าซุง
|
|
ตัวอย่าง สร้างฟังก์ชั่นสำหรับคำนวณ
Dilation
|
def gen(im,mask):
img_output
= Image.new("RGB",(im.size[0],im.size[1]))
for
x in range(1,im.size[0]-1):
for
y in range(1,im.size[1]-1):
r
= []; g=[]; b=[]
for
i in range(-1,2):
for
j in range(-1,2):
tmp
= im.getpixel((x+i,y+i))
r.append(tmp[0])
g.append(tmp[1])
b.append(tmp[2])
Red
= Dilation_Structure_Element(mask,r)
Green
= Dilation_Structure_Element(mask,g)
Blue
= Dilation_Structure_Element(mask,b)
RGB
= (Red,Green,Blue)
img_output.putpixel((x,y),RGB)
return
img_output
|
|
ตัวอย่าง การประมวลผลภาพด้วย
Dilation
|
>> from __future__ import division
>> im = open("c:\\temp\\promaharacha.bmp")
>> m = gen(im,[1,2,3,4,5,6,7,8,9])
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp")
|
 |
ผลลัพธ์
: การขยายพิกเซล (Dilation)
โดยใช้ mask = [1,2,3,4,5,6,7,8,9] |
การลดขนาดพิกเซล (Erosion)
ในการทำ Dilation แทนที่จะเป็นการรวมผลคูณของค่า Mask Coefficient แต่จะเป็นการคำนวณหาค่าที่น้อยที่สุดของผลคูณเหล่านั้นแทน
|
ตัวอย่าง สร้างฟังก์ชั่นสำหรับคำนวณหา
Structure Element ของ Erosion
|
import Image
def Erosion_Structure_Element(Coefficient, Raw_Data):
m =
[]
for
i in range(len(Coefficient)):
m.append(Coefficient[i]
* Raw_Data[i])
return
min(m) |
|
ภาพต้นฉบับ : naka.bmp
พระยานาคราช ทางขึ้นวิหารพระวิสุทธิเทพ วัดท่าซุง จ.อุทัยธานี
|
|
ตัวอย่าง สร้างฟังก์ชั่นสำหรับคำนวณ
Erosion
|
def gen(im,mask):
img_output
= Image.new("RGB",(im.size[0],im.size[1]))
for
x in range(1,im.size[0]-1):
for
y in range(1,im.size[1]-1):
r
= []; g=[]; b=[]
for
i in range(-1,2):
for
j in range(-1,2):
tmp
= im.getpixel((x+i,y+i))
r.append(tmp[0])
g.append(tmp[1])
b.append(tmp[2])
Red
= Erosion_Structure_Element(mask,r)
Green
= Erosion_Structure_Element(mask,g)
Blue
= Erosion_Structure_Element(mask,b)
RGB
= (Red,Green,Blue)
img_output.putpixel((x,y),RGB)
return
img_output
|
|
ตัวอย่าง การประมวลผลภาพด้วย
Erosion
|
>> from __future__ import division
>> im = open("c:\\temp\\naka.bmp")
m = gen(im,[2,10,15,8,12,15,10,15,20])
>> m = gen(im,mask)
>> m.save("c:\\temp\\output1.bmp") |
|
ภาพผลลัพธ์
: การประมวลผลด้วย Erosion
|
การเปิดพื้นที่ว่างภายในภาพ (Opening)
การประมวลผลภาพด้วยวิธีเปิดช่องว่างภายในภาพ (Opening) คือการประมวลผลวิธี
Erosion จากนั้นนำภาพที่ได้ไปผ่านการประมวลผล Dilation
การปิดพื้นที่ว่างภายในภาพ (Closing)
การประมวลผลภาพด้วยวิธีเปิดช่องว่างภายในภาพ (Opening) คือการประมวลผลวิธี
Dilationจากนั้นนำภาพที่ได้ไปผ่านการประมวลผล Erosion
สรุป
บทความนี้ได้นำท่านเรียนรู้และเข้าใจหลักการและแนวคิดพื้นฐานของอิมเมจโปรเซสซิ่ง
(การประมวลผลภาพ) ท่านสามารถใช้ภาษาใด ๆ ในการอิมพลิเมนต์ (สร้าง) ได้ทั้งสิ้น
ไม่ว่าจะเป็น Assembly, C/C++, Visual C++, Visual Basic และอื่น ๆ อีกมากมาย
ท่านจะพบว่าบทความที่ได้ศึกษาไปนั้นใช้เวลาในการประมวลผลแต่ละภาพประมาณ 1
วินาที ท่านสามารถปรับปรุงประสิทธิภาพการประมวลผลให้เร็วขึ้นกว่านี้ โดยใช้เทคนิคการเขียนโปรแกรมชั้นสูง
กล่าวคือการเขียนโปรแกรมแบบมัลติเธรดดิ่ง (Multi Threading) ซึ่งจะกล่าวถึงในบทความถัด
ๆ ไป (หากมีเวลา) สุดท้ายนี้ ขอความสวัสดีมีชัยจงมีแด่พ่อแม่พี่น้องที่รักทุกท่าน
สวัสดีครับ !!
แหล่งอ้างอิง
- อิมเมจโปรเซสซิ่งสำหรับผู้เริ่มต้น
- คู่มือการเขียนโปรแกรมวินโดวส์ขั้นสูงด้วย Visual C++
- คู่มือไพธอน http://www.python.org
- คู่มือการใช้งาน PIL (Python Image Library)
- สมการคณิตศาสตร์ โดย MathCAD 5.0
- แต่งภาพต่าง ๆ โดย Photoshop
- กล้อง Canon
- วัดท่าซุง (วัดจันทราราม) จังหวัดอุทัยธานี พระราชพรหมยาน (หลวงปู่ฤาษีลิงดำ)
|
|
|