การประมวลผลภาพดิจิตอลด้วยโปรแกรม...

22
1 Digital Image Processing using Microsoft Visual C++ ,KMITNB การประมวลผลภาพดิจิตอล (Digital Image Processing) เปนกระบวนการที่เกี่ยวของกับการแปลง ขอมูลภาพใหอยูในรูปแบบขอมูลดิจิตอล (Digital format) ซึ่งสามารถที่จะนําเอาขอมูลนี้จัดการผาน กระบวนการตางๆ ดวยโปรแกรมคอมพิวเตอรได ภาพดิจิตอลเปนภาพที่ประกอบดวยจุดภาพเล็กๆจํานวน มากเรียกวา พิกเซล (pixel) โดยใชตัวเลขแทนคาของระดับสีหรือระดับความสวางของแตละพิกเซล ซึ่ง สามารถปรับแตงเพื่อการแสดงผลภาพตามตองการได ดังนั้นภาพดิจิตอลจึงมีขอดีตรงทีสามารถนํามา ประมวลผลปรับปรุงคุณภาพของขอมูลดวยกระบวนการตางๆดวยคอมพิวเตอรได ลักษณะและความหมายของ Pixel ในโลกของกราฟกที่ใชในงานคอมพิวเตอร Pixel ถือเปนหนวยยอยที่เล็กที่สุดของรูปภาพ เปนจุด เล็กๆ ที่รวมกันทําใหเกิดภาพขึ้น ภาพหนึ่งจะประกอบดวย Pixel หรือจุดมากมาย ซึ่งแตละภาพที่สรางขึ้นจะ มีความหนาแนนของจุดหรือ Pixel เหลานี้แตกตางกันไป ความหนาแนนของจุดนี้เปนตัวบอกถึงความ ละเอียดของภาพ โดยมีหนวยเปน ppi (Pixel Per Inch) คือ จํานวนจุดตอนิ้ว Pixel มีความสําคัญตอการสราง ภาพของคอมพิวเตอรมาก เพราะทุกสวนของกราฟก เชน จุด เสน แบบลายและสีของภาพนั้นเริ่มจาก Pixel ทั้งสิ้น เมื่อเราขยายภาพจะเห็นเปนภาพจุด โดยปกติแลวภาพที่มีความละเอียดสูงหรือคุณภาพดีควรจะมีคา ความละเอียด 300 X 300 ppi ขึ้นไป ยิ่งคา ppi สูงขึ้นเทาไร ภาพก็จะมีความละเอียดคมชัดขึ้นมากขึ้นเทานั้น ขณะเดียวกันจุดหรือ Pixel แตละจุดก็จะแสดงคุณสมบัติทางสีใหแกภาพดวย โดยแตละจุดจะเปนตัวสรางสี ประกอบกันเปนภาพรวม ซึ่งอาจมีขนาดความเขมและสีแตกตางกันได ทําใหเกิดเปนภาพที่มีสีสันตางๆการ แสดงผลของอุปกรณแสดงผล (Output Devices) ไมวาจะเปนเครื่องพิมพแบบ Dot-matrix หรือแบบ Laser รวมทั้งจอภาพ จะเปนการแสดงผลแบบ Raster Devices นั่นคือ อาศัยการรวมกันของ Pixel ออกมาเปนรูป ภาพบิตแมพ (Bitmap) บิตแมพ (Bitmap) เปนภาพแปรผันตามความละเอียดแบบ (Resolution Dependent) ประกอบขึ้น ดวยจุดสีตางๆ ที่มีจํานวนคงที่ตายตัวตามการสรางภาพที่มีความละเอียดของภาพตางกันไป หากขยายภาพ บิตแมพ ก็จะพบวามีลักษณะเปนตารางเล็กๆซึ่งแตละบิตคือ สวนหนึ่งของขอมูลคอมพิวเตอร เนื่องจากบิต แมพมีคา Pixel จํานวนคงที่จึงทําใหมีขอจํากัดในเรื่องการขยายขนาดภาพ การเปลี่ยนขนาดภาพทําโดยเพิ่ม การประมวลผลภาพดิจิตอลดวยโปรแกรม Mr.Nattaphol Jasungnuen and Poolsak Koseeyaporn,Ph.D Department of Teacher Training in Electrical Engineering

description

การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

Transcript of การประมวลผลภาพดิจิตอลด้วยโปรแกรม...

