Showing posts with label image morphology. Show all posts
Showing posts with label image morphology. Show all posts

Wednesday, April 14, 2010

Learning OpenCV: Image Morphology (cont)

มาต่อกันที่ morphology กันอีกที ยังมี morphology พื้นฐานอีกหลายตัวที่สามารถใช้ได้กับ gray scale หรือ color image (ยังไม่เข้าใจว่าทำไม dilation, erosion ใช้ไม่ไ้ด้) ใน OpenCV ใช้คำสั่งดังนี้

void cvMorphologyEx(
    const CvArr*         src,
    CvArr*                  dst,
    CvArr*                  temp,
    IplConvKernel*      element,
    int                        operation,
    int                        iteration = 1
);

มีสิ่งที่เพิ่มมาจาก cvErode, cvDiate สองตัวคือ temp ใช้สำหรับเก็บค่า temp ของการคำนวณซึ่งอาจจะใช้หรือไม่ใช้ก็ได้ขึ้นอยู่กับ operation  ลองดูใน document (ละเอียดกว่านี้เดี๋ยวจะกลายเป็น document ย่อมๆ ไป) ส่วน operation จะมีค่าได้ดังนี้ CV_MOP_OPEN, CV_MOP_CLOSE, CV_MOP_GRADIENT, CV_MOP_TOPHAT, CV_MOP_BLACKHAT


Opening
นิยามของ opening ง่ายๆ คือเอา image มา erode แล้ว ค่อย dilate ใช้ในการลบ noise (เพราะว่า noise หายไปตอน erode แต่ขนาดของวัตถุเล็กลงก็เอาคืนด้วยการ dilate) ใช้ในการ ลบขอบที่ยื่นๆ ของวัตถุด้วย

Closing
ตรงข้างกับ opening คือการนำ image มา dilate แล้ว ค่อย erode ใช้ในการลบ small holes (หายไปตอบ dilate แล้วลดขนาดวัตถุที่บวมขึ้นมาด้วย erode) สามารถใช้ในการ เชื่อมวัตถุที่แยกจากกัน(เพราะ noise)

ทั้ง opening และ closing จะเหมือน erosion กับ dilation ต่างกันที่ opening กับ closing จะรักษาขนาดวัตถุไว้

Gradient
คือการนำภาพที่ dilate(บวม) มาลบด้วยภาพที่ erode(หด) ผลลัพธ์ที่ได้ก็จะเป็นขอบของภาพใช้ในการ detect edge

Top Hat, Black Hat
top hat ใช้ในการ isolate patch ที่สว่างกว่ารอบๆ ข้าง ในขณะที่ balck hat ใช้ isolate patch ที่มืดกว่ารอบๆ ข้าง โดย top hat คือ ภาพต้นฉบับ มาลบด้วย open(noise หาย ขอบยื่นๆ หาย ส่วน) ภาพที่ได้คือส่วนที่เป็นขอบยื่นๆ ที่หาย กับ noise ที่หายไปนั่นเอง ซึ่ง noise ในที่นี้คือพื่นที่สว่างถูก isolate(ไม่มีวัตถุ background สีขาว วัตถุสีดำ) ส่วน black hat ก็คือการนำ close(ภาพที่ holes หายไป และวัตถุ connected กับแล้ว) ลบด้วย ภาพต้นฉบับ ทำให้กลุ่ม patch ที่มืด(dark holes) ถูกแยกออกมา

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);