¡òã»ãðáçå¼åàò¾´éçâ...

13
NECTEC การประมวลผลภาพดวย C++ Builder ตอน 1 พื้นฐานภาพ สถิติของภาพ หลักการของภาพสี และ ฮิสโตแกรม (Image Processing with C++ Builder Part 1: Basic imaging, Colour model concept and Histogram) จันทรจิรา สินทนะโยธิน ศูนยเทคโนโลยีอิเล็กทรอนิกสและคอมพิวเตอรแหงชาติ ปจจุบันการพัฒนาการเขียนโปรแกรมไดเขามามีบทบาทมาก ทั้งในเรื่องการเรียนการสอน การทํางานวิจัย การแขงขัน ตลอดจนการพัฒนาศักยภาพทางดานวิทยาศาตรและเทคโนโลยีของบานเรา หลายคนอาจคิดวาการ พัฒนาโปรแกรมเปนเรื่องยาก มีเทคนิคที่ซับซอน ดังนั้นผูเขียนจึงอยากเสนอการพัฒนาโปรแกรมเพื่อการ วิเคราะหภาพ หรือประมวลผลภาพ หากไดติดตามกันไปตลอด คุณก็จะสามารถพัฒนาตัวเองใหเปนผูเชี่ยวชาญ การเขียนโปรแกรมดานการประมวลผลภาพไดอยางอัศจรรยทีเดียวคะ หลายคนอาจสงสัยวาทําไมตอง C++ Builder คําตอบก็คือวา C++ Builder เปนภาษาที่งายสําหรับการออกแบบ GUI (Graphics User Interface) เปนภาษาที่เหมาะกับการจัดการกับภาพ การคํานวณทําไดอยางรวดเร็ว เขียนงาย เขาใจงาย และสะดวกสําหรับ การเรียนรู แตเราคงไมเริ่มสอนกันตั้งแตพื้นฐานการใชภาษา C++ Builder กันหรอกนะคะ เพราะคุณสามารถ หาหนังสือเกี่ยวกับภาษา C++ Builder อานไดตามรานหนังสือทั่วไปอยูแลว แตเราจะมุงเนนไปสูการ พัฒนาโปรแกรมเพื่อการประมวลผลภาพ หรือที่เรียกเปนภาษาอังกฤษวา Image Processing ซึ่งแนนอนวา คุณคงไมสามารถหาอานไดงายๆ แตขณะนี้เราไดสรางโอกาศใหคุณไดศึกษาเทคนิคที่เราจะนําเสนอ โดยผูเขียน จะเนนการประมวลผลภาพโดยใช C++ Builder สําหรับผูที่ใชภาษาอื่นอยู ก็สามารถที่จะเรียนรูหลักการและนํา ไปประยุกตไดกับภาษาที่ตนเองถนัดไดนะคะ ผูเขียนจะทําการนําเสนอทั้งหมด 10 ตอนดวย กันโดยจะมีการนํา เสนอเรื่องราวดังตอไปทีตอนที1: พื้นฐานภาพ สถิติของภาพ หลักการของภาพสี และ ฮิสโตแกรม (Basic/Statistic image, Colour model concept and Histogram) ตอนที2: การซอนภาพ การทําภาพใหเปนจุดขาวและดํา การแปลงภาพสีเปนภาพขาวดํา และขาวดําเปนสี (Overlay, Dithering, Colour to B/W transformation and conversion) ตอนที3: การทําภาพใหคมชัดขึ้น (Contrast Enhancement) ตอนที4: การหาขอบภาพ (Edge detection) ตอนที5: การแบงภาพเปนพื้นที(Segmentation) ตอนที6: การจําแนกบริเวณ (Classification) ตอนที7: การแปลงฟูริเยร (Fourier Transform) ตอนที8: การทําภาพมัวใหชัด (Image Restoration) ตอนที9: การซอนทับภาพโดยกําหนดตําแหนง (Image Registration) ตอนที10: การทําภาพใหบิดเบี้ยว (Geometric Transformation) ตอนที1: พื้นฐานภาพ สถิติของภาพ หลักการของภาพสี การเปลี่ยนภาพสีเปนขาวดําและ ขาวดําเปนสี (Basic/Statistic image, Colour model concept and Histogram) ภาพดิจิตอลจะแทนดวยเมตริกซใน 2 มิติ โดยแตละหนวยในเมตริกซจะเรียกวาพิกเซล (pixel) กระบวนการแสดงภาพใหปรากฏขึ้นมานั้นก็คือการแสดงคาของเมตริกซ โดยแตละ pixel จะมีคาเฉพาะตัวแสดง