Page 1: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  1 Digital Image Processing using Microsoft Visual C++ ,KMITNB  การประมวลผลภาพดิจิตอล (Digital Image Processing) เปนกระบวนการท่ีเกี่ยวของกับการแปลงขอมูลภาพใหอยูในรูปแบบขอมูลดิจิตอล (Digital format) ซ่ึงสามารถท่ีจะนําเอาขอมูลนี้จัดการผานกระบวนการตางๆ ดวยโปรแกรมคอมพิวเตอรได ภาพดิจิตอลเปนภาพท่ีประกอบดวยจุดภาพเล็กๆจํานวนมากเรียกวา พิกเซล (pixel) โดยใชตัวเลขแทนคาของระดับสีหรือระดับความสวางของแตละพิกเซล ซ่ึงสามารถปรับแตงเพื่อการแสดงผลภาพตามตองการได ดังนั้นภาพดิจิตอลจึงมีขอดีตรงที่ สามารถนํามาประมวลผลปรับปรุงคุณภาพของขอมูลดวยกระบวนการตางๆดวยคอมพิวเตอรได ลักษณะและความหมายของ Pixel ในโลกของกราฟกท่ีใชในงานคอมพิวเตอร Pixel ถือเปนหนวยยอยท่ีเล็กท่ีสุดของรูปภาพ เปนจุดเล็กๆ ท่ีรวมกันทําใหเกิดภาพข้ึน ภาพหนึ่งจะประกอบดวย Pixel หรือจุดมากมาย ซ่ึงแตละภาพท่ีสรางข้ึนจะมีความหนาแนนของจุดหรือ Pixel เหลานี้แตกตางกันไป ความหนาแนนของจุดนี้เปนตัวบอกถึงความละเอียดของภาพ โดยมีหนวยเปน ppi (Pixel Per Inch) คือ จํานวนจุดตอนิ้ว Pixel มีความสําคัญตอการสรางภาพของคอมพิวเตอรมาก เพราะทุกสวนของกราฟก เชน จุด เสน แบบลายและสีของภาพนั้นเร่ิมจาก Pixel ท้ังส้ิน เม่ือเราขยายภาพจะเห็นเปนภาพจุด โดยปกติแลวภาพท่ีมีความละเอียดสูงหรือคุณภาพดีควรจะมีคาความละเอียด 300 X 300 ppi ข้ึนไป ยิ่งคา ppi สูงข้ึนเทาไร ภาพก็จะมีความละเอียดคมชัดข้ึนมากข้ึนเทานั้น ขณะเดียวกันจุดหรือ Pixel แตละจุดก็จะแสดงคุณสมบัติทางสีใหแกภาพดวย โดยแตละจุดจะเปนตัวสรางสีประกอบกันเปนภาพรวม ซ่ึงอาจมีขนาดความเขมและสีแตกตางกันได ทําใหเกิดเปนภาพท่ีมีสีสันตางๆการแสดงผลของอุปกรณแสดงผล (Output Devices) ไมวาจะเปนเคร่ืองพิมพแบบ Dot-matrix หรือแบบ Laser รวมท้ังจอภาพ จะเปนการแสดงผลแบบ Raster Devices นั่นคือ อาศัยการรวมกันของ Pixel ออกมาเปนรูป ภาพบิตแมพ (Bitmap) บิตแมพ (Bitmap) เปนภาพแปรผันตามความละเอียดแบบ (Resolution Dependent) ประกอบข้ึนดวยจุดสีตางๆ ท่ีมีจํานวนคงท่ีตายตัวตามการสรางภาพที่มีความละเอียดของภาพตางกันไป หากขยายภาพบิตแมพ ก็จะพบวามีลักษณะเปนตารางเล็กๆซ่ึงแตละบิตคือ สวนหน่ึงของขอมูลคอมพิวเตอร เนื่องจากบิตแมพมีคา Pixel จํานวนคงท่ีจึงทําใหมีขอจํากัดในเร่ืองการขยายขนาดภาพ การเปล่ียนขนาดภาพทําโดยเพ่ิมการประมวลผลภาพดิจิตอลดวยโปรแกรม

Mr.Nattaphol  Jasungnuen and Poolsak Koseeyaporn,Ph.DDepartment of Teacher Training in Electrical Engineering

Page 2: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  2 Digital Image Processing using Microsoft Visual C++ ,KMITNB หรือลดจํานวน Pixel จากท่ีมีอยูเดิม เม่ือขยายภาพใหใหญข้ึน ความละเอียดของภาพจึงลดลง และถาเพิ่มคาความละเอียดมากขึ้นก็จะทําใหไฟลมีขนาดใหญและเปลืองเนื้อท่ีหนวยความจํามากข้ึนตามไปดวย ภาพท่ีขยายโตข้ึนจะมองเห็นเปนตารางส่ีเหล่ียมเรียงตอกัน ไฟลภาพแบบ Bitmap ในระบบวินโดวสคือ ไฟลท่ีมีนามสกุล .BMP , .PCX , .TIF, .GIF, .JPG, .MSP, .PCD เปนตน การสรางโปรแกรมประมวลผลภาพ ตัวอยางตอไปนี้แสดงวิธีการเขียนโปรแกรมสําหรับการอานขอมูลภาพบิตแมพ โดยจะใชคลาส CBitmap เพื่ออานไฟลบิตแมพจาก Resource ในการสรางเราจะใชเทมเพลต MFC Applications เพื่อสรางโคดหลักของโปรแกรม ตามข้ันตอนดังนี ้1. เปดโปรแกรม MS Visual C++ สรางโปรแกรมดวย MFC Applications Wizard ดังภาพท่ี 1-1  ภาพท่ี 1-1 เร่ิมตนสราง Project ใหม 2. เลือก Application Type เปนรูปแบบ Single Document และทําการยกเลิก Document /View Architecture Support. ดังภาพ ท่ี 1-2 3. ใน Advance Features Tap ไมจําเปนตองเลือก Support ActiveX Control 4. ใน User Interface Features Tap ไมตองเลือก Docking Toolbar และเลือก Finish

Page 3: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  3 Digital Image Processing using Microsoft Visual C++ ,KMITNB  ภาพท่ี 1-2 กําหนด Application Type -Single document -Document/View architecture support ภาพท่ี 1-3 กําหนด User Interface Features -Main frame style -Toolbar Support ภาพท่ี 1- 4 กําหนด Advance Interface Features -ActiveX controls

Page 4: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  4 Digital Image Processing using Microsoft Visual C++ ,KMITNB  ภาพท่ี 1-5 ผลของโปรแกรมท่ี Class Wizard สรางข้ึนอัตโนมัติ Microsoft Visual C++ ทําการสราง Applications ตามท่ีกําหนดในข้ันตอนตางๆ จะไดผลรันโปรแกรม ImageColor ดังภาพท่ี 1-5 การประมวลผลภาพจะตองนําภาพท่ีตองการเขามาเก็บไวใน Project สามารถทําไดโดยเลือกท่ี Resource และทําการ Add Resource.. ดังภาพท่ี 1-6 ภาพท่ี 1-6 การนําภาพ BITMAP เขาในโปรเจ็ค Image Color Class Wizard สรางโคดใหอัตโนมัติ ผลรันโปรแกรม 2 1 3 4 5 เลือกภาพท่ีตองการ.... เลือก Resource ชนิด Bitmap

