[opencv4tegra] Changing camera resolution [solved]

hi everyone,

Has anybody tried to change the resolution of the videocapture device (ie a camera) using the CV_CAP_PROP_FRAME_WIDTH and CV_CAP_PROP_FRAME_HEIGHT arguments to the set property function in opencv?
I am able to stream only VGA from the camera.

I’m using opencv4tegra 2.4.12 on a Jetson TK1 running L4T 21.2. I tried the following code.

//Build using g++ opencv.cpp `pkg-config --cflags --libs opencv`
#include "opencv2/opencv.hpp"

using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())
        return -1;
    cap.set(CV_CAP_PROP_FRAME_WIDTH,1280);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,720);

    namedWindow("Preview",1);
    Mat frame;
    for(;;)
    {
        cap >> frame; // get a new frame from camera
        imshow("Preview", frame);
        if(waitKey(2) >= 0) break;
    }
    return 0;
}

I tried this code using a few USB cameras. I have made sure that the cameras support 1280x720 resolution. But its not working. In fact I am able to use only 640x480 resolution.

Can someone verify that this is a bug in opencv4tegra or if I am doing something wrong?

Hi dilipkumar25,

Thanks for reporting the issue, we are currently investigating the case and we’ll let you know when we have an update.
In the meantime, you can try using Gstreamer command for frame size, please refer to
https://devtalk.nvidia.com/default/topic/904949/post/4787122/#4787122

Thanks

Hi kayccc,

Thanks for the info. I tried out your suggestion to use gstreamer in opencv. This is my modified code.

//Build using g++ opencv.cpp `pkg-config --cflags --libs opencv`
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

int main(int, char**)
{
    const char* env = "GST_DEBUG=*:3";
    putenv((char*)env);
    const char* gst = "v4l2src device=/dev/video0 queue-size=4 always-copy=false ! image/jpeg, width=(int)1280, height=(int)720 ! jpegdec ! ffmpegcolorspace ! video/x-raw-rgb ! appsink";
    VideoCapture cap(gst);
    if(!cap.isOpened())
    {
        cout << "cant open camera" << endl;
        return -1;
    }

    namedWindow("Preview",1);
    Mat frame;
    for(;;)
    {
        cap >> frame; // get a new frame from camera
        imshow("Preview", frame);
        if(waitKey(2) >= 0) break;
    }
    return 0;
}

The camera fails to initialize. ie. fails at cap.isOpened(). I also checked the system calls and the device node is not even opened. Am I missing something?

Also the same gstreamer pipeline works fine when I tested it using gst-launch-0.10. I was wondering if opencv4tegra is built with gstreamer support. So I made a few tests.

ubuntu@tegra-ubuntu:~$ ldd /usr/lib/libopencv_highgui.so | grep gst

The above command returns nothing. This shows that opencv4tegra is built without gstreamer support. To further verify this I built opencv 2.4.9 with gstreamer support.

ubuntu@tegra-ubuntu:~$ ldd /usr/local/lib/libopencv_highgui.so | grep gst
	libgstreamer-0.10.so.0 => /usr/lib/arm-linux-gnueabihf/libgstreamer-0.10.so.0 (0xb6429000)
	libgstapp-0.10.so.0 => /usr/lib/arm-linux-gnueabihf/libgstapp-0.10.so.0 (0xb641e000)
	libgstvideo-0.10.so.0 => /usr/lib/arm-linux-gnueabihf/libgstvideo-0.10.so.0 (0xb6403000)
	libgstbase-0.10.so.0 => /usr/lib/arm-linux-gnueabihf/libgstbase-0.10.so.0 (0xb5154000)

And the above code I posted also works fine with my custom built version opencv with gstreamer support.

Hence, the option of using gstreamer with opencv4tegra is also out of the question. Is there any other method to use a camera in opencv4tegra at any resolution I choose?

I am also having issues getting the full resolution out of my usb camera. Did you end up solving your issue?

Until this issue is fixed in opencv4tegra, I did a workaround to use higher resolutions from the camera. I use v4l2 ioctls directly to grab the frame from the camera and then use the Mat constructor to load the buffer into an opencv data type (Mat). Then I do the appropriate colorspace conversion to BGR before doing any processing on the buffer.

Mat yuyv_frame = Mat(CAM_HEIGHT,CAM_WIDTH,CV_8UC2,ptr_cam_frame);
cvtColor(yuyv_frame,bgr_frame,COLOR_YUV2BGR_YUY2);

This works fine for me.

All,

We were having a similar problem with a third party USB3 video camera. We fixed it with help from the camera manufacturer. Details are on this website:

http://www.e-consystems.com/opencv-jetson-using-13MP-MIPI-camera.asp

Most of the fixes detailed on that website should apply to any camera talking thru OpenCV, not just the eCon Systems cameras.

One add’l trick we needed to access the absolute highest resolution provided by the camera (4224x3156) was to add

vmalloc=384M

to the end of /boot/extlinux/extlinux.conf

This was needed to increase kernel memory to accommodate the very large bufferrs needed for the highest camera resolution.

-Tim

Is there an official update on the way? thx

Hi rffLow,

The fix for opencv4tegra in TK1 is still under planning, no firm date yet.
Have you tried the suggestion from “SpaceVRTimD” to see if it can help by increase the vmalloc size?

Thanks

Hi dilipkumar25,
I try to build opencv with gst but when I use ldd to track ,it shows nothing .could you please post the method to enable the gst in opencv?

The opencv4tegra version provided by Nvidia does not support gstreamer. I’m not sure about the latest one though (2.4.13). You will have to build opencv from source code. Refer to the following links to build opencv from source:

http://elinux.org/Jetson/Installing_OpenCV

I successfully build .thanks.

Just to confirm, I have a Logitech 615 USB cam. Are you saying that I cannot get greater than 640 x 480 out of the box on the NVIDIA TK1? (I’m using a 2.0 USB hub)

How would this work-around look in Python?

I have the same problem as you.
Can you tell more details about how to solve this problem?
Thank you very much!

ccchen