исключение gstreamer в gst_element_get_state, запускающем программу opencv - PullRequest
0 голосов
/ 01 октября 2018

Я запускаю приложение OpenCV, которое использует также другие внешние библиотеки, такие как библиотеки Poco, jsoncpp и SDL.

Все библиотеки были скомпилированы локально, и я связываю их через Makefile.

Программа транслирует видео с веб-камеры и должна что-то перехватить с клавиатуры (например, символ * 1005).

Все это в Ubuntu 18.04;исходный код C ++ правильный, потому что под OSX он работает без проблем и делает то, что ожидал (при необходимости я добавлю пример исходного кода).

Программа запускается и не останавливается, но работаетне перехватывает ввод с клавиатуры и, как только он запускается, я получаю сообщение об ошибке

(process:11477): GStreamer-CRITICAL **: 18:44:25.567: gst_element_get_state: assertion 'GST_IS_ELEMENT (element)' failed
OpenCV | GStreamer warning: GStreamer: unable to query pipeline state (/home/fra/Documents/openCV/openCV/modules/videoio/src/cap_gstreamer.cpp:420)

Я установил библиотеки gstreamer, потому что они были необходимы для opencv, и я включил и связал их в Makefile следующим образомполный Makefile позже):

`pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-1.0.pc`\
 ...

и

`pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-1.0.pc`\
....

У кого-нибудь была такая же проблема?Что вызывает исключение?

Я думаю, что ошибка связана с зависимостями Opencv, но я не уверен, что это не проблема, связанная с SDL2.0.

ИСТОЧНИК КОДПРОГРАММА C ++

Вот минимальный рабочий пример: нажатие левой и правой кнопок мыши работает (отлавливается непосредственно с помощью обратных вызовов Opencv), в то время как нажатие и отпускание кнопок клавиатуры не вызывает надлежащего обратного вызова SDL.Сценарий может быть запущен с помощью ./executable camID anyNameYouWant, где camID - это целое число (обычно 0 или 1), которое идентифицирует камеру, которую вы хотите использовать.

#ifndef __OPENCV__
#define __OPENCV__
#include "opencv2/opencv.hpp"
#endif
#include<iostream>
//#include "utils.hpp"
//#include "constants.hpp"
#include<unistd.h>
#include <vector>
#include<SDL.h>
#include <SDL_events.h>

using namespace cv;
using namespace std;
static const int delay = 2;
#define WINDOW_SCALE 1.7

//const int SCREEN_WIDTH = 640;
//const int SCREEN_HEIGHT = 480;

void onTrackbar_changed(int, void* data);
//void onThreshold_changed(int, void* data);
void onMouse(int evt, int x, int y, int flags, void* param);
void PrintKeyInfo( SDL_KeyboardEvent *key );
int keyboardCallback(SDL_KeyboardEvent ev);

//InputStateContext context;

int main(int argc, char* argv[])
{
    /* Initialise SDL */
    if( SDL_Init( SDL_INIT_VIDEO ) < 0)
    {
        fprintf( stderr, "Could not initialise SDL: %s\n", SDL_GetError() );
        exit( -1 );
    }

  string host;
  unsigned int port;
  const String sourceReference = argv[1];
  int camNum;
  string sensorName;
  try
  {
    camNum = stoi(sourceReference); // throws std::length_error
  }
  catch (const std::exception& e)// reference to the base of a polymorphic object
    {
    std::cout<<"Exception: " << e.what()<<endl; // information from length_error printed
    return -1;
  }
  if (argc>4)
  {
    try
    {
      host = argv[2];
      port = atoi(argv[3]);
      sensorName = argv[4];
    }
    catch (const std::exception& e)
    {
      cout<<"impossible to convert host or port"<<endl;
      return -1;
    }
  }
  else if(argc>2)
  {
    cout<<"argumetns less than 4"<<endl;
    host = "http://localhost";
    port = 3456;

    sensorName = argv[2];
    cout<<argc<<endl;
    cout<<"sensor name set from arguments: "<< sensorName<<endl;

  }
  else
  {
    cout<<"stopping execution: too few arguments."<<endl;
    return -1;
  }
  VideoCapture cam(camNum);
  /* or
  VideoCapture captUndTst;
  captUndTst.open(sourceCompareWith);*/
  if ( !cam.isOpened())
  {
    cout << "Could not open reference " << sourceReference << endl;
   return -1;
  }

  namedWindow("Camera", WINDOW_NORMAL);
  Mat frame;

  SDL_Event keyboardEvent;

  cam>>frame;
  resize(frame, frame, cv::Size(frame.cols/WINDOW_SCALE, frame.rows/WINDOW_SCALE));
  resizeWindow("Camera", cv::Size(frame.cols/WINDOW_SCALE, frame.rows/WINDOW_SCALE));
  setMouseCallback("Camera", onMouse, &frame);
  while(1)
  {
      while( SDL_PollEvent( &keyboardEvent) )
      {
          switch( keyboardEvent.type )
          {
              /* Keyboard event */
              /* Pass the event data onto PrintKeyInfo() */

              case SDL_KEYDOWN:
              break;
              case SDL_KEYUP:
              keyboardCallback(keyboardEvent.key);
              break;

              /* SDL_QUIT event (window close) */
              case SDL_QUIT:
              return 0;
              break;

              default:
              break;
          }

      }
     Mat frame_out;
     frame_out = frame.clone();
    cam>>frame;
    resize(frame_out, frame_out, cv::Size(frame.cols/WINDOW_SCALE, frame.rows/WINDOW_SCALE));

    imshow("Camera", frame_out);

    /* A delay is needed to show (it actually wait for an input)*/
    if(waitKey(delay)>delay){;}

  }
    return 0;
}

