3

I am trying to convert an opencv image, generated from a webcam , to a virtual usb webcam using the v4l2 loopback following the example
https://gist.github.com/TimSC/6532334

The problem is that the function to convert the image to YUYV is really slow(about 500ms), so i want to convert using the function cv2.cvtColor but i can not find any way to convert in that format. I have try: 'COLOR_BGR2YCR_CB', 'COLOR_BGR2YUV', # 'COLOR_BGR2YUV_I420', 'COLOR_BGR2YUV_IYUV', 'COLOR_BGR2YUV_YV12'

The code

# install 
#git clone https://github.com/umlaeute/v4l2loopback.git
# cd v4l2looback
# make
#sudo make
#install v4l2 library sudo pip install v4l2
#run the driver
# sudo modprobe v4l2loopback
# it is based in:
#Send image data to v4l2loopback using python
#Remember to do sudo modprobe v4l2loopback first!
#Released under CC0 by Tim Sheerman-Chase, 2013

import fcntl, sys, os
from v4l2 import *
import time
#import scipy.misc as misc
import cv2
import math
import numpy as np

def ConvertToYUYV(sizeimage, bytesperline, im):
    padding = 4096
    buff = np.zeros((sizeimage+padding, ), dtype=np.uint8)
    imgrey = im[:,:,2] * 0.299 + im[:,:,1] * 0.587 + im[:,:,0] * 0.114
    Pb = im[:,:,2] * -0.168736 + im[:,:,1] * -0.331264 + im[:,:,0] * 0.5
    Pr = im[:,:,2] * 0.5 + im[:,:,1] * -0.418688 + im[:,:,0] * -0.081312

for y in range(imgrey.shape[0]):
        #Set lumenance
    cursor = y * bytesperline + padding
    for x in range(imgrey.shape[1]):
        try:
            buff[cursor] = imgrey[y, x]
        except IndexError:
            pass
        cursor += 2

        #Set color information for Cb
    cursor = y * bytesperline + padding
    for x in range(0, imgrey.shape[1], 2):
        try:
            buff[cursor+1] = 0.5 * (Pb[y, x] + Pb[y, x+1]) + 128
        except IndexError:
            pass
        cursor += 4

        #Set color information for Cr
    cursor = y * bytesperline + padding
    for x in range(0, imgrey.shape[1], 2):
        try:
            buff[cursor+3] = 0.5 * (Pr[y, x] + Pr[y, x+1]) + 128
        except IndexError:
            pass
        cursor += 4

return buff.tostring()

if __name__=="__main__":
devName = '/dev/video1'
if len(sys.argv) >= 2:
    devName = sys.argv[1]
width = 640
height = 480
if not os.path.exists(devName):
    print "Warning: device does not exist",devName
device = open(devName, 'wr')

print(device)
capability = v4l2_capability()
print "get capabilities result", (fcntl.ioctl(device, VIDIOC_QUERYCAP, capability))
print "capabilities", hex(capability.capabilities)

fmt = V4L2_PIX_FMT_YUYV
# testar http://linuxtv.org/downloads/v4l-dvb-apis/pixfmt.html
fmt = V4L2_PIX_FMT_YVU420
    #fmt=V4L2_PIX_FMT_SGBRG8 

print("v4l2 driver: " + capability.driver)
format = v4l2_format()
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT
format.fmt.pix.pixelformat = fmt
format.fmt.pix.width = width
format.fmt.pix.height = height
format.fmt.pix.field = V4L2_FIELD_NONE
format.fmt.pix.bytesperline = width * 2
format.fmt.pix.sizeimage = width * height * 2
format.fmt.pix.colorspace = V4L2_COLORSPACE_JPEG

print "set format result", (fcntl.ioctl(device, VIDIOC_S_FMT, format))

    # Camera 0 is the integrated web cam on my netbook
camera_port = 0 
camera = cv2.VideoCapture(camera_port)

while True:
    retval, im = camera.read()
        #print im.shape     
        #im = cv2.imread('original.bmp')
    gray = cv2.cvtColor(im,cv2.COLOR_BGR2YCR_CB)     #COLOR_YUV2RGBA_YUYV COLOR_GRAY2BGR COLOR_BGR2GRAY
        #possibilities
#       'COLOR_BGR2BGRA', 'COLOR_BGR2GRAY', 'COLOR_BGR2HLS', 'COLOR_BGR2HLS_FULL', 'COLOR_BGR2HSV', 'COLOR_BGR2HSV_FULL',     # 'COLOR_BGR2LAB', 'COLOR_BGR2LUV', 'COLOR_BGR2RGB', 'COLOR_BGR2RGBA', 'COLOR_BGR2XYZ', 'COLOR_BGR2YCR_CB', 'COLOR_BGR2YUV',     #    'COLOR_BGR2YUV_I420', 'COLOR_BGR2YUV_IYUV', 'COLOR_BGR2YUV_YV12', 'COLOR_BGR5552BGR'
    cv2.imshow("converted",gray)        
        #gray = ConvertToYUYV(format.fmt.pix.sizeimage, format.fmt.pix.bytesperline, im)
    device.write(gray)

    time.sleep(1./30.)
del(camera)
olmerg
  • 425
  • 4
  • 6
  • 1
    why do you think you need to convert to YUV? why can't you just use the original format? – umläute Aug 27 '15 at 13:32
  • I have try to send the original one, changing the format of the driver but I get a black image or a different image in the new webcam. I need to send in the format that I configure in `fmt = V4L2_PIX_FMT_YUYV` – olmerg Aug 28 '15 at 00:01
  • @olmerg: i tried to change the format during sending with ffmpeg - and i did not succeed. - i have the feeling that only the first time you sending something to the v4l2loopback device it sets the format. after this i did not get it to change again. (until restart) but i haven't looked closer into this.. – Stefan Krüger s-light Feb 22 '17 at 16:19

0 Answers0