题目说明:
b.将所有三个步骤实现显示在一个图像中。
提示:创建一个新的图像,其高度与原始图像相同,宽度为原来视频的3倍,将3幅图像分别复制到新的图像中:可使用指针;或者更巧妙地创建三个图像头,三个图像头分别指向图像数据的开始处,1/3处和2/3处,然后使用函数cvCopy()复制。
c.在图像的三个不同部分写上合适的文字标签
方法一:使用三个图像头
#include <highgui.h>
#include <cv.h>
int main()
{
char * file_path = "E:/song.mp4";
CvCapture * capture = 0;
capture = cvCreateFileCapture(file_path);
// 载入视频文件失败
if(capture == NULL)
{
printf("Can't load the video file, quit...\n");
return 0;
}
// 每一帧
IplImage * frame = cvQueryFrame(capture);
//原始图像的每一帧
IplImage * frame_origin = cvCreateImageHeader(cvGetSize(frame), frame->depth, 3);
// 灰度后的每一帧
IplImage * gray_frame = cvCreateImage( cvGetSize(frame), frame->depth, 1);
IplImage * gray_frame_3 = cvCreateImageHeader(cvGetSize(frame), frame->depth, 3);
// 边缘检测后的每一帧
IplImage * canny_frame = cvCreateImage( cvGetSize(frame), frame->depth, 1);
IplImage * canny_frame_3 = cvCreateImageHeader(cvGetSize(frame), frame->depth, 3);
// 母图像的每一帧
IplImage * total_frame = cvCreateImage( cvSize(frame->width * 3, frame->height),frame->depth, frame->nChannels);
//母图像显示窗口
cvNamedWindow("total",0);
//设置3个子图像的原点与行字长与原图像相同
frame_origin->origin = total_frame->origin;
frame_origin->widthStep = total_frame->widthStep;
gray_frame_3->origin = total_frame->origin;
gray_frame_3->widthStep = total_frame->widthStep;
canny_frame_3->origin = total_frame->origin;
canny_frame_3->widthStep = total_frame->widthStep;
//将子图像指向母图像,对子图像的操作就是在母图像进行操作
frame_origin->imageData = (char*) cvPtr2D(total_frame,0,0);
gray_frame_3->imageData = (char*) cvPtr2D(total_frame,0,frame_origin->width);
canny_frame_3->imageData = (char*) cvPtr2D(total_frame,0,frame_origin->width*2);
while(1)
{
// 从视频文件读入数据
frame = cvQueryFrame(capture);
if(!frame)
break;
//将frame读取的图像copy给frame_origin
cvCopy(frame,frame_origin,0);
// 将读入数据转换为灰度图
cvCvtColor( frame, gray_frame, CV_RGB2GRAY );
cvCvtColor( gray_frame, gray_frame_3, CV_GRAY2BGR );
// 对图像做Canny边缘检测
cvCanny( gray_frame, canny_frame, 30, 100, 3);
cvCvtColor( canny_frame, canny_frame_3, CV_GRAY2BGR );
// 在图像的三个不同的部分写上合适的文字标签
CvFont textFont = cvFont( 10, 1);
cvInitFont( &textFont, CV_FONT_HERSHEY_SIMPLEX, 0.5f, 0.5f, 0, 1 );
cvPutText( total_frame, "Frame_origin", cvPoint( 10, 20 ), &textFont, cvScalar( 0, 0, 255 ) );
cvPutText( total_frame, "Frame_Gray", cvPoint( frame->width + 10, 20 ), &textFont, cvScalar( 0, 0, 255 ) );
cvPutText( total_frame, "Frame_Canny", cvPoint( frame->width * 2 + 10, 20 ), &textFont, cvScalar( 0, 0, 255 ) );
// 显示图像
cvShowImage("total", total_frame);
char c = cvWaitKey(33);
if(c == 27)
break;
}
//释放物理内存
cvReleaseImage(&gray_frame);
cvReleaseImage(&canny_frame);
cvReleaseImageHeader( & frame_origin );
cvReleaseImageHeader( & gray_frame_3 );
cvReleaseImageHeader( & canny_frame_3 );
cvReleaseCapture(&capture);
cvDestroyAllWindows();
return 0;
}
方法二:使用感兴趣区,进行复制(qdsclove的专栏)
#include <highgui.h>
#include <cv.h>
int main()
{
char * file_path = "H:/TDDOWNLOAD/Video/STAR362.avi";
CvCapture * capture = 0;
capture = cvCreateFileCapture(file_path);
// 载入视频文件失败
if(capture == NULL)
{
printf("Can't load the video file, quit...\n");
return 0;
}
// 每一帧
IplImage * frame;
// 灰度后的每一帧
IplImage * gray_frame;
// 边缘检测后的每一帧
IplImage * canny_frame;
while(1)
{
// 从视频文件读入数据
frame = cvQueryFrame(capture);
if(!frame)
break;
// 将读入数据转换为灰度图
gray_frame = cvCreateImage( cvGetSize(frame), frame->depth, 1);
cvCvtColor( frame, gray_frame, CV_RGB2GRAY );
// 对图像做Canny边缘检测
canny_frame = cvCreateImage( cvGetSize(frame), frame->depth, 1);
cvCanny( gray_frame, canny_frame, 30, 100, 3);
// 显示图像
cvShowImage("color", frame);
cvShowImage("gray", gray_frame);
cvShowImage("canny", canny_frame);
char c = cvWaitKey(4);
if(c == 27)
break;
}
cvReleaseCapture(&capture);
cvDestroyAllWindows();
return 0;
}
注意: frame_origin->imageData = (char*) cvPtr2D(total_frame,0,0);将子图像指向母图像时坐标(0,0)为(行,列),且实现前提是子图像的origin和widthStep要一致。
引用qdsclove的专栏
http://blog.csdn.net/stk_overflow/article/details/8760044