将灰度、彩色和精巧的图像(3)全部复制到一个大的 IplImage:Opencv 错误?

Posted

技术标签:

【中文标题】将灰度、彩色和精巧的图像(3)全部复制到一个大的 IplImage:Opencv 错误?【英文标题】:Copy grayscale, color and canny images(3) all into one large IplImage:Opencv Error? 【发布时间】:2012-06-16 22:25:59 【问题描述】:

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

这里 test.cpp 的第 55 行是:

…… cvCopy(gray, 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;

【讨论】:

好的,既然您已经找到了解决方案,请接受您的回答并关闭此会话。 对于那些不想比较整个代码集的人来说,第一个变化是在 cvConvertImage(img, gray); 的 while 循环中。最后一个就在 cvShowImage("ALLONE", long_img);

以上是关于将灰度、彩色和精巧的图像(3)全部复制到一个大的 IplImage:Opencv 错误?的主要内容,如果未能解决你的问题,请参考以下文章

matlab 如何将彩图转成灰度图

图片灰度化

如何将opencv灰度和彩色图像发送到Qt中的ftp服务器?

如何将 WORD中将彩色图片变成灰度图 或 黑白图 ?

彩色图像转为灰度图像

如何在 MATLAB 中将彩色图像转换为灰度图像?