Upload: duongkiet

Post on 13-Mar-2018

245 views

Category:

Documents


10 download

TRANSCRIPT

Page 1: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

การประมวลผลภาพดวย C++ Builder ตอน 1พื้นฐานภาพ สถิติของภาพ หลักการของภาพสี และ ฮิสโตแกรม

(Image Processing with C++ Builder Part 1: Basic imaging, Colour model concept andHistogram)

จันทรจิรา สินทนะโยธินศูนยเทคโนโลยีอิเล็กทรอนิกสและคอมพิวเตอรแหงชาติ

ปจจุบันการพัฒนาการเขียนโปรแกรมไดเขามามีบทบาทมาก ท้ังในเรื่องการเรียนการสอน การทํางานวิจัยการแขงขัน ตลอดจนการพัฒนาศักยภาพทางดานวิทยาศาตรและเทคโนโลยีของบานเรา หลายคนอาจคิดวาการพัฒนาโปรแกรมเปนเรื่องยาก มีเทคนิคที่ซับซอน ดังนั้นผูเขียนจึงอยากเสนอการพัฒนาโปรแกรมเพื่อการวิเคราะหภาพ หรือประมวลผลภาพ หากไดติดตามกันไปตลอด คุณก็จะสามารถพัฒนาตัวเองใหเปนผูเชี่ยวชาญการเขียนโปรแกรมดานการประมวลผลภาพไดอยางอัศจรรยทีเดียวคะ หลายคนอาจสงสัยวาทําไมตอง C++Builder คําตอบก็คือวา C++ Builder เปนภาษาที่งายสําหรับการออกแบบ GUI (Graphics User Interface)เปนภาษาที่เหมาะกับการจัดการกับภาพ การคํานวณทําไดอยางรวดเร็ว เขียนงาย เขาใจงาย และสะดวกสําหรับการเรียนรู แตเราคงไมเริ่มสอนกันตั้งแตพ้ืนฐานการใชภาษา C++ Builder กันหรอกนะคะ เพราะคุณสามารถหาหนังสือเก่ียวกับภาษา C++ Builder อานไดตามรานหนังสือท่ัวไปอยูแลว แตเราจะมุงเนนไปสูการพัฒนาโปรแกรมเพื่อการประมวลผลภาพ หรือท่ีเรียกเปนภาษาอังกฤษวา Image Processing ซึ่งแนนอนวาคุณคงไมสามารถหาอานไดงายๆ แตขณะนี้เราไดสรางโอกาศใหคุณไดศึกษาเทคนิคที่เราจะนําเสนอ โดยผูเขียนจะเนนการประมวลผลภาพโดยใช C++ ฺBuilder สําหรับผูท่ีใชภาษาอื่นอยู ก็สามารถที่จะเรียนรูหลักการและนําไปประยุกตไดกับภาษาที่ตนเองถนัดไดนะคะ ผูเขียนจะทําการนําเสนอทั้งหมด 10 ตอนดวย กันโดยจะมีการนําเสนอเรื่องราวดังตอไปท่ีตอนที่ 1: พ้ืนฐานภาพ สถิติของภาพ หลักการของภาพสี และ ฮิสโตแกรม

(Basic/Statistic image, Colour model concept and Histogram)ตอนที่ 2: การซอนภาพ การทําภาพใหเปนจุดขาวและดํา การแปลงภาพสีเปนภาพขาวดํา และขาวดําเปนสี

(Overlay, Dithering, Colour to B/W transformation and conversion)ตอนที่ 3: การทําภาพใหคมชัดขึ้น (Contrast Enhancement)ตอนที่ 4: การหาขอบภาพ (Edge detection)ตอนที่ 5: การแบงภาพเปนพ้ืนที่ (Segmentation)ตอนที่ 6: การจําแนกบริเวณ (Classification)ตอนที่ 7: การแปลงฟูริเยร (Fourier Transform)ตอนที่ 8: การทําภาพมัวใหชัด (Image Restoration)ตอนที่ 9: การซอนทับภาพโดยกําหนดตําแหนง (Image Registration)ตอนที่ 10: การทําภาพใหบิดเบี้ยว (Geometric Transformation)

ตอนที่ 1: พ้ืนฐานภาพ สถิติของภาพ หลักการของภาพสี การเปลี่ยนภาพสีเปนขาวดําและ ขาวดําเปนสี(Basic/Statistic image, Colour model concept and Histogram)

