2016-04-22 3 views
1

Я хочу комбинировать поток веб-камеры в реальном времени в качестве фона фона, контролируя ориентацию панорамирования камеры с помощью курсора мыши при наведении курсора мыши на изображение.
У меня есть две программы, которые работают независимо, первый - это элемент управления pan_tilt, в котором используется сервоконтроллер pololu maestro8 с именем servo_control.py. второй - окно веб-камеры и элемент управления события XY для pan_tilt с именем test_servo_webcam3.py.python servo pan tilt webcam image as background

servo_control.py

#!/usr/bin/env python 

import serial 
import time 


class Servo: 

    def __init__(self): 
     self.ser = serial.Serial('/dev/ttyACM0') 
     self.ser.baudrate = 115200 
     self.ser.write(chr(0xAA)) 
     self.ser.flush() 
     self.centre_servo() 

    def centre_servo(self): 
     # tvalue is for every 1/4 us so 4000=1000us 
     # centre servos 
     self.ser.write(chr(0x84) + chr(0x00) + chr(0x70) + chr(0x2E)) 
     # 0x2E70 = 0b010.1110.111.0000 = 6000 -> 1500us = zero power 
     self.ser.flush() 
     self.ser.write(chr(0x84) + chr(0x01) + chr(0x70) + chr(0x2E)) 
     # 0x2E70 = 0b010.1110.111.0000 = 6000 -> 1500us = zero power 
     self.ser.flush() 

    def servo_track_XY(self, channel, XYvalue): 
     Xvalue = (XYvalue * 2) + 1000 
     if Xvalue < 1000: 
      Xvalue = 1000 
     if Xvalue > 2000: 
      Xvalue = 2000 
     #print "X, Y", Xvalue, Yvalue 
     Xvalue = round((Xvalue * 4), -1) 

     MSB = int(Xvalue/128) 
     LSB = int(Xvalue - (MSB * 128)) 
     xchannel = int(channel) 

     self.ser.flush() 
     self.ser.write(chr(0x84) + chr(xchannel) + chr(LSB) + chr(MSB)) 
     self.ser.flush() 

if __name__ == "__main__": 
    prog = Servo() 
    time.sleep(1) 
    for num in range(0, 500): 
     prog.servo_track_XY(0, num) 
     prog.servo_track_XY(1, num) 
     print num 
     time.sleep(0.02) 
    time.sleep(1) 
    prog.centre_servo() 

test_servo_webcam3.py

#!/usr/bin/python 

import sys, os 
import pygtk, gtk, gobject 
pygtk.require('2.0') 
import pygst 
pygst.require("0.10") 
import gst 
import servo_control 

