4

I trying to use openCV/c++ to capture the left and right image from a LI-USB30_V024 stereo camera without automatically converting it to RGB. The camera outputs images in YUYV format.

I have tried using videoCapture.set(CV_CAP_PROP_CONVERT_RGB, false) but I get the message "HIGHGUI ERROR: V4L: Property (16) not supported by device".

The reason I want to avoid the conversion to RGB is because the camera packages the left and right video together in to a single YUYV image. Both cameras are monochrome, and as far as I can tell the left image information is encoded in the Y channels while the right image is encoded in the U and V channels. For example if I run guvcview I get a single image that contains both the left and right images superpositioned. It looks like a black and white image (the left image is encoded in the Y channels) with a green and pink image lying on top (the right camera is encoded in the UV channels). I know this sounds pretty unusual so if you have any other ideas/questions about it then don't hesitate.

My goal is to capture the image as YUYV so that I can use split() to separate the left image (Y channels) from the right image (U and V channels) and display them both as monochrome images. However, once the image has been converted to RGB the luminance and chominance channels get blended together and it becomes impossible to separate the two images.

To sum it up, I need to capture the video without converting it to RGB so that the YUYV format is preserved. This will allow me to separate the left and right images.

OR I need a way of capturing the left and right images separately, but I think this is unlikely.

I think this would be possible in v4l, but I would prefer to only use openCV if possible.

Thanks!

Kozuch
  • 2,272
  • 3
  • 26
  • 38
titch
  • 101
  • 1
  • 1
  • 8
  • so u want it to convert to black and white? –  Dec 16 '14 at 02:48
  • or do u want to directly read it as grayscale –  Dec 16 '14 at 02:49
  • And convert it back to yuv wont work? – karlphillip Dec 16 '14 at 03:39
  • I have tried converting back to YUV and splitting the channels, but it doesn't quite work. The image formed from the Y channel is predominantly the left image, but there are still these ghostly shapes left over from the right image (and vice versa for the other image). I have a few ideas why that might be. Firstly, openCV is converting the image to a different sort of YUV. I dont know exactly which one it is, but there are only three channels as opposed to four. Secondly, could the YUYV->RGB conversion lose some information or irreversibly mix the luminance and chrominance information? – titch Dec 16 '14 at 03:55
  • I have just tried to convert back to YUYV using this formula: Y = 0.299R+0.587G+0.114B. I only found the Y value for each pixel since this should be enough to view just the left image. However there was still a left over ghost image from the right camera. Either my conversion was wrong or the YUYV->RGB conversion is not invertible. I got the formula here http://www.fourcc.org/fccyvrgb.php – titch Dec 16 '14 at 09:13

4 Answers4

3

I dont think there is a way to do this in openCV. In the end it wasn't too much trouble to capture frames with V4L2 and store them in openCV Mats.

titch
  • 101
  • 1
  • 1
  • 8
  • get any solution on windows? – flankechen Oct 15 '16 at 04:24
  • Sorry, I no longer have my old code. You might find this blog post useful though: https://jayrambhia.com/blog/capture-v4l2 – titch Mar 18 '19 at 22:25
  • Actually, I did find this old answer of mine to a related question: https://stackoverflow.com/questions/27820970/how-to-give-yuv-data-input-to-opencv/27914179?noredirect=1#comment44228820_27914179 – titch Mar 18 '19 at 22:35
0

I used to wrok on a camera which produce YUV420 data,and got some problem in configuring it. But this function works for me.

videoCapture.set(CV_CAP_PROP_CONVERT_RGB, 0)

Can you check if there is any other configuration that cause the problem.

TerryLu
  • 136
  • 1
  • 5
  • The question clearly states that this has been tried. – Hannes Ovrén Dec 16 '14 at 08:07
  • The only properties that that are supported are frame height, frame width, fps, and gain. All of the other property options give the message "property (x) is not supported by the device". I suppose the manufacturer didn't bother including those functionalities – titch Dec 16 '14 at 08:28
0

Yes you can do it but need build opencv c++ by urself

v4l2-ctl --list-formats #make sure your cam support yuyv

apt install libv4l-dev

source opencv 3.4.16

DWITH_GSTREAMER=OFF must off

cmake .. -G"Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/opt/opencv -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-O3 -g" -DCMAKE_CXX_FLAGS_RELEASE="-O3 -g" -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_JPEG=ON -DBUILD_PNG=ON -DBUILD_ZLIB=ON -DWITH_LIBV4L=ON -DBUILD_opencv_python3=ON -DBUILD_EXAMPLES=ON -DWITH_GSTREAMER=OFF -DWITH_CUDA=OFF
cmake --build . --config Release --target install -- -j$CPU_NUM VERBOSE=1

//try trace into cap_libv4l.cpp
cv::VideoCapture cap(0);
cap.set(CV_CAP_PROP_FRAME_WIDTH,    800);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,   600);
cap.set(CV_CAP_PROP_MODE,           CV_CAP_MODE_YUYV);

if ( cap.grab() )
{
            cv::Mat yuyv;
            cv::Mat cvimg;
            cap.retrieve(yuyv);
            cvtColor(yuyv,cvimg,CV_YUV2RGB_YUY2);
...
}

this way is ok I tried!!! and trace to 
static int _capture_V4L2 (CvCaptureCAM_V4L *capture, const char *deviceName)
~~~run to
  case CV_CAP_MODE_YUYV:
    requestedPixelFormat = V4L2_PIX_FMT_YUYV;
    break;

//no error
if (-1 == xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form)) {
      fprintf(stderr, "VIDEOIO ERROR: libv4l unable to ioctl S_FMT\n");
      return -1;
  }

/*If you wan to know how libv4l color convert look this
libv4l using c to convert color is slow
v4l2_ioctl
v4l2_dequeue_and_convert
v4lconvert_convert
v4lconvert_convert_pixfmt
https://github.com/philips/libv4l/blob/master/libv4lconvert/libv4lconvert.c
opencv can do cvtYUV422toRGB parallel faster than libv4l
https://forum.opencv.org/t/capture-rgb-frame-directly-using-open-cv-apis/4197/11
*/
-2

In header file videoio.hpp:

// Generic camera output modes.
// Currently, these are supported through the libv4l interface only.
enum { CAP_MODE_BGR  = 0, // BGR24 (default)
       CAP_MODE_RGB  = 1, // RGB24
       CAP_MODE_GRAY = 2, // Y8
       CAP_MODE_YUYV = 3  // YUYV
     };

Usage:

cv::VideoCapture camera = cv::VideoCapture();
camera.open(0);
camera.set(CV_CAP_PROP_MODE, CV_CAP_MODE_YUYV);