Повторение кадра при обнаружении движения (или вычитании фона) - PullRequest
0 голосов
/ 09 июля 2020

Я пытался сделать обнаружение движения, которое можно просто сделать, взяв разницу в последовательности кадров в видео. Поскольку я изучаю основы обработки изображений, я не хочу использовать opencv для каких-либо задач обработки ; Я просто использую его для чтения изображений. Я попытался вычислить математическую разницу изображений, и это дало мне хорошие результаты: всего img = current_img - prev_img соответствующих кадров. Но так как он давал слишком много лагов, я попробовал его с помощью pyopencl . Теперь проблема, которую я получаю, показана ниже. Уравнение или операция с изображением простым вычитанием для каждого пикселя. Но я получаю повторяющиеся кадры prevImg.

Результат, который я получаю:

Чтобы увидеть, что на самом деле происходит, я скопировал входные изображения в выводить один за другим, т.е. output[index] = currImg[index] и более поздние output[index] = prevImg[index], которые дали мне следующие результаты:

вывод копирования "currImg"

вывод копирования " prevImg "

Вот кое-что запутанное. Оба изображения, currImg и prevImg, имеют одинаковые размеры и тип данных. В чем может быть причина такого повторения при копировании prevImg?

Вот мои коды ...

Python Код :

import cv2
import pyopencl as cl
import numpy as np
from time import time


def derivate(p,d,now,prev,t):

    #input data
    curr = np.asarray(now).astype(np.int32)
    pre  = np.asarray(prev).astype(np.int32)

    #opencl platform-device-context-queue
    platform = cl.get_platforms()[p]
    device = platform.get_devices()[d]
    cntx = cl.Context([device])
    queue = cl.CommandQueue(cntx)

    #memory flags
    mf = cl.mem_flags

    #creating input and output buffers
    currImg = cl.Buffer(cntx,mf.READ_ONLY | mf.COPY_HOST_PTR,hostbuf=curr)
    prevImg = cl.Buffer(cntx,mf.READ_ONLY | mf.COPY_HOST_PTR,hostbuf=prev)
    output = cl.Buffer(cntx,mf.WRITE_ONLY,curr.nbytes)

    #reading kernel file
    kernel = open("F:\Image processing\derivative\kernel.c").read()

    #creating a opencl program
    program = cl.Program(cntx,kernel%(w,t)).build()

    #running the actual computation with required params for the kernel
    program.derive(queue,curr.shape,None,currImg,prevImg,output)

    #empty space result
    result = np.empty_like(curr)

    #copying results
    cl.enqueue_copy(queue,result,output)

    #conversion to image compatible types
    result = result.astype(np.uint8)

    #return result
    return np.array(result)


if __name__ == "__main__":
    vid = cv2.VideoCapture("F:\Image processing\Edge\Video.mp4")
    global w,h
    w = int(vid.get(3))
    h = int(vid.get(4))
    print(w,h)

    #empty initializing
    prev = np.zeros((h,w))
    prev = prev.astype(np.int32)
    t = 1
    while(vid.isOpened()):
        s = time()
        ret,frame = vid.read()
        #read current frame
        curr = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY).astype(np.uint8)
        #generate derivative of current and previous image
        img = derivate(0,0,curr,prev,t)
        cv2.imshow("out",img)
        #store current frame as previous for next iteration
        prev = curr
        e = time()
        # t = (e - s)
        print(t)
        if cv2.waitKey(10) & 0xff == 27:
            break

Код ядра :

__kernel void derive(__global int *currImg,__global int *prevImg,__global int *output){
    int i = get_global_id(0);
    int j = get_global_id(1);

    int w = %d;
    int t = %d;
    int index = i*w + j;

    output[index] = (currImg[index] - prevImg[index])/t; //copying of individual images was done on this line for debugging purpose 

}

...