ภาพดิจิตอลจะแทนดวยเมตริกซใน 2 มิติ โดยแตละหนวยในเมตริกซจะเรียกวาพิกเซล (pixel)กระบวนการแสดงภาพใหปรากฏขึ้นมานั้นก็คือการแสดงคาของเมตริกซ โดยแตละ pixel จะมีคาเฉพาะตัวแสดง

Page 2: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

ถึงสีตางๆ โดยปกติภาพขาว-ดํา จะมีคาของ pixel อยูระหวาง 0 ถึง 255 สวนภาพสีนั้นแตละ pixel จะประกอบไปดวยสีแดง (R) สีเขียว(G) สีนํ้าเงิน(B) โดยแตละสีจะมีคาของ pixel อยูระหวาง 0 ถึง 255 เชนกันหากจะใหเขาใจไดชัดเจนมากขึ้นสามารถพิจารณาไดจากกลองสี่เหลี่ยมที่มีพิกัดแทนดวย (R, G, B) สีดําจะมีพิกัด (0, 0, 0); สีขาวมีพิกัด (255, 255, 255); สีแดง (255, 0, 0); สีเขียว (0, 255, 0); สีนํ้าเงิน (0, 0,255); สีเหลือง (255, 255, 0); สีฟาคราม (0, 255, 255); สีมวง (255, 0, 255) ซึ่งสีท้ังแปดนี้จะอยูตรงมุมของกลองสี่เหลี่ยม สวนคาสีท่ีอยูในกลองจะประกอบไปดวยคา RGB ท่ีมีอัตราสวนที่ แตกตางกันออกไปและแสดงดวยสีเฉพาะตัวสําหรับแตละอัตราสวนดวย

ภาพที่ 1: ธรรมชาติของภาพ

ภาพโดยทั่วไปจะประกอบไปดวย pixel จํานวนมาก ยกตัวอยางเชนภาพที่มีขนาดกวางxยาวเปน 512x512ก็จะมีจํานวน pixel เปนเศษ 1/4 ลานเปนตน ตัวชี้วัดที่ใชในการพิจารณาภาพโดยทั่วไปของคอมพิวเตอรมี อยู2 ตัวไดแกคาทางสถิติ และ histogram ของภาพ คาทางสถิติก็ไดแก ขนาดของภาพ กวาง x ยาว จํานวน pixelคาต่ําสุด คาสูงสุด คาเฉลี่ย คาเบ่ียงเบนมาตราฐาน เปนตน สวน Histogram ไดแกกราฟที่แสดงถึงความถี่หรือความหนาแนนของคาสี (gray level) โดยแกนนอนคือคาความเขมสี และแกนตั้งคือคาความถี่ของแตละสี

ภาพที่ 2: หลักการพิจารณาภาพ ทางสถิติ และ Histogram

Page 3: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

เอาหละ มาถึงตอนนี้เราก็จะมาลองเขียนโปรแกรม ศึกษารายละเอียดของภาพ ตลอดจนคาทางสถิติของภาพกัน เนื่องจากวาตอนนี้ เปนตอนแรก หลายๆ คน อาจจะยังงงๆ จับตนชนปลายไมถูก ไมรูวาจะเริ่มอยางไรดี ดังนั้นผูเขียนจึงไดตัดสินใจที่จะเริ่มจากพื้นฐานการจัดการกับภาพที่คอนขางละเอียดซะกอน แตในตอนตอไป ผูเขียนคงจะไมสาธยายใหเห็นละเอียดเปนขั้นๆ ตอนๆ เชนนี้อีกแลวนะคะ เอาหละมาเริ่มกันเลยดีกวาจะไดไมเสียเวลากันนะคะ1. Borland C++ Builderขั้นแรกก็มาทําความเขาใจโปรแกรม Borland C++ Builder กันกอน เม่ือเปดโปรแกรมขึ้นมาสิ่งท่ีเห็นก็คือหนาจอดังภาพที่ 1.1 สวนดานบนของโปรแกรมจะเปนสวนของเมนู สําหรับเรียกใชฟงกชันตางดานขางซายจะเปนหนาจอที่ใชสําหรับกําหนด parameter ตางๆ (Object Instpector) และมี Window text(Unit1.cpp) ใชในการเขียน Source code สวน Window ท่ีซอนทับอยู (Form1) จะใชแสดงเปนหนาจอ GUIของเรานั่นเอง

