python伺服平移网络摄像头图像作为背景

时间:2016-04-22 11:31:09

标签: python pygtk

我希望将现场网络摄像头视频组合作为窗口背景,同时在鼠标悬停在图像上时用鼠标光标控制摄像机的pan_tilt方向。
我有两个独立工作的程序,第一个是pan_tilt控件,它使用一个名为servo_control.py的pololu maestro8伺服控制器。第二个是网络摄像头窗口和名为test_servo_webcam3.py的pan_tilt的XY事件控件。

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文件不会出现网络摄像头图像。

2 个答案:

答案 0 :(得分:0)

不确定这是否是导致问题的原因,但您的#!/bin/bash echo to argv[1] = $1 if [ -e $1 ] #exist the file then if [ -d $1 ] # is directory then if [ -r $1 ] #we can read then for k in $(ls $1) #all the files in the arv[1] do echo $k #print all the files of directory if [ -d $k ] then echo $k fi done fi fi fi gtk.threads_init()语句位置错误。它们应该是gtk.main()实例化的一侧,而不是在类定义中:

Application()

也许是因为你这样做:if __name__ == "__main__": gtk.gdk.threads_init() # Here, or immediately after the imports Application() gtk.main() 在GTK被正确初始化以允许线程之前,它会被卡在某处。

那就是说,似乎没有任何东西可以使用。在self.pan_tilt = servo_control.Servo(),但我从痛苦的经历中知道,GTK可以非常挑战线程。

答案 1 :(得分:0)

解决。经过大量的搜索,我找到了答案。 &#39; gst.parse_launch&#39;需要一个Source,它被送入一个传递给Sink的Filter。 &#39;来源 - &gt;过滤器 - &gt;水槽&#39 ;.在我的程序中,过滤器丢失了。一旦添加了代码函数。

所以改变这一行

{
  "presets": ["es2015"],
  "plugins": ["transform-function-bind"]
}

到这个

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

SiHa,谢谢你的评论