Page 5: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  5 Digital Image Processing using Microsoft Visual C++ ,KMITNB  ภาพท่ี 1-7 ผลของภาพ BITMAP ท่ีนําเขาโปรเจ็ค ทําความรูจักคลาส CBitmap กอนทําการเขียนโปรแกรม คลาสท่ีรวมฟงกชันตางๆ สําหรับการจัดการรูปภาพชนดิบิตแมพ อยางเชน การอานไฟลบิตแมพมาเก็บไวในหนวยความจําหรือการเก็บไวใน Object ของ CBitmap เราจะใชความสามารถตางๆของคลาสนี้ใชในการประมวลผลภาพ ฟงกชันและโอเปอรเรเตอรท่ีสําคัญของ CBitmap มีดังนี ้1. CBitmap::CreateCompatibleBitmap 2. CBitmap::LoadBitmap 3. CBitmap::GetBitmap Directory ของ Bitmap  

IDB_BITMAP1 เพ่ิมเขามา ภาพชนิด Bitmap  สรางบิตแมพใหมโครงสรางเดียวกับดซีี ตองกําหนดคาดีซีในหนวยความจํา ขนาดความกวางความสูง โดยปรกติแลวคาดีซีในหนวยความจําจะสอดคลองกับดีซีของจอภาพเสมอ [ดีซี คือ ดีไวซคอนเทกซ(Device Context) ] ใชโหลด Bitmap จาก Resource เขามาเก็บไวในออปเจ็คของ CBitmap ใชเพื่อเอาขอมูลท่ีเก่ียวกับบิตแมพ เชน ความสูง ความกวาง ขอมูลจะเก็บอยูในรูปแบบโครงสราง

Page 6: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  6 Digital Image Processing using Microsoft Visual C++ ,KMITNB  ฟงกชันท่ีสําคัญอีกตัวท่ีเราตองนํามาใชสําหรับเขียนโปรแกรมประมวลผลภาพ เปนตัวกลางสําหรับโอนยายขอมูลจากหนวยความจําไปสูจอภาพ ทําใหเราสามารถมองเห็นผลของภาพตางๆไดนั่นเอง โดยใชฟงกช่ัน BitBlt ของคลาส CDC โดยท่ีกําหนดคาตางๆดังนี้ - x,y คาพิกัดของจอภาพท่ีเราตองการแสดงผลบนหนาจอคอมพิวเตอร โดยในท่ีนี้จะเปนหนวยโลจิคอล(Pixel) 1 หนวย เทากับ 1 Pixel - nWidth,nHeight กําหนดความกวางและความสูงของ Image บนหนาจอคอมพิวเตอร - pSrcDC คือพอยเตอรท่ีช้ีไปยังหนวยความจํา - xSrc,ySrc กําหนดคา x,y ของภาพตนฉบับ ปรกติจะกําหนดคา x ,y เปน 0 - dwRop กําหนดโหมดการทําโอเปอรเรเตอรลอจิก ปรกติใช SRCCOPY คือการ Copy ขอมูลเหมือนตนฉบับท้ังหมด ตัวอยางท่ี 1 โปรแกรมสําหรับโหลดภาพบิตแมพจาก Resource ข้ันตอนตางๆที่กลาวมาในขางตนเปนเพียงการนําขอมูลภาพเก็บใน Resource ของ Project ตอไปจะตองทําการเขียนโปรแกรมเพื่อนําขอมูลภาพเขามาเก็บในหนวยความจําของ Object ของคลาส CBitmap และแสดงผลขอมูลโดยทําการโอนยายหนวยความจําผาน Device Context (CDC) โดยใชฟงกชัน BitBlt เราก็จะไดโปรแกรมแสดงผลภาพแบบ Bitmap ดังภาพท่ี 1-8 ภาพท่ี 1-8 แสดงโปรแกรมแสดงภาพ Bitmap

Page 7: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  7 Digital Image Processing using Microsoft Visual C++ ,KMITNB ขั้นตอนท่ี 1-1 ประกาศตัวแปรชนิด private ช่ือ m_pImage และ m_Size ลงในคลาส CChildView ในไฟล ChildView.h ดังภาพท่ี 1-9 ภาพท่ี 1-9 การเพิ่มตัวแปรลงในคลาส CChildView ขั้นตอนท่ี 1-2 ดับเบิลคล๊ิก ท่ี CChildView(Void) เพื่อเขาไปแกไขโคดโปรแกรมในสวนของ Constructer เพราะเม่ือโปรแกรมเร่ิมทํางาน CChildView(Void) ก็จะถูกเรียก ดังนั้นเราจะทําการโหลดภาพบิตแมพในฟงกชันนี้ โดยเขียนโคดโปรแกรมลงในไฟล ChildView.cpp ดังภาพท่ี 1-10 ภาพท่ี 1-10 การเพิ่มโคดลงใน Constructer ของคลาส CChildView การเพิ่มโคดโปรแกรมสวนนี้จะทําการโหลดขอมูลจาก Resource ท่ีเราทําการเก็บภาพชนิดบิตแมพ ช่ือ IDB_BITMAP1 เอาไว มาเก็บไวใน Object ของ CBitmap คือ m_pImage //ChildView.hclass CChildView : public CWnd {   …………  private:   CBitmap m_pImage;   CSize m_Size;      ………... } 

//ChildView.cpp CChildView::CChildView() { 