ภาพที่ 3: เริ่มตนเปดโปรแกรม C++ Bilderสําหรับการเขียน Basic โปรแกรมที่เก่ียวกับ Graphics ท่ีจะกลาวถึงในที่นี้จะใช Menu

ท่ีเก่ียวของดังตอไปนี้ (เรียงตามรูปวงกลมตามภาพที่ 4)(A) Memo (จาก Standard Tag) เมนูสําหรับสรางพ้ืนที่แสดงขอความ(B) Button (จาก Standard Tag) เมนูสําหรับสรางปุม(C) Image (จาก Additional Tag) เมนูสําหรับสรางพ้ืนที่แสดงภาพ(D) Open Picture Dialog (จาก Dialog Tag) เมนูสําหรับใชเปดภาพ(E) Save Picture Dialog (จาก Dialog Tag) เมนูสําหรับใชบันทึกภาพ

ภาพที่ 4: แสดงเมนูท่ีเก่ียวของกับการสราง GUI ท่ีเก่ียวกับกราฟฟก

Page 4: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

2. สราง Graphics Users Interface (GUI)หลังจากเรียนรูโปรแกรม C++ Builder ในสวนที่จําเปนตองใชงานเรียบรอยแลว ก็จะเปนขั้นของการออกแบบหนาจอ GUI(A) ขั้นแรก click ไปที่ Image menu (จาก Additional Tag) และ click ไปวางยัง Form1

ขยายขนาดดังรูปเสนประ จัดใหเปนไปตามรูป ทําอยางเดียวกันสําหรับ 4 Images แสดงดังภาพ(B) click ไปที่ button (จาก Standard Tag) และ click ไปวางยัง Form1 จัดใหเปนไปตามรูป ทําอยางเดียวกัน

ใหได 3 buttons แสดงดังภาพ(C) click ไปที่ Memo (จาก Standard Tag) และ click ไปวางยัง Form1 จัดใหเปนไปตามรูป

ทําอยางเดียวกัน ใหได 3 Memos แสดงดังภาพ(D) click ไปยัง Open Picture Dialog และ Save Picture Dialog (จาก Dialog Tag) ไปวางไวบน Form1

ดังท่ีเห็นในรูปแรก เลือก filter (เมนู Properties ของ Object Inspector) ใหเหลือแคบรรทัดที่เปนBitmaps (*.bmp) | *.bmp (บรรทัดที่ 4) บรรทัดเดียว บรรทัดที่เหลือลบทิ้ง

(E) เปลี่ยน Caption ตางๆ อันไดแก- Caption ของ Form1 ในที่นี้เปลี่ยนเปน [การประมวลผลภาพดวย C++ Builder ตอน 1]- Caption ของ buttons ไปเปนตางกัน มีดังนี้ Button1 -> Open Image , Button2 -> Histogram,Button3 -> Exit

หลังจากเปลี่ยน Caption ตางๆ เรียบรอยแลวก็จะไดรูปแบบ GUI ท่ีพึงประสงคดังภาพที่ 5

ภาพที่ 5: โครงสราง GUI ท่ีออกแบบไว

