0

我有一个源代码(test.cpp),它应该显示从 avi 文件(逐帧)复制到大图像并显示在单个窗口中的三个图像(彩色、灰度和 canny)。我在 Linux 平台上使用 OpenCV 库和 c++ 编译器(gnu)。

但是我遇到了分段错误(核心转储)。

核心转储:

GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/ad/Desktop/opencv_exercises/ch4/ex1_b/test...done.

warning: Can't read pathname for load map: Input/output error.
Cannot access memory at address 0x5454505052525555
(gdb) r test.avi
Starting program: /home/ad/Desktop/opencv_exercises/ch4/ex1_b/test test.avi
[Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff627f831 in memcpy () from /lib/libc.so.6
(gdb) bt
#0  0x00007ffff627f831 in memcpy () from /lib/libc.so.6
#1  0x00007ffff6e5ee42 in cv::Mat::copyTo(cv::Mat&) const ()
   from /usr/lib/libcxcore.so.2.1
#2  0x00007ffff6e629fb in cvCopy () from /usr/lib/libcxcore.so.2.1
#3  0x0000000000400e0a in main (argc=2, argv=0x7fffffffe3a8) at test.cpp:55
(gdb) 

这里 test.cpp 的第 55 行是:

...... cvCopy(gray, gray_sub);

……

该程序是(test.cpp)下面给出。是否可以在单个 IplImage 上复制三个图像(彩色、灰度和 canny)?我肯定做错了什么。是否可以帮助我找出我做错了什么?

#include <cv.h>
#include <highgui.h>
#include <stdio.h>


int main( int argc, char** argv )
{
    IplImage *frame;
    CvCapture *capture = NULL;


    if(( argc < 2 ) || !(capture = cvCreateFileCapture( argv[1] )))
    {
        printf("Failed to open %s\n", argv[1] );
        return -1;
    }

    double f = cvGetCaptureProperty(
        capture,
        CV_CAP_PROP_FRAME_COUNT
        );
    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);



    CvSize size = cvSize(cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH), cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
    IplImage *img = NULL;
    double index = 0;
    IplImage *gray = cvCreateImage(size,IPL_DEPTH_8U,1);
    IplImage *canny = cvCreateImage(size,IPL_DEPTH_8U,1);
    IplImage *long_img = cvCreateImage(cvSize(size.width*3, size.height),IPL_DEPTH_8U, 3);
    IplImage *color_sub, *gray_sub, *canny_sub;
    cvNamedWindow("ALLONE", 1);
    int key = 0;

    while( index++ < f)
    {       
            cvGrabFrame(capture);
        img = cvRetrieveFrame(capture);

        color_sub = cvCreateImageHeader(size, long_img->depth, long_img->nChannels);
        color_sub->origin = long_img->origin;
        color_sub->widthStep = long_img->widthStep;
        color_sub->imageData = long_img->imageData;

        cvCopy(img, color_sub);



        cvConvertImage(img, gray);
        gray_sub = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
        gray_sub->origin = long_img->origin;
        gray_sub->widthStep = long_img->widthStep;
        gray_sub->imageData = long_img->imageData + size.height * long_img->widthStep + size.width * long_img->nChannels;

        cvCopy(gray, gray_sub);


        cvCanny(gray, canny, 100, 200);
        canny_sub = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
        canny_sub->origin = long_img->origin;
        canny_sub->widthStep = long_img->widthStep;
        canny_sub->imageData = long_img->imageData + size.height * long_img->widthStep + (size.width * 2) * long_img->nChannels;

        cvCopy(canny, canny_sub);



        cvShowImage("ALLONE", long_img);

        key = cvWaitKey(10);
        if(key == 27) break;
        printf("%d\n", key);
    }




    cvReleaseCapture( &capture );

    return 0;
}
4

1 回答 1

1

我找到了解决方案。有兴趣的人代码如下:

#include <cv.h>
#include <highgui.h>
#include <stdio.h>


int main( int argc, char** argv )
{
    IplImage *frame;
    CvCapture *capture = NULL;


    if(( argc < 2 ) || !(capture = cvCreateFileCapture( argv[1] )))
    {
        printf("Failed to open %s\n", argv[1] );
        return -1;
    }

    double f = cvGetCaptureProperty(
        capture,
        CV_CAP_PROP_FRAME_COUNT
        );
    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);



    CvSize size = cvSize(cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH), cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
    IplImage *img = NULL;
    double index = 0;
    IplImage *gray = cvCreateImage(size,IPL_DEPTH_8U,1);
    IplImage *canny = cvCreateImage(size,IPL_DEPTH_8U,1);
    IplImage *long_img = cvCreateImage(cvSize(size.width*3, size.height),IPL_DEPTH_8U, 3);
    IplImage *color_sub, *gray_sub, *canny_sub;
    cvNamedWindow("ALLONE", 1);
    int key = 0;

    while( index++ < f)
    {       cvGrabFrame(capture);
        img = cvRetrieveFrame(capture);

        color_sub = cvCreateImageHeader(size, long_img->depth, long_img->nChannels);
        color_sub->origin = long_img->origin;
        color_sub->widthStep = long_img->widthStep;
        color_sub->imageData = long_img->imageData;

        cvCopy(img, color_sub);



        cvCvtColor(img, gray, CV_BGR2GRAY);
        gray_sub = cvCreateImageHeader(size,  long_img->depth,long_img->nChannels);
        gray_sub->origin = long_img->origin;
        gray_sub->widthStep = long_img->widthStep;
        gray_sub->imageData = long_img->imageData  + (size.width * long_img->nChannels);

        cvMerge(gray , gray, gray, NULL, gray_sub);


        cvCanny(gray, canny, 100, 200);
        canny_sub = cvCreateImageHeader(size, long_img->depth, long_img->nChannels);
        canny_sub->origin = long_img->origin;
        canny_sub->widthStep = long_img->widthStep;
        canny_sub->imageData = long_img->imageData +  ((size.width * 2)  * long_img->nChannels);

        cvMerge(canny , canny, canny, NULL, canny_sub);

        cvShowImage("ALLONE", long_img);

        key = (char) cvWaitKey(1000/fps);
        if(key == 27) break;
        printf("%d\n", key);
    }




    cvReleaseCapture( &capture );

    return 0;
}
于 2012-06-17T04:07:25.413 回答