Friday, April 16, 2010

Learning OpenCV: Moments

Moments เป็นวิธีหนึ่งที่ง่ายที่สุดในการเปรียบเทียบ contour โดยการเปรียบเทียบ contour moments
ลองมาดูนิยามของคำว่า moment กันก่อน

m(p,q) = ผลรวมของ (I(x,y)*x^p*y^q) ในทุกจุด

ในกรณีที่ p=q=0 m(0,0) และเป็นรูป binary จะหมายถึงความยาวของ contour ถ้าเป็นรูปปิดจะหมายถึงพื้นที่ (จำนวนจุดทุกจุดในเส้นรอบปิด เท่ากับพื้นที่)


ฟังก์ชันที่ใช้ในการหา moment คือ


void cvContoursMoments(
    CvSeq* contour,
    CvMoments* moments
)



โดย CvMoments นิยามดังนี้


typedef struct CvMoments {
    // spatial moments
    double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
    // central moments
    double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
    // m00 != 0 ? 1/sqrt(m00) : 0
    double inv_sqrt_m00;
} CvMoments;

cvContoursMoments จะคำนวนเฉพาะ spatial moments ให้เท่านั้น เราสามารถหา moment ได้โดยใช้คำสั่ง
cvGetSpatialMoment


moments ที่กล่าวมายังใช้ัในการเปรียบเทียบ contour ได้ไม่ดีนัก ปกติแล้วเรามักจะต้องการ normalized moments (contour ที่รูปร่างเหมือนกันแต่ขนาดต่างกันจะได้เปรียบเทียบกันได้) และ moment ที่คำนวณได้จะขึ้นกับ ระนาบที่เลือกใช้ เพราะฉะนั้นถ้า contour เกิดการหมุน moments ก็จะไม่ match กัน

OpenCV มีทางเลือกในการหา moments คือ

  • cvMoments เหมือน cvContoursMoments แต่รับ input เป็นภาพ สามารถตั้งให้เป็น binary image ได้
  • cvGetCentralMoment การคำนวณคล้ายกับ cvMoments เพียงแต่ ลบค่า เฉลี่ยในแกน x,y ลงไป มีผลทำให้เกิดคุณสมบัติ transition invariant (ไม่เปลี่ยนแปลงไปตามการเลื่อน)
  • cvGetNormalizedCentralMoment เหมือน cvGetCentralMoment ยกเว้นมีการ normalized การ normalized นี้ทำให้เกิด invariant to scale (moment ของ contour ที่คล้ายๆ กัน แต่ขนาดไม่เท่ากันจะถูก normalized ให้ใกล้ๆ กัน)
  • cvGetHuMoments เกิดจากผลรวมของ normalized central moment ผลที่ได้ จะได้ค่าที่ invariant to scale, rotation, and reflection (ผลจาก Hu Moment เลเวลหนึ่งจะ invariant to rotate  เลเวลเจ็ด จะ invariant to skew จึงสามารถนำมาใช้ในการเปรียบเทียบได้ดีกว่า moment ธรรมดา)

Matching with Hu Moments

การ matching contours ใน OpenCV ใช้คำสั่ง


double cvMatchShapes(
    const void* object1,
    const void* object2,
    int method,
    double parameter = 0
);

object1, object2 สามารถเป็น image หรือ contour ได้ ถ้าเป็น image ฟังก์ชันนี้จะคำนวณ moments ให้ก่อน แล้วนำมาเปรียบเทียบ
parameter ตอนนี้ไม่ได้ใช้
method เลือกได้ระหว่าง


  • CV_CONTOURS_MATCH_I1
  • CV_CONTOURS_MATCH_I2
  • CV_CONTOURS_MATCH_I3

รายละเอียดดูได้จากในหนังสือ (เพราะไม่ได้บอกถึงผลที่ได้จากการ คำนวณแต่ละแบบ)

1 comment:

  1. ยังอยู่ไหมครับจะถามหน่อยครับ
    ผมต้องการวัดองศาของวัตถุครับ

    ReplyDelete