2017-09-14 42 views
3

OpenCV VideoCaptureでビデオフレームをキャプチャしています。キャプチャは、私はこのようなフレームを使用することができる午前として正常に動作します:OpenCVからVideoWriterでGStreamerパイプラインを開く方法

cv::VideoCapture cap("v4l2src device=/dev/video1 ! videoscale ! videorate ! video/x-raw, width=640, height=360, framerate=30/1 ! videoconvert ! appsink"); 
cv::imshow("feed", frame); 

は、私はまた、ネットワーク経由でストリームを送信したいとここで私はこだわっています場所です。何とか私はappsrcパイプラインの部分で失敗しています。ストリームをjpegにエンコードして、それをudpと送信したいと思います。これは私が持っているものです:

cv::VideoWriter writer 
writer.open("appsrc ! videoconvert ! jpegenc ! jpegparse ! rtpjpegpay pt=96 ! udpsink host=192.168.1.25 port=5000", 0, (double)30, cv::Size(640, 360), true); 

上記の行は何もしないように見えます。 は何もしません。私はwriter.open一部に障害が発生していますどこ私は知らない

gst-launch-1.0 udpsrc port=5000 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)JPEG, payload=(int)96" ! rtpjpegdepay ! jpegdec ! decodebin ! videoconvert ! autovideosink 

:また、このgstreamerのコマンドは何も表示されません。私はこの怒鳴るようなgstreamerのコマンドを実行すると、彼らは働く:

gst-launch-1.0 v4l2src device=/dev/video1 ! videoscale ! videorate ! video/x-raw, width=640, height=360, framerate=30/1 ! jpegenc ! jpegparse ! rtpjpegpay pt=96 ! udpsink host=192.168.1.25 port=5000 
gst-launch-1.0 udpsrc port=5000 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)JPEG, payload=(int)96" ! rtpjpegdepay ! jpegdec ! decodebin ! videoconvert ! autovideosink 

答えて

2

OpenCVのののGStreamer APIを使用する前に、我々はGStreamerのコマンドラインツールを使用して作業パイプラインを必要とします。

送信者: OPはJPEGエンコーディングを使用しているため、このパイプラインでは同じエンコーディングが使用されます。

gst-launch-1.0 -v v4l2src \ 
! video/x-raw,format=YUY2,width=640,height=480 \ 
! jpegenc \ 
! rtpjpegpay \ 
! udpsink host=127.0.0.1 port=5000 

受信機:シンクcapsrtpjpegdepayの送信者パイプラインのrtpjpegpayのSRC capsと一致する必要があります。

gst-launch-1.0 -v udpsrc port=5000 \ 
! application/x-rtp, media=video, clock-rate=90000, encoding-name=JPEG, payload=26 \ 
! rtpjpegdepay \ 
! jpegdec \ 
! xvimagesink sync=0 

送信者と受信者の作業パイプラインが完成したので、OpenCVに移植することができます。

送信者:

void sender() 
{ 
    // VideoCapture: Getting frames using 'v4l2src' plugin, format is 'BGR' because 
    // the VideoWriter class expects a 3 channel image since we are sending colored images. 
    // Both 'YUY2' and 'I420' are single channel images. 
    VideoCapture cap("v4l2src ! video/x-raw,format=BGR,width=640,height=480,framerate=30/1 ! appsink",CAP_GSTREAMER); 

    // VideoWriter: 'videoconvert' converts the 'BGR' images into 'YUY2' raw frames to be fed to 
    // 'jpegenc' encoder since 'jpegenc' does not accept 'BGR' images. The 'videoconvert' is not 
    // in the original pipeline, because in there we are reading frames in 'YUY2' format from 'v4l2src' 
    VideoWriter out("appsrc ! videoconvert ! video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 ! jpegenc ! rtpjpegpay ! udpsink host=127.0.0.1 port=5000",CAP_GSTREAMER,0,30,Size(640,480),true); 

    if(!cap.isOpened() || !out.isOpened()) 
    { 
     cout<<"VideoCapture or VideoWriter not opened"<<endl; 
     exit(-1); 
    } 

    Mat frame; 

    while(true) { 

     cap.read(frame); 

     if(frame.empty()) 
      break; 

     out.write(frame); 

     imshow("Sender", frame); 
     if(waitKey(1) == 's') 
      break; 
    } 
    destroyWindow("Sender"); 
} 

受信機:

void receiver() 
{  
    // The sink caps for the 'rtpjpegdepay' need to match the src caps of the 'rtpjpegpay' of the sender pipeline 
    // Added 'videoconvert' at the end to convert the images into proper format for appsink, without 
    // 'videoconvert' the receiver will not read the frames, even though 'videoconvert' is not present 
    // in the original working pipeline 
    VideoCapture cap("udpsrc port=5000 ! application/x-rtp,media=video,payload=26,clock-rate=90000,encoding-name=JPEG,framerate=30/1 ! rtpjpegdepay ! jpegdec ! videoconvert ! appsink",CAP_GSTREAMER); 

    if(!cap.isOpened()) 
    { 
     cout<<"VideoCapture not opened"<<endl; 
     exit(-1); 
    } 

    Mat frame; 

    while(true) { 

     cap.read(frame); 

     if(frame.empty()) 
      break; 

     imshow("Receiver", frame); 
     if(waitKey(1) == 'r') 
      break; 
    } 
    destroyWindow("Receiver"); 
} 
+0

こんにちはサー!上記のコードを試してみましたが、VideoWriterを開いたときに何が問題なのですか?WindowsでGStreamerをインストールして環境パスに追加しました。 –

+0

@BahramdunAdil 'cout << cv :: getBuildInformation()<< endl;'の出力は何ですか? – zindarod

+0

@BahramdunAdilコメントを削除してください。出力をテキストファイルにコピーし、ファイルをどこかにアップロードし、リンクをここに投稿してください。これは2Kポイントのユーザーから受け入れられません! – zindarod

関連する問題