2013-10-21 14 views
14

Hem OpenCV hem de PyAudio çalışmalarını aldım ancak bunları nasıl senkronize edeceğimi bilmiyorum. OpenCV'den bir framerate alamıyorum ve bir an için bir an için değişiklik gösteren çağrı süresini ölçemiyorum. Ancak PyAudio ile temel, belirli bir örnekleme oranını tutmaktadır. Onları aynı hızda nasıl senkronize edebilirim? Bazı standart ya da bazı kodeklerin var olduğunu varsayalım. (Ben tüm google denedim dudak senkronizasyonu hakkında bilgi oldu: /).Ses ve videoyu OpenCV ve PyAudio ile senkronize etme

OpenCV Kare hızı

from __future__ import division 
import time 
import math 
import cv2, cv 

vc = cv2.VideoCapture(0) 
# get the frame 
while True: 

    before_read = time.time() 
    rval, frame = vc.read() 
    after_read = time.time() 
    if frame is not None: 
     print len(frame) 
     print math.ceil((1.0/(after_read - before_read))) 
     cv2.imshow("preview", frame) 

     if cv2.waitKey(1) & 0xFF == ord('q'): 
      break 

    else: 
     print "None..." 
     cv2.waitKey(1) 

# display the frame 

while True: 
    cv2.imshow("preview", frame) 

    if cv2.waitKey(1) & 0xFF == ord('q'): 
     break 

from sys import byteorder 
from array import array 
from struct import pack 

import pyaudio 
import wave 

THRESHOLD = 500 
CHUNK_SIZE = 1024 
FORMAT = pyaudio.paInt16 
RATE = 44100 

def is_silent(snd_data): 
    "Returns 'True' if below the 'silent' threshold" 
    print "\n\n\n\n\n\n\n\n" 
    print max(snd_data) 
    print "\n\n\n\n\n\n\n\n" 
    return max(snd_data) < THRESHOLD 

def normalize(snd_data): 
    "Average the volume out" 
    MAXIMUM = 16384 
    times = float(MAXIMUM)/max(abs(i) for i in snd_data) 

    r = array('h') 
    for i in snd_data: 
     r.append(int(i*times)) 
    return r 

def trim(snd_data): 
    "Trim the blank spots at the start and end" 
    def _trim(snd_data): 
     snd_started = False 
     r = array('h') 

     for i in snd_data: 
      if not snd_started and abs(i)>THRESHOLD: 
       snd_started = True 
       r.append(i) 

      elif snd_started: 
       r.append(i) 
     return r 

    # Trim to the left 
    snd_data = _trim(snd_data) 

    # Trim to the right 
    snd_data.reverse() 
    snd_data = _trim(snd_data) 
    snd_data.reverse() 
    return snd_data 

def add_silence(snd_data, seconds): 
    "Add silence to the start and end of 'snd_data' of length 'seconds' (float)" 
    r = array('h', [0 for i in xrange(int(seconds*RATE))]) 
    r.extend(snd_data) 
    r.extend([0 for i in xrange(int(seconds*RATE))]) 
    return r 

def record(): 
    """ 
    Record a word or words from the microphone and 
    return the data as an array of signed shorts. 

    Normalizes the audio, trims silence from the 
    start and end, and pads with 0.5 seconds of 
    blank sound to make sure VLC et al can play 
    it without getting chopped off. 
    """ 
    p = pyaudio.PyAudio() 
    stream = p.open(format=FORMAT, channels=1, rate=RATE, 
     input=True, output=True, 
     frames_per_buffer=CHUNK_SIZE) 

    num_silent = 0 
    snd_started = False 

    r = array('h') 

    while 1: 
     # little endian, signed short 
     snd_data = array('h', stream.read(1024)) 
     if byteorder == 'big': 
      snd_data.byteswap() 

     print "\n\n\n\n\n\n" 
     print len(snd_data) 
     print snd_data 

     r.extend(snd_data) 

     silent = is_silent(snd_data) 

     if silent and snd_started: 
      num_silent += 1 
     elif not silent and not snd_started: 
      snd_started = True 

     if snd_started and num_silent > 1: 
      break 

    sample_width = p.get_sample_size(FORMAT) 
    stream.stop_stream() 
    stream.close() 
    p.terminate() 

    r = normalize(r) 
    r = trim(r) 
    r = add_silence(r, 0.5) 
    return sample_width, r 

def record_to_file(path): 
    "Records from the microphone and outputs the resulting data to 'path'" 
    sample_width, data = record() 
    data = pack('<' + ('h'*len(data)), *data) 

    wf = wave.open(path, 'wb') 
    wf.setnchannels(1) 
    wf.setsampwidth(sample_width) 
    wf.setframerate(RATE) 
    wf.writeframes(data) 
    wf.close() 

if __name__ == '__main__': 
    print("please speak a word into the microphone") 
    record_to_file('demo.wav') 
    print("done - result written to demo.wav") 
+1

Çalışan bir "pyffmpeg" kurulu olması durumunda, video görüntüleme için OpenCV kullanmak yerine 'ffmpeg''in video (ve ses) görüntüleme özelliklerini kullanmayı deneyebilirsiniz. – boardrider

cevap

1

Sana GSreamer veya ffmpeg veya Windows üzerinde iseniz, DirectShow kullanarak daha iyi olurdu düşünmek ses kapma ve kaydetme. Bu lib'ler hem ses hem de video ile başa çıkabilir ve video ve sesleri düzgün bir şekilde karıştırmanızı sağlayacak bir Çoklayıcıya sahip olmalıdır.

Gerçekten de bunu Opencv kullanarak yapmak istiyorsanız, VideoCapture'u kare hızını kullanabilmeniz gerekir, this kullanmayı denediniz mi?

before_read = time.time() 
rval, frame = vc.read() 
after_read = time.time() 
: Ben burada yapmaya çalıştıkları şey anlayamadım

nFrames = cv.GetCaptureProperty(vc, CV_CAP_PROP_FRAME_COUNT) 
      cv.SetCaptureProperty(vc, CV_CAP_PROP_POS_AVI_RATIO, 1) 
duration = cv.GetCaptureProperty(vc, CV_CAP_PROP_POS_MSEC) 
fps = 1000 * nFrames/duration; 

:

fps = cv.GetCaptureProperty(vc, CV_CAP_PROP_FPS) 

başka yolu da süresi bölü kare sayısı olarak fps tahmin etmek olurdu

after_read - before_read yapmanın sadece OpenCV'nin bir sonraki kareyi yüklemek için ne kadar sürdüğünü ölçtüğüne inanıyor, fps değerini ölçemiyor. OpenCV oynatmaya çalışmıyor, sadece kareleri yüklüyor ve bunu olabildiğince hızlı bir şekilde yapmaya çalışacağım ve bunu yapılandırmanın bir yolu olmadığını düşünüyorum. Her bir kareyi görüntüledikten sonra bir waitKey(1/fps) koyduğunuzu, aradığınız şeyi elde edeceğini düşünüyorum.

+0

@ Zimm3r Çalışıyor mu? –

+0

Bu çok geç olsa da, GStreamer'ı kullanmak istediğim özel hedefler olduğu ve GStreamer ile geçmişte sorun yaşadığı için kullanmamıştım. – Zimm3r

İlgili konular