void saturate_sv( IplImage* img ) {
for( int y=0; y
uchar* ptr = (uchar*) (
img->imageData + y * img->widthStep
);
for( int x=0; x
ptr[3*x+1] = 255;
ptr[3*x+2] = 255;
}
}
}
เป็นฟังก์ชันเซตค่า image ในโหมด HSV ที่มี 3 channel ให้เพิ่มค่า S, V สูงสุด โดยไม่เปลี่ยน H
สังเกตวิธีการเข้าถึงทุก pixel ในภาพ การวนลูปจะวนตามแถว(row) ซึ่งจำนวน row มีค่าเท่ากับ height (ไม่งงใช่ไหม) ถ้าวนลูปกลับกันการเข้าถึงข้อมูลจะกระโดดไปมา และสังเกตว่าในแต่ละ row จะมีข้อมูลเฉพาะของแต่ละแถวอยู่ ขนาดข้อมูลส่วนนี้อยู่รวมอยู่ใน widthStep (แบบเดียวกับ step ใน CvMat) ดังนั้นเวลา iteration แต่ละแถวค่าที่เพิ่มขึ้นจะต้องเป็น widthStep ไม่ใช่ width*channel*bit dept
ข้อมูลที่่สำคัญอีกอันหนึ่งของ IplImage ที่ไม่มีใน CvMat คือ ROI(region on interest) ซึ่งโอเปอร์เรชั่นส่วนมากใน OpenCV สนับสนุน ROI ด้วย ข้อมูลใน IplImage จะถูกประมวลผลเฉพาะในส่วนที่ตั้งค่าไว้ใน ROI เท่านั้น มีคำสั่งที่สำคัญสำหรับ ROI คือ
- cvSetImageROI ตั้งค่า ROI
- cvResetImageROI ยกเลิกการตัั้งค่า ROI
แต่การใช้ ROI มีข้อจำกัดที่ว่าสามารถใช้ได้ทีละครั้ง แต่มีเทคนิคการในการสร้าง ROI หลายๆ อันได้ โดยใช้ประโยชน์ของ widthStep ขั้นตอนมีดังนี้
- สร้าง IplImage header โดยยังไม่ต้องสร้าง data (ประโยชน์หนึ่งของการสร้างแยกกันระหว่าง header กับ data) โดยตั้งค่าต่างๆ (depth, channel)ให้เท่ากับภาพต้นฉบับ ยกเว้น width กับ height
- ตั้งค่า widthStep ของ sub image ให้ตรงกับของต้นฉบับ
- ตั้งค่า pointer data ของ sub image ให้ตรงกับจุดเริ่มต้น ROI ในภาพต้นฉบับที่เราสนใจ
IplImage *sub_img = cvCreateImageHeader(
cvSize(
interest_rect.width,
interest_rect.height
),
interest_img->depth,
interest_img->nChannels
);
sub_img->origin = interest_img->origin;
sub_img->widthStep = interest_img->widthStep;
sub_img->imageData = interest_img->imageData +
interest_rect.y * interest_img->widthStep +
interest_rect.x * interest_img->nChannels;
.................// operation with sub_image here
cvReleaseImageHeader(&sub_img);
โดย interest_img คือภาพต้นฉบับ, interest_rect คือ ROI ที่สัมพันธ์กับต้นฉบับ sub_image จะเป็นภาพ ROI ของ interest_img โดยวิธีนี้สามารถสร้าง ROI ได้หลายๆ อันในครั้งเดียว
No comments:
Post a Comment