การ resize image ใน OpenCV จริงๆ แล้วไม่น่าจะมีอะไรยุ่งยากในการใช้ ลองดูคำสั่งกันก่อน
void cvResize(
const CvArr* src,
CvArr* dst,
int interpolation = CV_INTER_LINEAR
);
src, dst คือภาพต้นฉบับและผลลัพธ์โดยดูจากขนาดของภาพใน header (IplImage) ควรระวังการตั้ง ROI ในภาพต้นฉบับ พารามิเตอร์สุดท้ายคือฟังก์ชันในการประมาณค่า interpolate ค่า pixel โดยมีค่าเป็น
- CV_INTER_NN nearest neighbor
- CV_INTER_LINEAR Bilinear
- CV_INTER_AREA Pixel area re-sampling
- CV_INTER_CUBIC Bicubic interpolation
Image Pyramids
Image pyramids คือ collection ของ image โดยเริ่มจาก image เริ่มต้นแล้วลดขนาดไปเรื่อยๆ จนถึงจุดที่ต้องการ ในหนังสือกล่าวถึง image pyramid สองแบบคือ gaussian pyramid กับ laplacian pyramid
Gaussian Pyramids จะเริ่มต้นที่ภาพต้นแบบเรียกว่าเลเยอร์ที่ 0 (แทนด้วย G0) เราจะสร้าง เลเยอร์ีที่ G(i+1) จากเลเยอร์ Gi โดยการ convolute Gi ด้วย gaussian kernel แล้วลบแถวคู่และหลักคู่ของภาพออกไป จะได้ภาพที่ขนาดเหลือหนึ่งในสี่ของเดิม ทำได้โดยใช้คำสั่ง
void cvPyrDown(
IplImage* src,
IplImage* dst,
IplFilter filter = IPL_GAUSSIAN_5x5
);
ถ้าต้องการ ขยายภาพขึ้นมาใช้คำสั่ง
void cvPyrUp(
IplImage* src,
IplImage* dst,
IplFilter filter = IPL_GAUSSIAN_5x5
);
แต่ภาพที่ได้จะคำสั่ง cvPyrUp จะไม่เท่ากับภาพก่อนหน้า เพราะว่ามีข้อมูลที่หายไปจากการ down sampling collection ของข้อมูลเหล่านี้จะเรียกว่า Laplicain Pyramids ลองดูรูปภาพตัวอย่างจากหนังสือ Learning OpenCV ของ OReilly
ไอ้ส่วนที่วงสีแดงไว้ผมว่าลูกศรน่าจะกลับทิศนะ
แล้วปัญหาคือไอ้ Image Pyramids นี่เกี่ยวกับ image segmentation ยังไงล่ะ
เขาบอกว่า การทำ image pyramids ทำให้การ segment สามารถ segment ที่ภาพเล็กๆ ก่อนแล้วค่อย map กลับเป็นภาพใหญ่ทีหลัง แน่นอน OpenCV ได้ใส่ฟังก์ชันนี้มาใ้ห้ท่านแล้ว
void cvPyrSegmentation(
IplImage* src,
IplImage* dst,
CvMemStorage* storage,
CvSeq** comp,
int level,
double threshold1,
double threshold2
);
src, dst คือต้นฉบับและผลลัพธ์(เนื่องจาก OpenCV ใช้ dst ในการคำนวณด้วย ดังนั้นยังไงก็ต้องใส่) int คือจำนวน level ของ pyramids (จะต้องระวังด้วย ว่าขนาดของความกว้างและความยาวของภาพใน src จะต้องหารด้วย 2^(levlel-1) ลงตัว)
stroage เป็น memory storage ที่ OpenCV ต้องการใช้ (รายละเอียดใน Memory Storage)
comp จะเป็น sequence ที่สร้างมาจาก cvPyrSegmentation เป็นข้อมูลเกี่ยวกับ connected component (cvConnectedComp) ซึ่งอธิบายโดย
typedef struct CvConnectedComponent {
double area; // พื้นที่ของ component
CvScalar value; // สีเฉลี่ยของพื้นที่นั้น
CvRect rect; // กรอบสี่เหลี่ยมรอบ component นั้น
CvSeq* contour; // ในฟังก์ชัน cvPyrSegmentation ไม่ได้เซต แต่หมายถึง sequence ของ contour(ไว้อธิบายในเรื่อง contour)
};
ลองมาดูตัวอย่างเพื่อความเข้าใจในการ segmentation ด้วย cyPyrSegmentation
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* comp = NULL;
cvPyrSegmentation( src, dst, storage, &comp, 4, 200, 50 );
int n_comp = comp->total;
for( int i=0; i
CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem( comp, i );
do_something_with( cc );
cvReleaseMemStorage( &storage );
จากโคด เราจะได้ sequence ของ connected component ซึ่งส่งต่อให้ฟังก์ชัน do_something_with
No comments:
Post a Comment