使用OpenCV使用Python访问Prosilica GigE相机时,函数调用在C中工作但在Segfaults中工作

时间:2012-07-23 23:14:13

标签: python c opencv camera computer-vision

我正在尝试调试的一般问题是为什么C程序可以毫无问题地调用函数,但是当在Python中调用相同的函数时它会导致段错误。

我正在尝试使用Python OpenCV绑定来访问AVT GigE GC1360H摄像机使用模块/ highgui / src / cap_pvapi.cpp。我会读 并且在C中完美地显示来自相机的帧,但是当我尝试时 在Python中读取一个解释器段错误的帧。调用 Python中的VideoCapture.open(0)成功初始化摄像头 Mono8模式,并观察ifconfig显示来自的数据 相机。我可以使用我的v4l网络摄像头运行相同的Python代码 AVT相机,它工作正常。我正在使用OpenCV 2.3.1 Gentoo Linux 3.2.12 x64。这是我正在使用的Python代码,正在运行 在Python 2.7.2上:

import cv2

if __name__ == '__main__':
    cv2.namedWindow("Cam", 1)
    capture = cv2.VideoCapture()
    capture.open(0) # This successfully opens the Camera and ifconfig
shows data being transferred
    while True:
        img = capture.read()[1] # This is where it segfaults

        cv2.imshow("Cam", img)
        if cv2.waitKey(10) == 27: break

    cv2.destroyWindow("Cam")

我将gdb附加到Python解释器并找出它 在调用PvCaptureQueueFrame()里面的段错误 OpenCV源中的CvCaptureCAM_PvAPI :: grabFrame()。以下是该输出:

alex@Wassenberg ~ $ gdb python GNU gdb (Gentoo 7.3.1 p2) 7.3.1 Copyright (C) 2011 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-pc-linux-gnu". For bug reporting instructions, please see: <http://bugs.gentoo.org/>... Reading symbols from /usr/bin/python...(no debugging symbols found)...done. (gdb) run ./pyview.py Starting program: /usr/bin/python ./pyview.py process 8921 is executing new program: /usr/bin/python2.7 [Thread debugging using libthread_db enabled] [New Thread 0x7fffe3c10700 (LWP 8929)] [New Thread 0x7fffe340f700 (LWP 8930)] [New Thread 0x7fffe2c0e700 (LWP 8931)] [New Thread 0x7fffe240d700 (LWP 8932)] [Thread 0x7fffe240d700 (LWP 8932) exited] [New Thread 0x7fffe240d700 (LWP 8933)] [Thread 0x7fffe240d700 (LWP 8933) exited] [New Thread 0x7fffe240d700 (LWP 8940)] [Thread 0x7fffe240d700 (LWP 8940) exited] [New Thread 0x7fffe240d700 (LWP 8941)] [New Thread 0x7fffe1c0c700 (LWP 8942)] [New Thread 0x7fffe0eb9700 (LWP 8948)] [New Thread 0x7fffdbfff700 (LWP 8949)]

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff007c8ea in PvCaptureQueueFrame () from /usr/local/lib/libPvAPI.so (gdb) bt
#0  0x00007ffff007c8ea in PvCaptureQueueFrame () from /usr/local/lib/libPvAPI.so
#1  0x00007ffff55dd123 in CvCaptureCAM_PvAPI::grabFrame() () from /usr/lib64/libopencv_highgui.so.2.3
#2  0x00007ffff55dde31 in cvGrabFrame () from /usr/lib64/libopencv_highgui.so.2.3
#3  0x00007ffff55dde4d in cv::VideoCapture::grab() () from /usr/lib64/libopencv_highgui.so.2.3
#4  0x00007ffff55ddaf2 in cv::VideoCapture::read(cv::Mat&) () from /usr/lib64/libopencv_highgui.so.2.3
#5  0x00007ffff6b355c5 in ?? () from /usr/lib64/python2.7/site-packages/cv2.so
#6  0x00007ffff7afdfdc in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#7  0x00007ffff7aff88d in PyEval_EvalCodeEx () from /usr/lib64/libpython2.7.so.1.0
#8  0x00007ffff7aff9a2 in PyEval_EvalCode () from /usr/lib64/libpython2.7.so.1.0
#9  0x00007ffff7b19afc in ?? () from /usr/lib64/libpython2.7.so.1.0
#10 0x00007ffff7b1a930 in PyRun_FileExFlags () from /usr/lib64/libpython2.7.so.1.0
#11 0x00007ffff7b1b50f in PyRun_SimpleFileExFlags () from /usr/lib64/libpython2.7.so.1.0
#12 0x00007ffff7b2c823 in Py_Main () from /usr/lib64/libpython2.7.so.1.0
#13 0x00007ffff74902ad in __libc_start_main () from /lib64/libc.so.6
#14 0x00000000004008a9 in _start () (gdb)

对此问题的任何见解将不胜感激。归根结底,这个问题归结为为什么C可以调用grabFrame()而没有问题,但Python段错误。我倾向于认为 问题是生成Python绑定到C的方式,但是我 我不熟悉OpenCV如何做到这一点。任何想法为什么grabFrame()和PvCaptureQueueFrame()在C中都能正常工作但在Python中却不行?

此处参考的是可以成功读取AVT摄像机的C程序:

#include <opencv2/imgproc/imgproc_c.h>
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>

int main(int argc, char** argv)
{
      printf("Press ESC to exit\n");
      cvNamedWindow( "First Example of PVAPI Integrated", CV_WINDOW_AUTOSIZE );
      CvCapture* capture = cvCreateCameraCapture( CV_CAP_PVAPI );
      assert( capture != NULL );

      IplImage* frame;

      while(1)
      {
            frame = cvQueryFrame(capture);

            if(!frame) break;
            cvShowImage( "First Example of PVAPI Integrated", frame);
            char c = cvWaitKey(50);
            if( c == 27) break;
      }
      cvReleaseCapture( &capture );
      cvDestroyWindow( "First Example of PVAPI Integrated" );
}

使用gcc 4.5.3-r2编译:

  

gcc -I / usr / include / opencv -o main ./main.c -lopencv_core   -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video   -lopencv_features2d -lopencv_calib3d -lopencv_objdetect   -lopencv_contrib -lopencv_legacy -lopencv_flann

1 个答案:

答案 0 :(得分:0)

我修复了问题,C代码和Python代码之间的唯一区别是传递给cvCreateCameraCapture()(Python中的capture.open())的参数。将0传递给此函数(就像我在Python中所做的那样)应该让它扫描OpenCV支持的任何视频设备。传递CV_CAP_PVAPI(就像我在C中所做的那样)应该将此搜索限制为仅限Prosilica设备。虽然这些结果应该完全相同(它们都找到相同的相机),但是当传入0时相机没有初始化并且还没准备好接受队列中的tPvFrames。将800传递给capture.open()修复了问题,因为800是CV_CAP_PVAPI的值。