class Application(): 
    def __init__(self): 
     #...setup_window 
     window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     window.set_title("Webcam-Viewer") 
     window.set_default_size(500, 500) 
     window.connect("destroy", gtk.main_quit, "WM destroy") 
     vbox = gtk.VBox() 
     window.add(vbox) 
     self.movie_window = gtk.DrawingArea() 
     self.movie_window.connect("motion_notify_event", self.motion_notify_event) 
     self.movie_window.set_events(gtk.gdk.EXPOSURE_MASK 
          | gtk.gdk.LEAVE_NOTIFY_MASK 
          | gtk.gdk.BUTTON_PRESS_MASK 
          | gtk.gdk.POINTER_MOTION_MASK 
          | gtk.gdk.POINTER_MOTION_HINT_MASK) 
     vbox.add(self.movie_window) 
     hbox = gtk.HBox() 
     vbox.pack_start(hbox, False) 
     #hbox.set_border_width(10) 
     hbox.pack_start(gtk.Label()) 
     hbox.add(gtk.Label()) 
    #...button - centre 
     self.button1 = gtk.Button("Centre") 
     vbox.pack_start(self.button1, False) 
    #...button - start 
     self.button2 = gtk.Button("Start") 
     vbox.pack_start(self.button2, False) 
    #...button - quit 
     self.button3 = gtk.Button("Quit") 
     vbox.pack_start(self.button3, False) 
    #...connect_signals 
     self.movie_window.connect("motion_notify_event", self.motion_notify_event) 
     self.button1.connect("clicked", self.centre_servo) 
     self.button2.connect("clicked", self.start_stop) 
     self.button3.connect("clicked", self.exit) 

     window.show_all() 

     # Set up the gstreamer pipeline 
     self.player = gst.parse_launch ("v4l2src ! autovideosink") 

     bus = self.player.get_bus() 
     bus.add_signal_watch() 
     bus.enable_sync_message_emission() 
     bus.connect("message", self.on_message) 
     bus.connect("sync-message::element", self.on_sync_message) 
     #...initialise 
     self.pan_tilt = servo_control.Servo() 
     gtk.gdk.threads_init() 
     gtk.main() 

    def start_stop(self, w, data=None): 
     if self.button2.get_label() == "Start": 
      self.button2.set_label("Stop") 
      self.player.set_state(gst.STATE_PLAYING) 
     else: 
      self.player.set_state(gst.STATE_NULL) 
      self.button2.set_label("Start") 

    def exit(self, widget, data=None): 
     self.player.set_state(gst.STATE_NULL) 
     gtk.main_quit() 

    def on_message(self, bus, message): 
     t = message.type 
     if t == gst.MESSAGE_EOS: 
      self.player.set_state(gst.STATE_NULL) 
      self.button2.set_label("Start") 
     elif t == gst.MESSAGE_ERROR: 
      err, debug = message.parse_error() 
      print "Error: %s" % err, debug 
      self.player.set_state(gst.STATE_NULL) 
      self.button2.set_label("Start") 

    def on_sync_message(self, bus, message): 
     if message.structure is None: 
      return 
     message_name = message.structure.get_name() 
     if message_name == "prepare-xwindow-id": 
      # Assign the viewport 
      imagesink = message.src 
      imagesink.set_property("force-aspect-ratio", True) 
      imagesink.set_xwindow_id(self.movie_window.window.xid) 

    def motion_notify_event(self, widget, event): 
     self.pan_tilt.servo_track_XY(0, event.x) 
     self.pan_tilt.servo_track_XY(1, event.y) 
     #print event.x, event.y 

    def centre_servo(self, widget, data=None): 
     self.pan_tilt.centre_servo() 

if __name__ == "__main__": 
    Application() 

test_servo_webcam3.py как написано будет импортировать servo_control.py и управлять панорамированием и наклоном камеры с помощью движения мыши над окном , Нажатие start должно отображать изображение веб-камеры, но изображение веб-камеры не отображается.

для изображения веб-камеры, чтобы показать, что servo_control должен быть прокомментирован следующим образом.

#self.pan_tilt = servo_control.Servo() 

Я не понимаю, почему при доступе к файлу servo_control изображение веб-камеры не отображается.

+0

Вы должны попытаться сократить это к [mcve]. – SiHa

ответ

0

Не уверен, что это является причиной вашей проблемы, но ваши gtk.threads_init() и gtk.main() заявления находятся в неправильном месте. Они должны быть по обе стороны вашего экземпляра Application(), а не в определении класса:

if __name__ == "__main__": 
    gtk.gdk.threads_init() # Here, or immediately after the imports 
    Application() 
    gtk.main() 

Это может быть потому, что вы делаете это: self.pan_tilt = servo_control.Servo() перед тем GTK был правильно инициализирован, чтобы многопоточность, это застрять где-нибудь.

Это не похоже на что-либо «thready» в Servo(), но я знаю с горького опыта, что GTK может быть очень finicky о потоках.

0

Решено. После долгих поисков я нашел ответ. Для «gst.parse_launch» требуется источник, который подается в фильтр, который переходит к раковине. «Источник -> Фильтр -> Раковина». В моей программе фильтр отсутствовал. После добавления функций кода.

Так, изменяя эту строку

self.player = gst.parse_launch ("v4l2src ! autovideosink") 

к этому

self.player = gst.parse_launch ("v4l2src ! video/x-raw-yuv,width=640,height=480,framerate=30/1 ! autovideosink") 

SIHA, большое спасибо за ваши комментарии