Wednesday, April 14, 2010

Learning OpenCV: Image Morphology

มาถึงการ morph image กันแล้ว.(แปลเป็นภาษาไทยว่าอะไรดีหว่า)  เขาว่านิยมสำหรับการกำจัด noise แยกวัตถุ ต่างๆ ออกจากกัน หรือเชื่อมวัตถุต่างๆ เข้าด้วยกัน ใช้หา bumps(อะไรหว่า หลุมบ่อเหรอ) กับ holes

ตอนนี้มาเริ่มกันที่ตัวพื้นฐานเลยดีกว่า

พื้นฐานในการ morph เหล่านี้ส่วนใหญ่อ้างถึงภาพแบบ binary คือมีสองสี แต่สามารถอธิบายไปกับภาพที่เป็น intensity ได้ แต่อาจจะไม่ตรงนัก

Dilation
เดาจากชื่อได้ว่าเป็นการทำให้ image ใหญ่ขึ้นจริงๆ(จริงๆคือวัตถุใน image) คือการ นำ kernel (คือ shape ใดๆ มักจะเป็นวงกลมหรือสี่เหลี่ยม) โดยมีจุด anchor point (มักจะอยู่ตรงกลาง kernel) วางทับไปทั่ว image ภาพที่อยู่ภายใต้ image จะทำการหาค่า maximun แล้ว pixel ที่ตรงกับ จะถูกแทนที่ด้วยค่า maximum นั้น ผลลัพธ์คือรูปที่ได้จะมีขนาดใหญ่ขึ้น (เพราะพื้นที่ส่วนนอกวัตถุไม่ไกลมากเจอ max operator เข้าไป ทำให้พื้นที่ใำกล้ๆ วัตถุที่ว่างเปล่า (ค่า 0) กลายเป็นวัตถุ (ค่า 1) ไป)  และ ความเว้า จะหายไป(ถูกถมด้วยพื้นที่รอบๆ) และยังมีผลทำให้วัตถุใหญ่ๆ ที่อยู่ใกล้ๆ กันเชื่อมกัน(นัยว่ามันขาดไปเพราะเกิด noise)

Erosion
ก็ตรงข้ามกับ Dilation ที่ใช้ max operator ตัว Erosion จะใช้ min operator ทำให้พื้นที่บริเวณใกล้ๆ ขอบของวัตถุถูกกำจัดไปด้วย min operator ทำให้บริเวณผิวของวัตถุหายไป ตรงกับความหมายของ erosion ที่แปลว่ากัดกร่อน ผลที่ได้ วัตถุจะมีขนาดเล็กลง,  และส่วนที่ยื่นออกมาของวัตถุก็จะหายไป (กลับกันกับ Dilation)
และมีผลทำให้จุดด่างหรือวัตถุเล็กๆ ที่อยู่โดดๆ (น่าจะเป็น noise ชนิดหนึ่ง) หายไป

ใน OpenCV มีคำสั่งสำหรับ Dilation และ Erosion คือ
void cvErode(
    IplImage*             src,
    IplImage*             dst,
    IplConvKernel*    B = NULL,
    int                         iterations = 1
);

void cvDilate(
    IplImage*             src,
    IplImage*             dst,
    IplConvKernel*    B = NULL,
    int                         iterations = 1
);


ค่า B ถ้าไม่กำหนดจะเป็นสี่เหลี่ยมขนาด 3x3 เราสามารถกำหนด kernel ได้ด้วยคำสั่ง
IplConvKernel* cvCreateStructuringElementEx(
    int      cols,
    int      rows,
    int      anchor_x,
    int      anchor_y,
    int      shape,
    int*    values=NULL
);

cols, rows คือขนาดของสี่เหลี่ยมที่กำหนด kernel anchor_x, anchor_y คือตำแหน่ง anchor pixel ใน kernel shape จะเป็นค่า CV_SHAPE_RECT, CV_SHAPE_CROSS, CV_SHAPE_ELLIPSE, CV_CUSTOM คงเดาได้จากชื่อ ในส่วนของ CV_CUSTOM จะกำหนดรูปร่างของ kernel อีกที่ด้วย ตัวแปร values ที่แทน array ของ mask สำหรับสี่เหลี่ยมขนาด cols * rows

เสร็จแล้วก็อย่าลืม release ด้วยคำสั่ง

void cvReleaseStructuringElement(IplConvKernel** element);

No comments:

Post a Comment