แลวเราก็จะทําการ Save โปรแกรม GUI ท่ีเราสรางขึ้นมา ซึ่งควรนําไปเก็บไวใน Directory เฉพาะ(แตละโปรแกรมควรจัดเก็บไวใน directory ท่ีแตกตางกันออกไป) โดยใชคําลั่ง Save All (จาก File Menu)และจะมี dialog โผลขึ้นมาใหเราทําการบันทึก Source code (Unit1.cpp) ซึ่งสามารถที่จะเปลี่ยนชื่อfileไดใหมไดตามตองการ หลังจากบันทึก source code เสร็จ ก็จะโผล Dialog ใหมขึ้นมา สําหรับบันทึก Projectซึง่เปน file สําหรับบันทึกลักษณะของ GUI ท่ีเราออกแบบไว (บันทึกในชื่อท่ีแตกตางจาก Source code)ขณะนี้โปรแกรม GUI ท่ีถูกออกแบบขึ้นมาสามารถที่จะ ทําการ Run ได (วิธีการ Run สามารถกระทําไดโดยใชคําสั่ง Run จาก Run menu หรือ F9 อยางไรก็ตามจะมีขอสังเกตวาเมื่อกด button แตละอันจะยังไมมีอะไร

Page 5: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

เกิดขึ้น ซึ่งหากตองการใหมีการทํางานใดๆ เกิดขึ้นจําเปนตองเขียน Source code การทํางานใหกับ buttonแตละอันนั่นเอง

3. เขียน Source codeถึงตอนนี้ก็จะมาถึงหัวใจหลักของโปรแกรมก็คือการเขียน Source code ใหมีการทํางานเกิดขึ้นใน GUI

ท่ีถูกออกแบบขึ้นมานั่นเอง กอนอ่ืนจะขอกลาวถึง Souce code ท่ีถูกสรางขึ้นอยางอัตโนมัติ จะแสดงใหเห็นดังนี้Part1.cpp

//------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop

#include "Part1.h"//------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm"TForm1 *Form1;//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}//------------------------------------------------------------------------

Part1.h//------------------------------------------------------------------------#ifndef Part1H#define Part1H//------------------------------------------------------------------------#include <Classes.hpp>#include <Controls.hpp>#include <StdCtrls.hpp>#include <Forms.hpp>#include <Dialogs.hpp>#include <ExtCtrls.hpp>#include <ExtDlgs.hpp>//------------------------------------------------------------------------class TForm1 : public TForm{__published: // IDE-managed Components TImage *Image1; TImage *Image2; TImage *Image3; TImage *Image4; TMemo *Memo1; TMemo *Memo2; TMemo *Memo3; TButton *Button1; TButton *Button2; TOpenPictureDialog *OpenPictureDialog1; TSavePictureDialog *SavePictureDialog1; TButton *Button3;

Page 6: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

private: // User declarationspublic: // User declarations __fastcall TForm1(TComponent* Owner);};//------------------------------------------------------------------------extern PACKAGE TForm1 *Form1;//------------------------------------------------------------------------#endif

ในการเปด header file (.h) สามารถกระทําไดดวย file open หรือ mouse ขวา click ไปยังตําแหนงชื่อ file#include “Part1.h” แลวเลือก Open Source/Header file และสามารถสลับไปมาไดระหวาง source code และheader file โดยใช Tag เปนตัวเลือก ซึ่ง Source code ดังกลาวนี้ไดถูกสรางขึ้นอยางอัตโนมัติดังนั้นจึงจะไมสามารถลบทิ้งได หาไมแลว โปรแกรมจะไมสามารถ Run ได อยางปกติ

ขั้นตอนตอไปกอนที่จะเขียนคําสั่งใหกับแตละ button จําเปนจะตองกําหนดตัวแปรที่สําคัญที่จําเปนตองใชตางๆ ซึ่งสําหรับโปรแกรมนี้ก็มีดังนี้ (กําหนดตัวแปรใน header file – Par1.h) หลังจากบรรทัดprivate: // User declarations ใหเติมตัวแปรตอไปนี้

Graphics::TBitmap *bitmap1, *bitmap2, *bitmap3, *bitmap4; Byte *newscanline1, *newscanline2, *newscanline3, *ptr; TRect Rect1, Rect2; int i, j, k, n; bool HaveImg; int red[5], green[5], blue[5]; String RcolorValue, GcolorValue, BcolorValue;ตอไปก็ควรจะมีการกําหนด Parameter เริ่มตนเมื่อ Run Program ซึ่งสามารถกระทําไดโดย ใช Menu

ทางซายมือ (Object Inspector) เลือกไปท่ี Form1 (ตรงชองวางบนสุด) แลว click ไปที่ Event Tag และDouble click บน ชองซายมือของ OnCreate จนปรากฏคําวา FormCreate และ Cursor จะไปปรากฎอยูตรงSource code พรอมดวย procedure FormCreate ใหกําหนด parameters ดังท่ีแสดงไวvoid __fastcall TForm1::FormCreate(TObject *Sender){bitmap1 = new Graphics::TBitmap; bitmap2 = new Graphics::TBitmap; bitmap3 = new Graphics::TBitmap; bitmap4 = new Graphics::TBitmap; bitmap2->Width = 5; bitmap3->Width = 5; bitmap4->Width = 5; bitmap2->Height = 5; bitmap3->Height = 5; bitmap4->Height = 5; bitmap2->PixelFormat = pf24bit; bitmap3->PixelFormat = pf24bit; bitmap4->PixelFormat = pf24bit; Rect1 = Rect(0, 0, Image1->Width, Image1->Height); Rect2 = Rect(0, 0, Image2->Width, Image2->Height); Memo1->Clear(); Memo2->Clear(); Memo3->Clear(); HaveImg = false;

Page 7: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

}

สําหรับคําสั่งสําหรับแตละ button สามารถเขียนไดโดย Double click บน button ท่ีเราตองการเขียนคําสั่งใหนั่นเอง cursor ก็จะเปลี่ยนมาตําแหนง source และสราง procedure จากนั้นก็จะตองใส source codeเขาไปเพ่ือใหโปรแกรมทํางานดังท่ีตองการ

ตอนนี้เราก็จะมาดูการเขียน source code สําหรับแตละ button ดังตอไปนี้(A) Open Imagevoid __fastcall TForm1::Button1Click(TObject *Sender){ try{ if(OpenPictureDialog1->Execute()) { bitmap1->LoadFromFile(OpenPictureDialog1->FileName); Image1->Canvas->StretchDraw(Rect1, bitmap1);

HaveImg = true; }

}catch(...) { ShowMessage( "Can not open Image"); }}ผลที่ได เม่ือทําการ Run โปรแกรม แลวกดปุม Open Image เราก็จะสามารถเปดภาพ BMP ใดๆ ใหแสดงในพ้ืนที่ Image1 ไดดังภาพ

ภาพที่ 6: ผลการ run โปรแกรมเมื่อกดปุม Open Image จะปรากฏ dialog สําหรับเปดภาพ BMP(B) การแสดงคาความเขมสีของแตละ Pixel และการ Zoom ภาพของแตละเฉดสีในการทํางานของโปรแกรมในสวนนี้ เราจะออกแบบใหบริเวณ Image2-Image4 แสดงภาพขยายของแตละเฉดสีแดง เขียว น้ําเงิน ณ.ตําแหนงท่ีเมาสเคลื่อนที่บนภาพ และในขณะเดียวกันเมื่อทําการ Memo1-Memo3ก็จะแสดงคาความเขมสีของภาพณ.บริเวณที่เมาสเคลื่อนที่ดวย เอาหละหลังจากที่ออกแบบวาโปรแกรมจะทํางานอยางไร เราก็เริ่มเขียนโปรแกรมในสวนนี้กันดังนี้

Page 8: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

1. ตรง Object Inspector ให Click เลือก Image1 และ doublic click ตรงสวน OnMouseMove ใน EventsTab ตรงสวนของ Part1.cpp จะปรากฎ Source code ดังนี้void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y){

}//------------------------------------------------------------------------จากนั้นก็เขียน source code ตามดังนี้void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y){ int xpos, ypos, ii, jj; Memo1->Clear(); Memo2->Clear(); Memo3->Clear(); if(HaveImg == true) { xpos = (int)((float)X*(float)bitmap1->Width/(float)Image1->Width); ypos = (int)((float)Y*(float)bitmap1->Height/(float)Image1->Height); for(j= 0; j< 5; j++){ jj = ypos + j - 2; if(jj < 0) jj = 0; if(jj >= bitmap1->Height) jj = bitmap1->Height-1; ptr = (Byte *)(bitmap1->ScanLine[jj]); newscanline1 = (Byte *)(bitmap2->ScanLine[j]); newscanline2 = (Byte *)(bitmap3->ScanLine[j]); newscanline3 = (Byte *)(bitmap4->ScanLine[j]); RcolorValue = ""; GcolorValue = ""; BcolorValue = ""; for(i = 0; i< 5; i++) { ii = xpos + i -2; if (ii < 0) ii = 0; if (ii >= bitmap1->Width) ii = bitmap1->Width-1; for(k=0; k< 3; k++) { newscanline1[3*i+k] = ptr[3*ii+2]; newscanline2[3*i+k] = ptr[3*ii+1]; newscanline3[3*i+k] = ptr[3*ii]; } red[i] = ptr[3*ii+2]; green[i] = ptr[3*ii+1]; blue[i] = ptr[3*ii]; if(red[i] < 10) RcolorValue = RcolorValue + " " + IntToStr(red[i]); else if (red[i] < 100) RcolorValue = RcolorValue + " " + IntToStr(red[i]); else RcolorValue = RcolorValue + " " + IntToStr(red[i]);