m_pImage.LoadBitmap(IDB_BITMAP1); } 

Page 8: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  8 Digital Image Processing using Microsoft Visual C++ ,KMITNB ขั้นตอนท่ี 1- 3 ดับเบิลคล๊ิก ท่ี OnPaint(void) ในคลาส CChildView เพื่อทําการเพ่ิมโคดโปรแกรมใหมีการวาดภาพบิตแมพลงในวินโดวลูกของโปรแกรม ดังภาพที่ 1-11 ภาพท่ี 1-11 การเพิ่มโคดลงใน OnPaint ของคลาส CChildView ทําการคอมไพลไฟลท้ังหมด โดยคล๊ิกท่ีเมน ูBuild > Build ImageColor และทําการ Run โปรแกรม กด Ctrl+F5 จะเหน็ภาพบิตแมพแสดงในโปรแกรมท่ีสรางข้ึนดังภาพท่ี 1-12 ภาพท่ี 1-12 ผลของโปรแกรมแสดงภาพบิตแมพดวย Visual C++ //ChildView.cpp void CChildView::OnPaint()  {   CPaintDC dc(this); // device context for painting    CDC memDC;   memDC.CreateCompatibleDC(&dc);   memDC.SelectObject(&m_pImage);   dc.TextOut(20,10,"The original image");   dc.BitBlt(20,30,m_Size.cx,m_Size.cy,&memDC,0,0,SRCCOPY);    // Do not call CWnd::OnPaint() for painting messages } 

Page 9: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  9 Digital Image Processing using Microsoft Visual C++ ,KMITNB  ตัวอยางท่ี 2 โปรแกรมแยกองคประกอบของสี ตัวอยางตอไปนี้เราจะทําการสรางโปรแกรมประมวลผลภาพสําหรับแสดงองคประกอบของสีภาพบิตแมพ โดยเราจะพัฒนาโปรแกรมตอจากเดิมท่ีไดกลาวมาขางตน กําหนดใหโปรแกรมสามารถแสดงองค ประกอบของสีแดง สีเขียว สีน้ําเงิน และ ภาพขาวดํา ใหทําการแกไขโคดโปรแกรมดังตอไปนี ้ ขั้นตอนท่ี 2-1 เพิ่มตัวแปรชนิด private ลงในคลาส CChildView ดังภาพท่ี 2-1 ตัวแปร **f คือ ตัวแปรพอยเตอร สําหรับช้ีคาในพอยเตอรของ *f โดยเราจะกําหนดใหตัวแปรเปนแบบ Dynamic Variable ใหมีขนาดไมเกินคา N ใชสําหรับเปนอาเรยสองมิติเก็บคา Pixel ของภาพบิตแมพ , ตัวแปร sImage ใชสําหรับเก็บขนาดของภาพสวนตางๆที่เราตองการนํามาประมวลผล , ตัวแปร Home ใชสําหรับเก็บคาเร่ิมตนของตําแหนงภาพท่ีเราตองการประมวลผลภาพ ภาพท่ี 2-1 การเพิ่มตัวแปรในคลาส CChildView ขั้นตอนท่ี 2-2 กําหนดคาตางๆท่ีจําเปนตอการประมวลผลภาพ ใหทําการสราง Dynamic Variable ของตัวแปร **f โดยกําหนดใหมีคาเทากับ 500 หรือเทากับ N นั่นเอง เราจะใชเปนตัวแปรสําหรับรับคาพิกเซลของภาพ และกําหนดคาเร่ิมตนใหกับ sImage และ Home ดังภาพท่ี 2-2 //ChildView.h#define N 500 class CChildView : public CWnd {      …………........... private:   CBitmap m_pImage;   int **f;   CSize sImage;   CPoint Home;      ……………… } 

Page 10: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  10 Digital Image Processing using Microsoft Visual C++ ,KMITNB  ภาพท่ี 2-2 กําหนดคาใหกับ Constructers ของคลาส CChildView ขั้นตอนท่ี 2-3 ทําการเพ่ิมโคดโปรแกรมลงในฟงกชัน OnPaint(void) ของคลาส CChildView โดยทําการกําหนด memDC เปน Object ของ CDC (Device Context) สําหรับเปน ดีซีหนวยความจํา และกําหนดใหสรางดีซีหนวยควมจําท่ีสอดคลองกับดีซีจอภาพโดยใชฟงกชัน CreateCompatibleDC และทําการโอนยายขอมูลบิตแมพมาเก็บไวในดีซีหนวยความจํา โดยใชฟงกชัน SelectObject สุดทายจะใช BitBlt นําขอมูลจากดีซีหนวยความจําออกแสดงทางจอภาพของคอมพิวเตอร ตามขนาดเดิมของภาพบิตแมพจาก Resource โคดโปรแกรมกําหนดไดดังภาพท่ี 2-3 ภาพท่ี 2-3 เพิม่โคดในฟงกชัน OnPaint(void) //ChildView.cppCChildView::CChildView() {   f = new int *[N+1];   for(int i=0;i<=N;i++)   {     f[i] = new int [N+1];   }   Home = CPoint(10,30);   sImage = CSize(200,100);   m_pImage.LoadBitmap(IDB_BITMAP1); } 

//ChildView.cppVoid  CChildView::OnPaint()  {   CPaintDC dc(this); // device context for painting   CDC memDC;   memDC.CreateCompatibleDC(&dc);   memDC.SelectObject(&m_pImage);   dc.TextOut(10,10,"The original image");   dc.BitBlt(Home.x,Home.y,400,320,&memDC,0,0,SRCCOPY);    CWinApp* app = AfxGetApp();   if(app) 

