Thursday, April 15, 2010

Learning OpenCV: more about image segmentation in OpenCV

ต่อจากเรื่อง image morphology ยังมีเรื่องค้างอีกนิดหน่อยเีกี่ยวกับการ segment ข้อมูล
เรื่องการคือการทำ Flood Fill แนวคิดของ flood fill นี้อาจจะเคยเห็นกันมาแล้วบ้างจากโปรแกรมแต่งรูปต่างๆ
คือจะมีเลือกจุดในรูปภาพ (seed point) แล้วทั้ง seed point และจุดรอบข้างที่มีสีเหมือนกัน(หรือใกล้เคียงกันตามกำหนด) จะถูกแทนที่ด้วยสีที่กำหนด และประเด็นคืออะไร จริงๆ แล้วประเด็นสำคัญคือ ผลที่ได้จาก flood ่่fill operation นั้นจะเป็นพื้นที่ๆ ต่อเนื่องกันพื้นที่หนึ่ง เรียกได้ว่าเป็นการ segment ด้วยสี ลองดูการประกาศฟังก์ชัน


void cvFloodFill(
    IplImage* img,
    CvPoint seedPoint,
    CvScalar newVal,
    CvScalar loDiff = cvScalarAll(0),
    CvScalar upDiff = cvScalarAll(0),
    CvConnectedComp* comp = NULL,
    int flags = 4,
    CvArr* mask = NULL
);

พารามิเตอร์จะเป็น img รูปภาพที่จะ fill, seedPoint คือตำแหน่ง seed point  newVal คือสีที่จะ fill loDiff กับ upDiff คือผลต่างค่าที่จะยอมรับได้ที่จะต้องแทนที่สี(หรือว่าเป็นพื้้นที่เดียวกันนั่นเอง) ปกติผลต่างนัั้นจะคำนวณระหว่าง pixel ที่ติดกันยกเว้นถ้ามี flag CV_FLOODFILL_FIXED_RANGE จะคำนวณผลต่างจาก seed point เท่านั้น

CvConnectedComp จะเก็บข้อมูลสถิติเกี่ยวกับพื้นที่ๆ ถูก fill จะยกยอดไปอธิบายในเรื่อง Image Pyramids


mask ถ้ากำหนดจะต้องมีขนาด 1 channel และขนาดกว้างและยาวกว่า img (เพื่อการคำนวณ filter ภายใน) โดย pixel (x+1,y+1) ใน mask จะ map กับ x,y ใน img โดยการทำงาน Flood Fill จะ fill img เฉพาะในส่วนที่ mask ตรงตำแหน่งเป็น 0 
ผลการ Flood Fill สามารถ กำหนดให้ fill ทั้ง  img และ mask หรือ fill เฉพาะ mask อย่างเดียวก็ได้


flag จะประกอบด้วยข้อมูลสามส่วน
        แปดบิทล่าง จะมีค่าเป็น 4,8 ใช้กำหนดทิศทางในการ fill โดย 4 จะเป็นการ fill เฉพาะแนวตั้งและแนวนอนและ 8 จะ fill รอบด้านทั้งแปดทิศ
        แปดบิทกลาง จะกำหนดว่า mask จะถูกกำหนดว่า mask จะถูก fill ด้วยค่าอะไรถ้า set เป็น 0 จะถูก fill ด้วยค่า 1s(127)
        แปดบิดบน จะเป็นการเซตค่า CV_FLOODFILL_FIXED_RANGE (ที่อธิบายไปแล้ว) และ CV_FLOODFILL_MASK_ONLY fill เฉพาะ mask เท่านั้น

ลองยกตัวอย่าง flag ถ้าเราต้องการให้  fill ทั้งแปดทิศ, fill เฉพาะ mask, fill mask ด้วยค่า 47

flag = 8 | CV_FLOODFILL_MASK_ONLY | CV_FLOODFILL_FIXED_RANGE | (47<<8)

(น่าจะไม่มีปัญหา bitwise or และ shift bit ธรรมดา)

No comments:

Post a Comment