Page 9: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

if(green[i] < 10) GcolorValue = GcolorValue + " " + IntToStr(green[i]); else if (green[i] < 100) GcolorValue = GcolorValue + " " + IntToStr(green[i]); else GcolorValue = GcolorValue + " " + IntToStr(green[i]);

if(blue[i] < 10) BcolorValue = BcolorValue + " " + IntToStr(blue[i]); else if (blue[i] < 100) BcolorValue = BcolorValue + " " + IntToStr(blue[i]); else BcolorValue = BcolorValue + " " + IntToStr(blue[i]);

} Memo1->Lines->Add(RcolorValue); Memo2->Lines->Add(GcolorValue); Memo3->Lines->Add(BcolorValue); } Image2->Canvas->StretchDraw(Rect2, bitmap2); Image3->Canvas->StretchDraw(Rect2, bitmap3); Image4->Canvas->StretchDraw(Rect2, bitmap4);

}}//------------------------------------------------------------------------

ผลที่ไดจะพบวา หลังจากที่เปดภาพเปนที่เรียบรอย เม่ือเราเคลื่อนเมาส ไปยังบริเวณใดของภาพก็ตามหนาตางดานขางทั้งสามจะแสดงภาพขยายขนาด 5x5 ณ.ตําแหนงท่ีเมาสวางบนภาพ ในเฉดสี แดง เขียวและนําเงินตามลําดับ ขณะท่ี Memo1-Memo3 จะแสดงคาความเขมสีของแตละเฉดสี แดงเขียวและนํ้าเงินตามลําดับ ดังจะเห็นไดจากภาพที่ 7

