《学习OpenCV》第四章课后题1-b&c

题目说明:
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

发布了19 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/windxf/article/details/46943449