app‐>m_pMainWnd‐>SetWindowPos(NULL, 50, 50, 700,                                                 700, SWP_SHOWWINDOW ); 

1

Page 11: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  11 Digital Image Processing using Microsoft Visual C++ ,KMITNB ขั้นตอนท่ี 2-4 กําหนด Window Message ช่ือ WM_LBUTTONDOWN ของคลาส CChildView ทําไดโดย เลือกท่ี Tap Class Wizard แลวคลิกขวาเลือก Properties เลือก Message WM_LBUTTONDOWN > OnLButtonDown แลวแทรกโคดดังภาพท่ี 2-4 ภาพท่ี 2-4 เพิม่โคดลงในฟงกชัน OnLButtonDown //ChildView.cpp void CChildView::OnLButtonDown(UINT nFlags, CPoint point) {   CClientDC dc(this);    int r,g,b,bw;      dc.TextOut(440,Home.y‐20,"Extract from the original image");   dc.TextOut(440,180,"Gray scale by setting r=g=b");   dc.TextOut(10,380,"Red scale by setting g=b=0");   dc.TextOut(220,380,"Green scale by setting r=b=0");   dc.TextOut(430,380,"Blue scale by setting r=g=0");    for(int j=0;j<= sImage.cy;j++)       for(int i=0;i<= sImage.cx ;i++) 

{     f[i][j] = dc.GetPixel(Home.x+i+80,Home.y+j+100);     dc.SetPixel(440+i,Home.y+j,f[i][j]);            r = f[i][j]>>16;     dc.SetPixel(10+i,400+j,r);      g = r<<8;     dc.SetPixel(220+i,400+j,g);      b = g<<8;     dc.SetPixel(430+i,400+j,b);      bw = r+g+b;     dc.SetPixel(440+i,200+j, bw); 

}            

dc.TextOut(10,510,"ภาพตนแบบเฉพาะสวนสีแดง ");   for (int j=0;j<=sImage.cy;j++)           for (int i=0;i<=sImage.cx;i++)          {     f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);       r = f[i][j] >> 16;     dc.SetPixel(10+i,530+j,RGB(r,0,0));           }    dc.TextOut(220,510,"ภาพตนแบบเฉพาะสวนสีเขียว ");   for (int j=0;j<=sImage.cy;j++)          for (int i=0;i<=sImage.cx;i++)         {                

f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);     g = (f[i][j] >> 8);     dc.SetPixel(220+i,530+j,RGB(0,g,0)); 

}   dc.TextOut(430,510,"ภาพตนแบบเฉพาะสวนน้ําเงิน "); 

for (int j=0;j<=sImage.cy;j++)          for (int i=0;i<=sImage.cx;i++) 

{     f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);     b = (f[i][j]);     dc.SetPixel(430+i,530+j,RGB(0,0,b)); 

}    CWnd::OnLButtonDown(nFlags, point); } 

Page 12: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  12 Digital Image Processing using Microsoft Visual C++ ,KMITNB เม่ือทําการเพ่ิมโคดโปรแกรมตางๆสมบูรณแลวทําการ Build > Build ColorImage แลวทําการรันโปรแกรม Ctrl+F5 ผลของโปรแกรมดงัภาพท่ี 2-5 ภาพท่ี 2-5 ผลของโปรแกรม Color Image Processing dc.TextOut(10,10,"The original image");dc.BitBlt(Home.x,Home.y,400,320,&memDC,0,0,SRCCOPY); 

dc.SetPixel(440+i,Home.y+j,f[i][j]); 

dc.SetPixel(440+i,200+j, bw); 

1

4  5  6

7  8  9

Page 13: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  13 Digital Image Processing using Microsoft Visual C++ ,KMITNB ตัวอยางโปรแกรม ColorImage  // ChildView.h : interface of the CChildView class #pragma once  // CChildView window #define N 500   class CChildView : public CWnd { // Construction public:   CChildView(); private:   CBitmap m_pImage;   int **f;   CSize sImage;   CPoint Home; public: // Overrides   protected:   virtual BOOL PreCreateWindow(CREATESTRUCT& cs); // Implementation public:   virtual ~CChildView();  // Generated message map functions protected:   afx_msg void OnPaint();   DECLARE_MESSAGE_MAP() public:   afx_msg void OnLButtonDown(UINT nFlags, CPoint point); };  // ChildView.cpp : implementation of the CChildView class #include "stdafx.h" #include "ImageColor.h" #include "ChildView.h" #include ".\childview.h"  #ifdef _DEBUG #define new DEBUG_NEW #endif  // CChildView CChildView::CChildView() {   f = new int *[N+1];   for(int i=0;i<=N;i++)   {     f[i] = new int [N+1];   }   Home = CPoint(10,30);   sImage = CSize(200,100);   m_pImage.LoadBitmap(IDB_BITMAP1); }  

Page 14: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  14 Digital Image Processing using Microsoft Visual C++ ,KMITNB 

CChildView::~CChildView() {   for(int i=0;i<=N;i++)     delete f[i];   delete f;  }  BEGIN_MESSAGE_MAP(CChildView, CWnd)   ON_WM_PAINT()   ON_WM_LBUTTONDOWN() END_MESSAGE_MAP()  // CChildView message handlers  BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)  {   if (!CWnd::PreCreateWindow(cs))     return FALSE;    cs.dwExStyle |= WS_EX_CLIENTEDGE;   cs.style &= ~WS_BORDER;   cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,       ::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);    return TRUE; }  void CChildView::OnPaint()  {   CPaintDC dc(this); // device context for painting    CDC memDC;   memDC.CreateCompatibleDC(&dc);   memDC.SelectObject(&m_pImage);   dc.TextOut(10,10,"The original image");   dc.BitBlt(Home.x,Home.y,400,320,&memDC,0,0,SRCCOPY);    CWinApp* app = AfxGetApp();   if(app)     app‐>m_pMainWnd‐>SetWindowPos(NULL, 50, 50, 700, 700, SWP_SHOWWINDOW );   // Do not call CWnd::OnPaint() for painting messages }  void CChildView::OnLButtonDown(UINT nFlags, CPoint point) {   CClientDC dc(this);      int r,g,b,bw;      dc.TextOut(440,Home.y‐20,"Extract from the original image");   dc.TextOut(440,180,"Gray scale by setting r=g=b");   dc.TextOut(10,380,"Red scale by setting g=b=0");   dc.TextOut(220,380,"Green scale by setting r=b=0");   dc.TextOut(430,380,"Blue scale by setting r=g=0");      