ภาพที่ 7: แสดงภาพขยายและคาความเขมสี ณ.ตําแหนงท่ีเมาสเคลื่อนที่ สําหรับสีแดง เขียว และน้ําเงิน

Page 10: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

เอาหละ ตอนนี้เราก็พอจะทราบแลววา เราจะสามารถหาคาความเขมสีของแตละจุดสีไดอยางไร คราวนี้เราก็จะนําความรูในการหาคาจุดสีไป วาดบนกราฟโดย แกนนอนจะเปนคาความเขมของจุดสี สวนแกนตั้งจะเปนความถี่ของจํานวน pixel ท่ีมีความเขมสีนั้นๆ กราฟดังกลาวนี้จะมีชื่อเรียกอีกอยางวา ฮิสโตแกรม (Histogram)(C) ฮิสโตแกรม (Histogram)ในการสรางฮิสโตแกรม เราจะสราง Form ใหมขึ้นมา โดย Form ใหมนี้จะแสดงฮิสโตแกรมของภาพ การสรางform สามารถกระทําไดโดย เลือก File -> new แลวเลือก Form ดังภาพที่ 8

ภาพที่ 8 หนาตางสําหรับสราง Form ใหม ภาพที่ 9: หนาตางสําหรับ Add seriesสําหรับ Form ใหมท่ีถูกสรางขึ้นมา จะมีชื่อเรียกวา Form2 เราก็จะทําการออกแบบหนาจอของ Form 2 ใหเปนไปตามที่เราตองการ ในที่นี้ เราจะใช Form2 สําหรับแสดงฮิสโตแกรม เราจะใช Chart จาก Additional tabเม่ือวาง chart ลงบน form2 แลว ก็ double click เพ่ือ add series และออกแบบกราฟ ดังแสดงใหดูในภาพที่ 9จากนั้นก็ออกแบบหนาตา GUI ของ Form2 ใหเปนไปดังภาพที่ 10

ภาพที่ 10: หนาตา GUI ของ Form2 ท่ีจะใชแสดงฮิสโตรแกรมของภาพเอาหละมาถึงตรงนี้เราก็ตองทําให Form1, Form2 สามารถเชื่อมถึงกันได และสามารถสงผานขอมูลใหกันไดเราก็จะทําการ include “Unit2.h” (header file ของ Form2) ใน Part1.h สําหรับ สําหรับ Unit2.hเราจะเพ่ิมเติมลงไปดังนี้public: // User declarations __fastcall TForm2(TComponent* Owner);

Page 11: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