void onMouse(int evt, int x, int y, int flags, void* param)
{

    if(evt == EVENT_LBUTTONDOWN)
    {
      cout<<"Left button pressed"<<endl;

    }
    else if(evt == EVENT_RBUTTONDOWN)
    {
      cout<<"Right button pressed"<<endl;
    }
}

int keyboardCallback(SDL_KeyboardEvent ev)
{
    switch(ev.keysym.sym)
    {
        case(SDLK_a):
        cout<<"calling context keyboardA"<<endl;
        break;
        case(SDLK_e):
        cout<<"calling context keyboardE"<<endl;
        break;
        case(SDLK_m):
        cout<<"calling context keyboardM"<<endl;
        break;
        case SDLK_UP:
        case SDLK_RIGHT:
        cout<<"calling context RIGHT ARROW"<<endl;
        break;
        case SDLK_DOWN:
        case SDLK_LEFT:
        cout<<"calling context RIGHT ARROW"<<endl;
        break;
        case (SDLK_RETURN):
        cout<<"calling context RIGHT ARROW"<<endl;
        break;
        default:
        break;

    }
    return 0;
}

** COMPILATION **

Для компиляции скрипта я использую следующее Makefile.Пути к библиотекам являются родственниками (кроме библиотек gstreamer), так как я собрал их в локальной папке.

CXX = g++

CXXFLAGS = -std=c++11
INC_PATH = `pkg-config --cflags ../openCV/build/lib/pkgconfig/opencv.pc` \
    `pkg-config --cflags ../SDL2-2.0.8/instDir/lib/pkgconfig/sdl2.pc` \
    `pkg-config --cflags ../jsoncpp/build/pkg-config/jsoncpp.pc` \
    -I ../poco/instDir/include/ \
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-1.0.pc`\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-allocators-1.0.pc`\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-app-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-audio-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-bad-audio-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-bad-video-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-base-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-check-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-codecparsers-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-controller-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-fft-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-gl-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-insertbin-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-mpegts-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-net-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-pbutils-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-player-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-plugins-bad-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-plugins-base-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-plugins-good-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-riff-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-rtp-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-rtsp-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-sdp-1.0.pc`\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-tag-1.0.pc`\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-video-1.0.pc `\
    `pkg-config --cflags /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-webrtc-1.0.pc` 

#LIB_PATH = -L../cmake_bin_dir/lib/ ./gainput/build/lib -L../SDL2-2.0.8/build/ -L../SDL2-2.0.8/build/lib
LIBS =  `pkg-config --libs ../openCV/build//lib/pkgconfig/opencv.pc` \
    `pkg-config --libs ../SDL2-2.0.8/instDir/lib/pkgconfig/sdl2.pc` \
    `pkg-config --libs ../jsoncpp/build/pkg-config/jsoncpp.pc` \
    -L../poco/instDir/lib/ -lPocoNetd -lPocoUtild -lPocoFoundationd \
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-1.0.pc`\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-allocators-1.0.pc`\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-app-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-audio-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-bad-audio-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-bad-video-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-base-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-check-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-codecparsers-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-controller-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-fft-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-gl-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-insertbin-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-mpegts-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-net-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-pbutils-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-player-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-plugins-bad-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-plugins-base-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-plugins-good-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-riff-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-rtp-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-rtsp-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-sdp-1.0.pc`\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-tag-1.0.pc`\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-video-1.0.pc `\
    `pkg-config --libs /usr/lib/x86_64-linux-gnu/pkgconfig/gstreamer-webrtc-1.0.pc`

SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.cpp)
OBJDIR=$(SOURCEDIR)/obj

OBJECTS := $(patsubst $(SOURCEDIR)/%.cpp,$(OBJDIR)/%.o,$(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.cpp,$(OBJDIR)/%.d,$(SOURCES))

# ADD MORE WARNINGS!
WARNING := -Wall -Wextra

# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean

# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: parking

clean:
    $(RM) $(OBJECTS) $(DEPENDS) parking

# Linking the executable from the object files
parking: $(OBJECTS)
    $(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $@ $(LIBS)

-include $(DEPENDS)

$(OBJDIR):
    mkdir -p $(OBJDIR)

$(OBJDIR)/%.o: $(SOURCEDIR)/%.cpp Makefile $(OBJDIR)
    $(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) -MMD -MP -c $< -o $@
...