Tuesday, April 13, 2010

Learning OpenCV: CvMat in OpenCV short guide

จากชื่่อก็คงจะเดาได้อยู่แล้วว่า CvMat นั้นเอาใช้ใช้แทน matrix ซึ่ง CvMat นี่ประกอบไปด้วยสองส่วน คือส่วน Header กับ ส่วน Data (คงพอเดากันได้ว่า Data นั้นจริงๆ ก็คือ  pointer ธรรมดาแล้ว malloc ค่าเอานั่นเอง) ซึ่งจริงๆ เวลาสร้าง CvMat นั้นคือคำสั่ง cvCreateMat ซึ่งแท้จริงแล้วคือการเรียกคำสั่ง cvCreateMateHeader และ cvCreateData เหตุผลก็คือเราสามารถ สร้าง header ก่อนแล้วค่อยกำหนด data
พอใช้งานเสร็จแล้ว ก็อย่าลืม release ด้วย(ย้ำอีกที C ไม่มี auto dealloc)  โดยคำสั่ง cvReleaseMat ฟังก์ชันที่เกี่ยวข้องกับ CvMat สรุปคร่าวๆ ได้ดังนี้ (คงไม่ต้องอธิบายอ่านจากชื่อเอาน่าจะพอไหว)

  • cvCreateMat
  • cvCreateMatHeader
  • cvInitHeader
  • cvMat
  • cvCloneMat
  • cvReleaseMat


ทีนี้มาถีงเรื่องสำคัญกับการเข้าถึงข้อมูลใน CvMat OpenCV เตรียม function และ macro ไว้สำหรับการเข้าถึงข้อมูล แต่เขาแนะนำกันว่ามันช้าโดยเฉพาะอย่างยิ่งการประมวลผลกราฟฟิกต้องทำงานช้าอยู่แล้ว จึงแนะนำ ให้ประมวลผลโดยใช้วิธีการ iteration ไปยังค่าแต่ละค่าใน CvMat แทนดังตัวอย่าง


float sum( const CvMat* mat ) {
        float s = 0.0f;
        for(int row=0; rowrows; row++ ) {
               const float* ptr = (const float*)(mat->data.ptr + row * mat->step);
               for( col=0; colcols; col++ ) {
                        s += *ptr++;
               }
      }
      return( s );
}

อย่างลืมเวลาวนลูปนี่ข้างนอกเป็น row ห้ามสลับกัน เนื่องจากการวนลูปแบบนี้เนื้อที่ที่ถูก access ใน หน่วยความจำจะเรียกต่อกันพอดี (หน่วยความจำจริงๆ มีมิติเดียวการอ้างถึงแบบนี้จะเป็นการอ้างถึงข้อมูลที่ต่อเนื่องกันจากการ alloc)


matrix แต่ละตัวอาจจะมีข้อมูลพิเศษเก็บไว้ในแต่ละแถว ดังนั้นขนาดของแถวหนึ่งๆ อาจจะไม่เท่ากับ width*size of (int or float) ค่า step เป็นค่าที่รวมค่าทั้งหมดของแต่ละแถวไว้แล้ว


มีข้อยกเว้นในการใช้ macro กับ function ในการอ้างถึงข้อมูล ถ้าอ้างถึงข้อมูลเพียงจุดเดียวการใช้ macro หรือ function ก็ดูเป็นการประหยัดเวลาการเขียนโปรแกรม




สำคัญ(อีกแล้ว) ดังนั้นการสร้าง CvMat ขนาด MxN, NxM, 1x(M*N), (M*N)x1 จึงอาจจะไม่จำเป็นต้องเหมือนกัน ทำให้การส่งผ้านข้อมูลไปยังพารามิเตอร์ที่เป็น CvArr เกิดการจัดการข้อมูลผิดพลาดได้(เพราะ CvArr ไม่เช็คตรงนี้) แต่ปัญหาส่วนใหญ่คงไม่เกิด เพราะว่าถ้าเรายุ่งกับ image เราคงไม่จัดการ matrix เอง




*source code ตัวอย่างนำมาจากหนังสือ Learning OpenCV ของ Oreilly

No comments:

Post a Comment