void __fastcall TForm2::ShowForm2(Graphics::TBitmap *bitmap1);สวน Unit2.cpp เราจะเพิ่ม code ลงไปดังนี้void __fastcall TForm2::ShowForm2(Graphics::TBitmap *bitmap1){ ShowModal();}คราวนี้เราก็จะกลับมายัง Part1.cpp เพ่ิม code เม่ือทําการกดปุม Histogram บน form1 ดังนี้void __fastcall TForm1::Button2Click(TObject *Sender){ Form2->ShowForm2(bitmap1);}//------------------------------------------------------------------------ตอนนี้ ถาเราลองทําการ Run โปรแกรม เม่ือเรากดปุม Histogram บน form1, form2 ก็จะปรากฎออกมาคราวนี้เราก็จะมาทําการเขียน Source code การทํางานใหกับ Form2 กันนะคะในสวนของ Unit2.h เพ่ิมตัวแปรดังนี้private: // User declarations int i, j, k, xsize, ysize, r, g, b, t; float hist1[255], hist2[255], hist3[255], hist[255]; Graphics::TBitmap *BMP;สําหรับ Unit2.cpp เขียน code ดังนี้void __fastcall TForm2::ShowForm2(Graphics::TBitmap *bitmap){ Byte *ptr1; xsize = bitmap->Width; ysize = bitmap->Height; for(i=0; i< 256; i++){ hist1[i] = hist2[i] = hist3[i] = hist[i] = 0; } for(j=0; j<ysize; j++) { ptr1 = (Byte *)(bitmap->ScanLine[j]); for(i=0; i< xsize; i++){ r = ptr1[3*i+2]; g = ptr1[3*i+1]; b = ptr1[3*i]; hist1[r] = hist1[r]+1; hist2[g] = hist2[g]+1; hist3[b] = hist3[b]+1; t = (r+ g +b)/3; hist[t] = hist[t]+1; } } for(i=0; i< 256; i++) { Series1->AddXY((float)i, hist1[i], ' ', clTeeColor); Series2->AddXY((float)i, hist2[i], ' ', clTeeColor); Series3->AddXY((float)i, hist3[i], ' ', clTeeColor); Series4->AddXY((float)i, hist[i], ' ', clTeeColor); } ShowModal();

Page 12: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

}

void __fastcall TForm2::Button2Click(TObject *Sender){ Close();}//------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender){ Chart1->UndoZoom();}//------------------------------------------------------------------------

void __fastcall TForm2::CheckBox1Click(TObject *Sender){ if(CheckBox1->Checked == true) { for(i=0; i< 256; i++) Series1->AddXY((float)i, hist1[i], ' ', clTeeColor); } else Series1->Clear();}//------------------------------------------------------------------------

void __fastcall TForm2::CheckBox2Click(TObject *Sender){ if(CheckBox2->Checked == true) { for(i=0; i< 256; i++) Series2->AddXY((float)i, hist2[i], ' ', clTeeColor); } else Series2->Clear();}//-------------------------------------------------------------------------void __fastcall TForm2::CheckBox3Click(TObject *Sender){ if(CheckBox3->Checked == true) { for(i=0; i< 256; i++) Series3->AddXY((float)i, hist3[i], ' ', clTeeColor); } else Series3->Clear();}//------------------------------------------------------------------------

void __fastcall TForm2::CheckBox4Click(TObject *Sender){ if(CheckBox4->Checked == true) { for(i=0; i< 256; i++) Series4->AddXY((float)i, hist[i], ' ', clTeeColor); } else Series4->Clear();}

Page 13: ¡ÒûÃÐÁÇżÅÀÒ¾´éÇ C++ Builder µÍ¹ 1 · PDF file- Caption ของ Form1 ในที่นี้ี่เปล น [ยนเปการประมวลผลภาพด

NECTEC

//------------------------------------------------------------------------

(D) จบโปรแกรม (Exit)

มาถึงชวงนี้ ผูอานคงจะพอมองภาพกันออกแลวนะคะ วาจะเขียนการทํางานใหสัมพันธกับ GUI ท่ีเราสรางขึ้นมาไดอยางไร สุดทายก็จบโปรแกรม ก็กลับมายัง form1 แลว double click ท่ี Exit แลวเขียน code เพ่ิมไปดังนี้void __fastcall TForm1::Button3Click(TObject *Sender){ delete (bitmap1); delete (bitmap2); delete (bitmap3); delete (bitmap4); Close();}//---------------------------------------------------------------------โปรแกรมนี้ก็เปนอันเสร็จสมบูรณ เม่ือทําการ Run ก็จะไดผลดังภาพที่ 11 สําหรับ source codeของโปรแกรมสามารถ download ไดจาก web site ขางลางนะคะ สําหรับฉบับนี้ก็ขอตจบลงตรงนี้รอติดตามฉบับตอๆ ไปนะคะ คงจะมีอะไรมันสๆ ใหเราไดเรียนรูกันอีกเยอะเชียวคะDownload source code http://202.44.221.60/pooh/nectec_magazine/src/part1_src.zip

ภาพที่ 11: โปรแกรมแสดง คาความเขมสี และ ฮิสโตแกรมของภาพ