Запись timeback секунд видео, основанные на сравнении пикселей из изображения


Код считывает с экрана, сравнивает пиксель в ранее представленном образце изображения и, если пиксели матч, он записывает timeback секунд видео, ведущей к нему. На выходе в папке 'ТМ'. Поскольку я не предполагаю пикселя происходит все время, процесс написания буферизированный поток, чтобы не тормозить процесс захвата. Фотографии в папке 'ТМ' может в конце концов быть объединены, чтобы составить сокращенный фильм, содержащий все кадры с пиксель на месте.

Я даже не знаю, с чего начать оптимизацию. Что я должен улучшить в плане читабельности и скорости?

import PIL.ImageGrab
import PIL.Image
import time
from collections import deque
import threading 
from numpy import *

def get_pixel_colour(i_x, i_y):
    return PIL.ImageGrab.grab().load()[i_x, i_y]

class framebuffer:
    def __init__(self,size):
        self.buffer = deque(maxlen=size)
        self.i= 0
    def add_frame(self, frame):
        self.buffer.append(frame)
    def remove_frame(self):
        return self.buffer.popleft()
    def write_frame(self):
        x = self.buffer.popleft()
        self.i+=1
        x.save("tm\screengrab"+ str(self.i).zfill(10) +".jpg")
        print "tm\screengrab"+ str(self.i).zfill(10) +".jpg written, ", len(self.buffer), "to go " 
    def is_empfty(self):
        return (len(self.buffer)>0)

class mythread(threading.Thread):
    def run (self):
        while(True):
            if (len(self.frameb.buffer) > 0):
                self.frameb.write_frame()
            else:
                time.sleep(1)
    def setbuffer(self,frameb):
            self.frameb = frameb


seedimage = PIL.Image.open("seed.bmp") 
pos_x = 983
pos_y = 263
recpixel = seedimage.load()[pos_x, pos_y]
print "The pixel is now", recpixel
fps = 50
skipticks = 1/(fps*1.0)
i= 0
timeback = fps * 3
allframes=framebuffer(timeback)
nextsnap=time.clock()
recordframes = framebuffer(None)
t= mythread()
t.setbuffer(recordframes)


print 'Starting thread'
t.setDaemon(True)
t.start()
print 'starting program'
print skipticks, fps
while (True):
    tim= time.clock()
    i=i+1
    x = PIL.ImageGrab.grab()  
    allframes.add_frame(x)
    imp_pixel = x.load()[pos_x, pos_y]
    r, i = array(recpixel),array(imp_pixel)
    if (sum(r-i)<1 and sum(r-i)>-1 ):
        print "recognized", sum(r-i),"with size:", len(allframes.buffer)
        recordframes.buffer.extend(allframes.buffer)
        allframes.buffer.clear()
        sleep(10)

    # this is the sleep that limits the fps
    nextsnap+=skipticks
    sleeptime = nextsnap-time.clock()
    if (sleeptime>0):
        time.sleep (sleeptime)


487
0
задан 11 декабря 2011 в 10:12 Источник Поделиться
Комментарии
1 ответ

import PIL.ImageGrab
import PIL.Image
import time
from collections import deque
import threading
from numpy import *

Как правило, импорт * не одобряется, потому что это делает его трудно, чтобы выяснить, где вещи приходят фром

def get_pixel_colour(i_x, i_y):
return PIL.ImageGrab.grab().load()[i_x, i_y]

Вам не кажется, что на самом деле использовать эту функцию

class framebuffer:

Руководство по стилю Python рекомендует верблюжьего для имен классов

    def __init__(self,size):
self.buffer = deque(maxlen=size)
self.i= 0

я это любопытное трудно догадаться для чего.

    def add_frame(self, frame):
self.buffer.append(frame)
def remove_frame(self):
return self.buffer.popleft()

Вы никогда не использовать этот метод

    def write_frame(self):
x = self.buffer.popleft()
self.i+=1
x.save("tm\screengrab"+ str(self.i).zfill(10) +".jpg")
print "tm\screengrab"+ str(self.i).zfill(10) +".jpg written, ", len(self.buffer), "to go "
def is_empfty(self):

Неправильно написали имя и никогда не использовал

        return (len(self.buffer)>0)

Вам не нужны скобки вокруг всего выражения

class mythread(threading.Thread):
def run (self):
while(True):

Нет нужды в этих скобок. Пусть ваше дыхание жетоны

            if (len(self.frameb.buffer) > 0):

Его странно, что вы определяете функцию is_empfty, но не называют его.

                self.frameb.write_frame()
else:
time.sleep(1)

Python имеет очереди.Класса очереди, которая реализует потокобезопасную очередь. Это будет получше, то список, потому что ее гарантированно будет потокобезопасным. Также, если вы пытаетесь поп из пустой очереди и будете ждать, пока элемент помещается в очередь. Таким образом, вам не нужно делать время.Sleep() и цикл здесь

    def setbuffer(self,frameb):

Руководство по стилю Python рекомендует имена, как set_buffer

            self.frameb = frameb

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

seedimage = PIL.Image.open("seed.bmp") 
pos_x = 983
pos_y = 263

Вместо этого, сохраняя позицию как кортеж? Вы можете проезжать кортеж для индексации массивов

recpixel = seedimage.load()[pos_x, pos_y]
print "The pixel is now", recpixel
fps = 50
skipticks = 1/(fps*1.0)
i= 0

Каких-либо сложную логику, как это должно быть в функции. Это будет несколько быстрее.

timeback = fps * 3
allframes=framebuffer(timeback)
nextsnap=time.clock()
recordframes = framebuffer(None)
t= mythread()
t.setbuffer(recordframes)

print 'Starting thread'
t.setDaemon(True)
t.start()

Я бы сделал, по крайней мере, setDaemon вместо резьбы. (И вы действительно поток Деамон?)

print 'starting program'
print skipticks, fps
while (True):
tim= time.clock()
i=i+1

польза для меня в itertools.граф(): вместо цикла while, и вы хотите, чтобы вручную отслеживать я

    x = PIL.ImageGrab.grab()  
allframes.add_frame(x)

избегайте имен, таких как X. Делает его трудно следовать ваш код

    imp_pixel = x.load()[pos_x, pos_y]
r, i = array(recpixel),array(imp_pixel)

Это переопределение свой предыдущий я, предполагая, что это не было действительно достаточно важной, чтобы отслеживать в любом случае

    if (sum(r-i)<1 and sum(r-i)>-1 ):

Python имеет синтаксис -1 < сумма(Р-1) < 1 что лучше для такого рода вещи

        print "recognized", sum(r-i),"with size:", len(allframes.buffer)
recordframes.buffer.extend(allframes.buffer)

Почему бы вам не сделать allframes список? Он не использует какие-либо другие поведения класса, который вы сделали.

        allframes.buffer.clear()
sleep(10)

Я не знаю, почему вы спите здесь

    # this is the sleep that limits the fps
nextsnap+=skipticks
sleeptime = nextsnap-time.clock()
if (sleeptime>0):
time.sleep (sleeptime)

Обратите внимание, что время.сон не очень точны, как время идет.

0
ответ дан 12 декабря 2011 в 05:12 Источник Поделиться