python - 使用 OpenCV 使用 Python 访问 Prosilica GigE 相机时,函数调用在 C 中有效,但在 Python 中出现段错误

标签 python c opencv camera computer-vision

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

我正在尝试让 Python OpenCV 绑定(bind)来访问 AVT GigE GC1360H 相机使用 modules/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 绑定(bind)到 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

最佳答案

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

关于python - 使用 OpenCV 使用 Python 访问 Prosilica GigE 相机时,函数调用在 C 中有效,但在 Python 中出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11621893/

相关文章:

python - 用于开发环境的Docker设置?

python - KMeans "No handles with labels found to put in legend"的 3D 散点图图例错误

java - 有没有可以优化数学公式的工具?

python - 如何在opencv python中获取视频的前一帧

python - Airflow 调度程序异常停止

c - 制作并口DB25的设备驱动程序

c - 在 C 中设置环境变量

python - 如何将 OpenCV 与 PyQt 结合起来创建一个简单的 GUI?

c++ - 使用 Qt 5.0 以编程方式创建视频

python Pandas : list of integers as individual values of DataFrame