Page 15: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  15 Digital Image Processing using Microsoft Visual C++ ,KMITNB 

  for(int j=0;j<= sImage.cy;j++)     for(int i=0;i<= sImage.cx ;i++)     {       f[i][j] = dc.GetPixel(Home.x+i+80,Home.y+j+100);       dc.SetPixel(440+i,Home.y+j,f[i][j]);              r = f[i][j]>>16;       dc.SetPixel(10+i,400+j,r);        g = r<<8;       dc.SetPixel(220+i,400+j,g);        b = g<<8;       dc.SetPixel(430+i,400+j,b);        bw = r+g+b;       dc.SetPixel(440+i,200+j, bw);      }      dc.TextOut(10,510,"ภาพตนแบบเฉพาะสวนสีแดง ");     for (int j=0;j<=sImage.cy;j++)       for (int i=0;i<=sImage.cx;i++)       {         f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);           r = f[i][j] >> 16;         dc.SetPixel(10+i,530+j,RGB(r,0,0));       }      dc.TextOut(220,510,"ภาพตนแบบเฉพาะสวนสีเขียว");     for (int j=0;j<=sImage.cy;j++)       for (int i=0;i<=sImage.cx;i++)       {         f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);         g = (f[i][j] >> 8);         dc.SetPixel(220+i,530+j,RGB(0,g,0));       }          dc.TextOut(430,510,"ภาพตนแบบเฉพาะสวนสีนํ้าเงิน ");     for (int j=0;j<=sImage.cy;j++)       for (int i=0;i<=sImage.cx;i++)       {         f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);         b = (f[i][j]);         dc.SetPixel(430+i,530+j,RGB(0,0,b));       }    CWnd::OnLButtonDown(nFlags, point); } 

Page 16: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  16 Digital Image Processing using Microsoft Visual C++ ,KMITNB ตัวอยางท่ี 3 โปรแกรมหาขอบภาพ (Edge Detection) การหาขอบภาพ (Edge Detection) เปนการหาเสนรอบวัตถุท่ีอยูในภาพ เม่ือทราบเสนรอบวัตถุ เราจะสามารถคํานวณหาพืน้ท่ี (ขนาด) หรือรูจําชนิดของวัตถุนั้นได อยางไรก็ตามการหาขอบภาพท่ีถูกตองสมบูรณไมใชเปนเร่ืองท่ีงาย โดยเฉพาะอยางยิ่งการหาขอบของภาพท่ีมีคุณภาพตํ่า มีความแตกตางระหวางพื้นหนากับพืน้หลังนอย หรือมีความสวางไมสมํ่าเสมอท่ัวภาพ ขอบภาพเกิดจากความแตกตางของความเขมแสงจากจดุหนึ่งไปยังอีกจุดหนึ่ง หากความแตกตางนี้มีคามากขอบภาพก็จะเหน็ไดชัด ถาความแตกตางมีคานอยขอบภาพก็จะไมชัดเจน ในบทนีจ้ะกลาวถึงเทคนิคเบ้ืองตนในการหาขอบภาพ การสรางโปรแกรมสําหรับการตรวจหาขอบภาพดวย Visual C++ ใหเราทําการสรางโปรเจ็คใหมช่ือEdgeDetect โดยมีข้ันตอนการสรางเชนเดียวกับหวัขอเร่ือง การสรางโปรแกรมประมวลผลภาพในหนาท่ี 2 แลวทําการ Add Resource ขอมูลภาพบิตแมพใหเรียบรอย ก็จะไดโปรเจ็คใหมดังภาพท่ี 3-1 ภาพท่ี 3-1 สรางโปรเจ็คใหมแบบ Single Document

Page 17: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  17 Digital Image Processing using Microsoft Visual C++ ,KMITNB ขั้นตอนท่ี 1 เพิ่มตัวแปรชนิด private ลงในคลาส ChildView และกําหนด Preprocessor ของ N ไวภายนอกคลาสมีคาเทากับ 200 ตัวแปรท่ีเพิม่เขามาคือ threshold ใชเปนตัวแปรสําหรับการคํานวณหาขอบภาพ การเพิ่มตัวแปรดังภาพท่ี 3-2 ภาพท่ี 3-2 การเพิ่มตัวแปรชนิด private ลงในคลาส ChildView ขั้นตอนท่ี 2 เพิ่มโคดโปรแกรมสําหรับ Constructers ของคลาส CChildView เม่ือโปรแกรมเร่ิมทํางานในสวนของ Constructers จะเร่ิมทํางาน ดังนั้นจะกาํหนดให Dynamic array ของ **f ใหมีขนาดเทากับ N คือ 200 กําหนดคา Home สําหรับเปนจุดเร่ิมของขอบภาพท่ีตองการประมวลผล และกําหนดคาขนาดของภาพท่ี ตองการประมวลผล โคดโปรแกรมดังภาพท่ี 3-3 ภาพท่ี 3-3 เพิม่โคดโปรแกรม Constructers ของคลาส CChildView // CChildView .h#define N 200 class CChildView : public CWnd {   private:   CBitmap bmp;   CPoint Home;   CSize sImage;   double threshold;   int **f;     ………. } 

