1

私がデバッグしようとしている一般的な問題は、Cプログラムが問題なく関数を呼び出すことができる理由ですが、Pythonで同じ関数を呼び出すと、セグメンテーション違反が発生します。

modules / highgui / src/cap_pvapi.cppを使用してAVTGigEGC1360HカメラにアクセスするためのPythonOpenCVバインディングを取得しようとしています。Cではカメラからフレームを問題なく読み取って表示できますが、Pythonでフレームを読み取ろうとすると、インタープリターが失敗します。PythonでVideoCapture.open(0)を呼び出すと、カメラがMono8モードに正常に初期化され、ifconfigを監視するとカメラからのデータが表示されます。AVTカメラの代わりにv4lWebカメラを使用してこれと同じPythonコードを実行でき、正常に動作します。Gentoo Linux3.2.12x64でOpenCV2.3.1を使用しています。これが私が使用しているPythonコードで、Python2.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インタープリターにアタッチし、OpenCVソースのCvCaptureCAM_PvAPI :: grabFrame()内のPvCaptureQueueFrame()の呼び出しでsegfaultが発生することを理解しました。その結果は次のとおりです。

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のsegfaultsです。問題はCへのPythonバインディングが生成される方法であると思う傾向がありますが、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_fla

4

1 に答える 1

0

問題を修正しました。CコードとPythonコードの唯一の違いは、PythonではcvCreateCameraCapture()(capture.open())に渡される引数でした。この関数に0を渡すと(Pythonで行ったように)、OpenCVがサポートするビデオデバイスをスキャンする必要があります。(Cで行ったように)CV_CAP_PVAPIを渡すと、この検索はProsilicaデバイスのみに制限されます。これらはまったく同じ結果をもたらすはずですが(両方とも同じカメラを見つけました)、0を渡すと、カメラは初期化されず、キューでtPvFrameを受け入れる準備ができていませんでした。800はCV_CAP_PVAPIの値であるため、capture.open()に800を渡すと問題が修正されました。

于 2012-07-24T22:02:26.490 に答える