Я запускаю приложение OpenCV, которое использует также другие внешние библиотеки, такие как библиотеки Poco, jsoncpp и SDL.
Все библиотеки были скомпилированы локально, и я связываю их через Makefile.
Программа транслирует видео с веб-камеры и должна ловить ввод с клавиатуры (a
персонаж например) что-то сделать.
Все это под 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;
}
** компиляция **
Для компиляции скрипта я использую следующее 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 $@
Задача ещё не решена.
Других решений пока нет …