CChildView::CChildView(){   f=new int *[N+1];   for (int i=0;i<=N;i++)     f[i]=new int [N+1];    Home=CPoint(10,50);   sImage=CSize(200,100);   threshold=0;   bmp.LoadBitmap(IDB_BITMAP1); } 

Page 18: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  18 Digital Image Processing using Microsoft Visual C++ ,KMITNB ขั้นตอนท่ี 3 ทําการเพ่ิมโคดโปรแกรมลงในฟงกชัน OnPaint(void) ของคลาส CChildView โดยทําการกําหนด memDC เปน Object ของ CDC (Device Context) สําหรับเปน ดีซีหนวยความจํา และกําหนดใหสรางดีซีหนวยควมจําท่ีสอดคลองกับดีซีจอภาพโดยใชฟงกชัน CreateCompatibleDC และทําการโอนยายขอมูลบิตแมพมาเก็บไวในดีซีหนวยความจํา โดยใชฟงกชัน SelectObject สุดทายจะใช BitBlt นําขอมูลจากดีซีหนวยความจําออกแสดงทางจอภาพของคอมพิวเตอร ตามขนาดเดิมของ BITMAP จาก Resource โคดโปรแกรมกําหนดไดดังภาพท่ี 3-4 ภาพท่ี 3-4 OnPaint() ขั้นตอนท่ี 4 กําหนด Window Message ช่ือ WM_LBUTTONDOWN ของคลาส CChildView ทําไดโดย เลือกท่ี Tap Class Wizard แลวคลิกขวาเลือก Properties เลือก Message WM_LBUTTONDOWN > OnLButtonDown แลวแทรกโคดดังภาพท่ี 3-5 ภาพท่ี 3-5 WM_LBUTTONDOWN ของคลาส CChildView void CChildView::OnPaint() {   CPaintDC dc(this); // device context for painting   CDC memDC;   memDC.CreateCompatibleDC(&dc);   memDC.SelectObject(&bmp);   dc.BitBlt(Home.x,Home.y,400,300,&memDC,0,0,SRCCOPY);   for (int j=0;j<=sImage.cy;j++)              for (int i=0;i<=sImage.cx;i++)             {       

f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);     threshold += (double)f[i][j];              }   threshold /= (double)(N*N);    CWinApp* app = AfxGetApp();   if(app)     app‐>m_pMainWnd‐>SetWindowPos(NULL, 50, 50,  

700, 500, SWP_SHOWWINDOW ); } 

