2012-06-16 2 views
0

У меня есть исходный код (test.cpp), который должен отображать три изображения (цветные, полутоновые и канонические), скопированные на большое изображение из файла avi (по кадре) и отображаемые в одном окне. Я использую библиотеку OpenCV с компилятором C++ (gnu) на платформе linux.Копирование изображений в оттенках серого, цвета и canny (3) все в один большой IplImage: Ошибка Opencv?

Но у меня возникает ошибка сегментации (ядро сбрасывается).

дамп ядра:

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) 

Здесь линия 55 является test.cpp:

...... cvCopy (серый, gray_sub);

......

Программа (test.cpp) приведены ниже. Можно ли копировать три изображения (цветные, полутоновые и канны на одиночном IplImage)? Я определенно делаю что-то не так. Можно ли любезно помочь мне узнать, что я делаю неправильно?

#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; 
} 

ответ

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; 
} 
+0

Хорошо, так как вы получили решение, примите ваш ответ и закройте эту сессию. –

+0

Для тех, кто не хочет сравнивать весь набор кода, первое изменение находится в цикле while в cvConvertImage (img, gray); и последним перед cvShowImage («ALLONE», long_img); – RyanfaeScotland