Reputation: 51
I want to process videos using a blackMagic card. The first step is obviously capturing frame but I don't know how to do it. I tried to use the usual opencv code to detect the cam and display frames but it didn't work. Does anybody know something about it?
Thank you
This is my code:
I'm recording there, but it's ok, that's not the main thing I want to do I created a class to be able to set the properties of a webcam, but I don't think it is right to do it with this way with BMCC
from Capture import Capture
import cv2
import os
from src import improcess
# video recorder
capture = cv2.VideoCapture(1)
cap = Capture(capture)
fourcc = cv2.cv.CV_FOURCC(*'MSVC') # cv2.VideoWriter_fourcc() does not exist
video_writer = cv2.VideoWriter("C:\Users\Syllia\Videos\output3.avi", fourcc, 30.0, (640, 480))
i = 0
cap.set_brightness(25)
while(capture.isOpened()):
# Capture frame-by-frame
ret, frame = cap.cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if(i==120):
cap.adjust_brightness(100, frame)
if i >= 240 and i<360:
frame = improcess.binarize(170, frame)
if i>360:
frame = gray
video_writer.write(frame)
cv2.imshow('frame',frame)
i = i+1
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
video_writer.release()
capture.release()
cv2.destroyAllWindows()
Upvotes: 1
Views: 6987
Reputation: 1
What I did was create a command using FFMPEG tool something like this takes the stream for a BlackMagic Video Recorder and only take 120 frames in format YUV 4:2:0 with a 60 fps:
"C:\ffmpeg\bin\ffmpeg.exe" -y -f dshow -video_size 1920x1080 -r 60 -i video="Blackmagic WDM Capture" -c:v rawvideo -pix_fmt yuv420p -frames:v 120 myVideoTest.avi
You can find the video source using this command:
ffmpeg -list_devices true -f dshow -i dummy
Here is some explanation of the arguments:
-y Overwrite existing video file (Counterpart is -n)
-f Force the format (Ex: dshow)
-r Frames Per Second (Ex: 60)
-c:v Codec Output to "copy" this means, no encoding process
-pix_fmt Pixel Format to YUV (Ex: yuv420p)
-frames:v Number of frames to Output (Ex: 120)
Also I note a issue that FFMPEG does not cleary terminate on Windows, for that I use taskkill /im ffmpeg.exe /t /f
Upvotes: 0
Reputation: 16
I had the same problem. I solved it encoding the frame using python-vlc library overriding libvlc_video_set_callbacks and then using the frame already converted in numpy format using opencv.
This is the code:
import vlc,cv2
import ctypes
import time
import sys
import numpy as np
from PIL import Image
pl = vlc.MediaPlayer('dshow://')
VIDEOWIDTH = 1280
VIDEOHEIGHT = 720
# size in bytes when RV32
size = VIDEOWIDTH * VIDEOHEIGHT * 4
# allocate buffer
buf1 = (ctypes.c_ubyte * size)()
buf2 = (ctypes.c_ubyte * size)()
# get pointer to buffer
buf_p = ctypes.cast(buf1, ctypes.c_void_p)
# global frame (or actually displayed frame) counter
framenr = 0
test=[]
# vlc.CallbackDecorators.VideoLockCb is incorrect
CorrectVideoLockCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p))
@CorrectVideoLockCb
def _lockcb(opaque, planes):
print "lock"
planes[0] = buf_p
ctypes.memmove(buf2, buf1, size)
#time.sleep(1)
@vlc.CallbackDecorators.VideoDisplayCb
def _display(opaque, picture):
global framenr,test
img = Image.frombuffer("RGBA", (VIDEOWIDTH, VIDEOHEIGHT), buf2, "raw", "BGRA", 0, 1)
#img.save('img{}.png'.format(framenr))
#print "display {}".format(framenr)
# shouldn't do this here! copy buffer fast and process in our own thread, or maybe cycle
# through a couple of buffers, passing one of them in _lockcb while we read from the other(s).
#img.save('img{}.png'.format(framenr))
#img=cv2.cvtColor(np.array(img), cv2.COLOR_BGRA2RGB)
frame_CV=np.array(img)
framenr+=1
print "frame",framenr,frame_CV.shape
test=frame_CV
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(test,"Test",(50,50), font, 0.7,(250,20,30),1,cv2.LINE_AA)
#cv2.imshow("Test",test)
#cv2.waitKey(1)
#if framenr==10:
#cv2.imshow("Test",test)
#print "OpenCV"
#------------------------------------------------------------------------------
# MAIN CYCLE
#------------------------------------------------------------------------------
vlc.libvlc_video_set_callbacks(pl, _lockcb, None, _display, None)
pl.video_set_format("RV32", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH * 4)
pl.play()
#10 seconds are necessary to consolidate memory buffer exchange and library
#syncronization
time.sleep(10)
while True:
cv2.imshow("Test",test)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
pl.stop()
cv2.destroyAllWindows()
#time.sleep(10)
#------------------------------------------------------------------------------
Upvotes: 0
Reputation: 1084
The OpenCV video capture functionality does not support Blackmagic devices (probably). I use the Blackmagic Decklink SDK for capturing Blackmagic cameras. You can find and download it at the Blackmagic support site: Blackmagic design support.
Please note that it does not support Python nor OpenCV interfacing but there are C++ cross-platform examples including Windows MFC ones. Further note that the (color) pixel formats are probably not the same as for OpenCV if I recall correctly: you need to convert them yourselves if you want to do further image processing.
Upvotes: 1