void CChildView::OnLButtonDown(UINT nFlags, CPoint point) {     // // TODO: Add your message handler code here          CWnd::OnLButtonDown(nFlags, point); } 

1

Page 19: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  19 Digital Image Processing using Microsoft Visual C++ ,KMITNB ทําการเพ่ิมโปรแกรมในสวนของการหาขอบภาพ ดังภาพที่ 3-6 ภาพท่ี 3-6 โปรแกรมสวนของการหาขอบภาพ void CChildView::OnLButtonDown(UINT nFlags, CPoint point){   // TODO: Add your message handler code here and/or call default   CClientDC dc(this);    int Sy,Sx,S,L;   dc.TextOut(440,Home.y‐40,"Sobel Mtd");   dc.TextOut(440,Home.y‐10+sImage.cy,"Laplacian 1 Mtd");   dc.TextOut(440,Home.y+20+2*sImage.cy,"Laplacian 2 Mtd");   for (int j=1;j<=sImage.cy‐1;j++)   for (int i=1;i<=sImage.cx‐1;i++)   {     // Sobel masking for detecting the edges     Sy  =  f[i‐1][j+1] ‐f[i+1][j+1] +2*f[i‐1][j] // horizontal kernel               ‐2*f[i+1][j] +f[i‐1][j‐1] ‐f[i+1][j‐1];      Sx = ‐f[i‐1][j+1] ‐2*f[i][j+1] ‐f[i+1][j+1] // vertical kernel               +f[i‐1][j‐1] +2*f[i][j‐1] +f[i+1][j‐1];          S = abs(Sy)+abs(Sx);      if (S<=(int)threshold)       S=RGB(0,0,0);     else       S=RGB(255,255,255);       dc.SetPixel(440+i,Home.y‐25+j,S);       // Laplacian masking for detecting the edges       L =   ‐f[i][j+1]‐f[i‐1][j]              +4*f[i][j]‐f[i+1][j]‐f[i][j‐1]; // kernel 1       L = abs(L);      if (L<=(int)threshold)       L= RGB(0,0,0);     else       L= RGB(255,255,255);       dc.SetPixel(440+i,Home.y+5+sImage.cy+j,L);       L =  ‐f[i‐1][j+1] ‐f[i][j+1] ‐f[i+1][j+1] // kernel 2               ‐f[i‐1][j] +8*f[i][j] ‐f[i+1][j]               ‐f[i‐1][j‐1] ‐f[i][j‐1] ‐f[i+1][j‐1];       L= abs(L);      if (L<=(int)threshold)       L=RGB(0,0,0);     else       L=RGB(255,255,255);       dc.SetPixel(440+i,Home.y+35+2*sImage.cy+j,L);   }    CWnd::OnLButtonDown(nFlags, point); } 

2

3

4

1 2 10 0 01 2 1

 

 

1 0 12 0 21 0 1

 

Sobel Filtering Method  

S =   

Laplacian Filtering Method  Kernel 1: 

L = 0 0 01 2 10 0 0

+0 1 00 2 00 1 0

 

    =0 1 01 4 10 1 0

 

Laplacian Filtering Method  Kernel 2: 

L = 1 1 11 8 11 1 1

 

Page 20: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  20 Digital Image Processing using Microsoft Visual C++ ,KMITNB เม่ือทําการแกไขโปรแกรมเรียบรอยแลว ทําการ Build > Build EdgeDetect และรันโปรแกรม EdgeDetect ไดผลของโปรแกรมดังภาพท่ี 3-7 ภาพท่ี 3-7 ผลของโปรแกรมตรวจหาขอบภาพ ตัวอยางโปรแกรม EdgeDetect // ChildView.h : interface of the CChildView class #pragma once #define N 200 class CChildView : public CWnd { // Construction public:   CChildView(); // Operations private:   CBitmap bmp;   CPoint Home;   CSize sImage;   double threshold;   int **f;  // Overrides protected:    virtual BOOL PreCreateWindow(CREATESTRUCT& cs); // Implementation public: 

virtual ~CChildView();   // Generated message map functions protected:   afx_msg void OnPaint();   DECLARE_MESSAGE_MAP() public:   afx_msg void OnLButtonDown(UINT nFlags, CPoint point); };  1 2

3

4

Page 21: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  21 Digital Image Processing using Microsoft Visual C++ ,KMITNB 

// ChildView.cpp : implementation of the CChildView class #include "stdafx.h" #include "EdgeDetect.h" #include "ChildView.h" #include ".\childview.h"  #ifdef _DEBUG #define new DEBUG_NEW #endif  // CChildView CChildView::CChildView() {   f=new int *[N+1];   for (int i=0;i<=N;i++)     f[i]=new int [N+1];    Home=CPoint(10,50);   sImage=CSize(200,100);   threshold=0;   bmp.LoadBitmap(IDB_BITMAP1); }  CChildView::~CChildView() {   for(int i=0;i<=N;i++)     delete f[i];   delete f;   }  BEGIN_MESSAGE_MAP(CChildView, CWnd)   ON_WM_PAINT()   ON_WM_LBUTTONDOWN() END_MESSAGE_MAP()  // CChildView message handlers BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)  {   if (!CWnd::PreCreateWindow(cs))     return FALSE;   cs.dwExStyle |= WS_EX_CLIENTEDGE;   cs.style &= ~WS_BORDER;   cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,      ::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);   return TRUE; }  void CChildView::OnPaint()  {   CPaintDC dc(this); // device context for painting   CDC memDC;   memDC.CreateCompatibleDC(&dc);   memDC.SelectObject(&bmp);   dc.BitBlt(Home.x,Home.y,400,300,&memDC,0,0,SRCCOPY);   for (int j=0;j<=sImage.cy;j++)     for (int i=0;i<=sImage.cx;i++)     {       f[i][j]=dc.GetPixel(Home.x+i+50,Home.y+j+100);       threshold += (double)f[i][j];     }   threshold /= (double)(N*N);   CWinApp* app = AfxGetApp();   if(app)     app‐>m_pMainWnd‐>SetWindowPos(NULL, 50, 50, 700, 500, SWP_SHOWWINDOW );   // Do not call CWnd::OnPaint() for painting messages } 

Page 22: การประมวลผลภาพดิจิตอลด้วยโปรแกรม Visual C++ EP0 บทนำและโค้ด

  22 Digital Image Processing using Microsoft Visual C++ ,KMITNB 

void CChildView::OnLButtonDown(UINT nFlags, CPoint point) {   // TODO: Add your message handler code here and/or call default   CClientDC dc(this);    int Sy,Sx,S,L;   dc.TextOut(440,Home.y‐40,"Sobel Mtd");   dc.TextOut(440,Home.y‐10+sImage.cy,"Laplacian 1 Mtd");   dc.TextOut(440,Home.y+20+2*sImage.cy,"Laplacian 2 Mtd");    for (int j=1;j<=sImage.cy‐1;j++)   for (int i=1;i<=sImage.cx‐1;i++)   {     // Sobel masking for detecting the edges     Sy=   f[i‐1][j+1]‐f[i+1][j+1]+2*f[i‐1][j] // horizontal kernel              ‐2*f[i+1][j]+f[i‐1][j‐1]‐f[i+1][j‐1];     Sx=  ‐f[i‐1][j+1]‐2*f[i][j+1]‐f[i+1][j+1] // vertical kernel              +f[i‐1][j‐1]+2*f[i][j‐1]+f[i+1][j‐1];          S= abs(Sy) + abs(Sx);      if (S<=(int)threshold)       S=RGB(0,0,0);     else       S= RGB(255,255,255);       dc.SetPixel(440+i,Home.y‐25+j,S);       // Laplacian masking for detecting the edges       L=‐f[i][j+1]‐f[i‐1][j]       +4*f[i][j]‐f[i+1][j]‐f[i][j‐1]; // kernel 1       L=abs(L);      if (L<=(int)threshold)       L=RGB(0,0,0);     else       L=RGB(255,255,255);       dc.SetPixel(440+i,Home.y+5+sImage.cy+j,L);       L=‐f[i‐1][j+1]‐f[i][j+1]‐f[i+1][j+1] // kernel 2       ‐f[i‐1][j]+8*f[i][j]‐f[i+1][j]       ‐f[i‐1][j‐1]‐f[i][j‐1]‐f[i+1][j‐1];       L=abs(L);      if (L<=(int)threshold)       L=RGB(0,0,0);     else       L=RGB(255,255,255);       dc.SetPixel(440+i,Home.y+35+2*sImage.cy+j,L);   }   CWnd::OnLButtonDown(nFlags, point); }  References: - Numerical Simulations and Case Studies Using Visual C++.NET