<p>Your issue is probably that you don't have enough USB bandwidth available, if your webcams support it switch to MJPEG instead of uncompressed frames. Usually any webcam supports MJPEG encoding to deliver frames to your PC.</p>

<p>Here a similar question on SO <a href="https://stackoverflow.com/questions/9781770/capturing-multiple-webcams-uvcvideo-with-opencv-on-linux">https://stackoverflow.com/questions/9781770/capturing-multiple-webcams-uvcvideo-with-opencv-on-linux</a></p>

CC BY-SA 3.0
2014-09-02T18:41:32.383Z
2014-09-02T18:41:32.383Z
2017-05-23T11:33:38.633Z
timonsku
<p>I am fairly certain you are getting the corruption because of the usleep(100000); - This is based on the fact I have achieved similar corruption using one webcam by adding usleep(100000) to my code.</p>

<p>My usleep(100000); is substitution for running an opencl kernel, meaning this point I know the problem is that the usleep(100000) affects the video frame delivery in some way (this happens in my code if I strip out all other code, and just save the frames to disk as ppm files).</p>

<p>What I don't know is why ....</p>

<p>I can put the usleep anywhere in my code, the affect is always the same.</p>

<p>Perhaps the video4linux webcam code needs to be on a different pthread ..</p>

CC BY-SA 3.0
2016-07-01T15:31:47.157Z
2016-07-01T15:31:47.157Z
user536489
<p>I would like to grab images from multiple cameras under linux. I followed <a href="http://linuxtv.org/downloads/presentations/summit_jun_2010/20100206-fosdem.pdf" rel="nofollow noreferrer">this presentation</a> used the code and enhanced it for my purpose. It works very well for 1 camera.</p>

<p><img src="https://i.sstatic.net/ORkXX.png" alt="Saved image from the carema using v4l2 and libpng">
Once I begin to grab images from multiple cameras (successively) I get corrupt images.
<img src="https://i.sstatic.net/u4DCQ.png" alt="Corrupt image when grabbing picture from multiple cameras">
The more cameras I sue the more artefacts/stripes in the images appear. It does not make any difference if I save the images as BMP using another code. So I assume the problem has nothing to do with the storing routine. The resolution is also right (744 * 480).</p>

<p>The result is the same on two different computers running Fedora and Debian. I am absolutely baffled and can not find any clue what is going wrong. Could me please someone give some hints ?</p>

<p>Here is my code</p>

<pre><code>int main()
{
    /* #################### INIT #################### */

    int numOfCameras = 1;
    int xRes = 744;
    int yRes = 480;
    int exposure = 2000;
    unsigned int timeBetweenSnapshots = 2; // in sec
    char fileName[sizeof "./output/image 000 from camera 0.PNG"];

    static const char *devices[] = { "/dev/video0", "/dev/video1", "/dev/video2", "/dev/video3", "/dev/video4", "/dev/video5", "/dev/video6", "/dev/video7" };

    struct v4l2_capability cap[8];
    struct v4l2_control control[8];
    struct v4l2_format format[8];
    struct v4l2_requestbuffers req[8];
    struct v4l2_buffer buffer[8];

    int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // had to declare the type here because of the loop

    unsigned int i;
    unsigned int j;
    unsigned int k;

    int fd[8];
    void **mem[8];

    /* #################### OPEN DEVICE #################### */

    for (j = 0; j &lt; numOfCameras; ++j) {

        fd[j] = open(devices[j], O_RDWR);
        ioctl(fd[j], VIDIOC_QUERYCAP, &amp;cap[j]);


        /* #################### CAM CONTROLL #################### */

        control[j].id = V4L2_CID_EXPOSURE_AUTO;
        control[j].value = V4L2_EXPOSURE_SHUTTER_PRIORITY;
        ioctl(fd[j], VIDIOC_S_CTRL, &amp;control[j]);

        control[j].id = V4L2_CID_EXPOSURE_ABSOLUTE;
        control[j].value = exposure;
        ioctl(fd[j], VIDIOC_S_CTRL, &amp;control[j]);

        /* #################### FORMAT #################### */

        ioctl(fd[j], VIDIOC_G_FMT, &amp;format[j]);
        format[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        format[j].fmt.pix.width = xRes;
        format[j].fmt.pix.height = yRes;
        //format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        format[j].fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
        ioctl(fd[j], VIDIOC_S_FMT, &amp;format[j]);

        /* #################### REQ BUF #################### */

        req[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req[j].count = 4;
        req[j].memory = V4L2_MEMORY_MMAP;
        ioctl(fd[j], VIDIOC_REQBUFS, &amp;req[j]);
        mem[j] = malloc(req[j].count * sizeof(*mem));

        /* #################### MMAP #################### */

        for (i = 0; i &lt; req[j].count; ++i) {
            buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer[j].memory = V4L2_MEMORY_MMAP;
            buffer[j].index = i;
            ioctl(fd[j], VIDIOC_QUERYBUF, &amp;buffer[j]);
            mem[j][i] = mmap(0, buffer[j].length,
                    PROT_READ|PROT_WRITE,
                    MAP_SHARED, fd[j], buffer[j].m.offset);
        }

        /* #################### CREATE QUEUE #################### */

        for (i = 0; i &lt; req[j].count; ++i) {
            buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer[j].memory = V4L2_MEMORY_MMAP;
            buffer[j].index = i;
            ioctl(fd[j], VIDIOC_QBUF, &amp;buffer[j]);
        }

    } /* ### ### end of camera init ### ### */

    /* ##################### STREAM ON #################### */
    for (j = 0; j &lt; numOfCameras; ++j) {

        ioctl(fd[j], VIDIOC_STREAMON, &amp;type);
    }


    /* ##################### GET FRAME ##################### */

    k = 0;
    while (!kbhit()){
        k ++;

        for (j = 0; j &lt; numOfCameras; j++) {

            buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer[j].memory = V4L2_MEMORY_MMAP;
            usleep(100000);
            ioctl(fd[j], VIDIOC_DQBUF, &amp;buffer[j]);

            // create filename
            sprintf(fileName, "./output/image %03d from camera %d.PNG", k, j);
            // save as PNG file
            saveToPng(mem[j][buffer[j].index], fileName, xRes, yRes);

            ioctl(fd[j], VIDIOC_QBUF, &amp;buffer[j]);

            sleep(timeBetweenSnapshots);
        }
    }

    /* ##################### STREAM OFF ##################### */
    for (j = 0; j &lt; numOfCameras; ++j) {

        ioctl(fd[j], VIDIOC_STREAMOFF, &amp;type);
    }

    /* ##################### CLEANUP ##################### */

    for (j = 0; j &lt; numOfCameras; ++j) {

        close(fd[j]);
        free(mem[j]);
    }

    return (0);
}
</code></pre>

CC BY-SA 3.0
2014-09-02T18:39:50.473Z
This is a very borderline question for this SE, anything programming related should be asked on StackOverflow instead.
timonsku
CC BY-SA 3.0
2014-09-02T20:09:27.300Z
Are you sure that the frame rate and frame dimensions are uniform between the cameras?  That looks suspiciously like improper line timing, which would result from having the wrong height and width and/or frame rate.
AJ Henderson
<video><capturing><video-capture>
Corrupt images, when capturing from multiple cameras using the V4L2 API
karlitos
# Corrupt images, when capturing from multiple cameras using the V4L2 API

(Asked by: username_0 on 2014-09-02)

I would like to grab images from multiple cameras under linux. I followed this presentation used the code and enhanced it for my purpose. It works very well for 1 camera.

Once I begin to grab images from multiple cameras (successively) I get corrupt images.

The more cameras I sue the more artefacts/stripes in the images appear. It does not make any difference if I save the images as BMP using another code. So I assume the problem has nothing to do with the storing routine. The resolution is also right (744 * 480).
The result is the same on two different computers running Fedora and Debian. I am absolutely baffled and can not find any clue what is going wrong. Could me please someone give some hints ?
Here is my code
int main()
{
    /* #################### INIT #################### */

    int numOfCameras = 1;
    int xRes = 744;
    int yRes = 480;
    int exposure = 2000;
    unsigned int timeBetweenSnapshots = 2; // in sec
    char fileName[sizeof "./output/image 000 from camera 0.PNG"];

    static const char *devices[] = { "/dev/video0", "/dev/video1", "/dev/video2", "/dev/video3", "/dev/video4", "/dev/video5", "/dev/video6", "/dev/video7" };

    struct v4l2_capability cap[8];
    struct v4l2_control control[8];
    struct v4l2_format format[8];
    struct v4l2_requestbuffers req[8];
    struct v4l2_buffer buffer[8];

    int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // had to declare the type here because of the loop

    unsigned int i;
    unsigned int j;
    unsigned int k;

    int fd[8];
    void **mem[8];

    /* #################### OPEN DEVICE #################### */

    for (j = 0; j < numOfCameras; ++j) {

        fd[j] = open(devices[j], O_RDWR);
        ioctl(fd[j], VIDIOC_QUERYCAP, ∩[j]);


        /* #################### CAM CONTROLL #################### */

        control[j].id = V4L2_CID_EXPOSURE_AUTO;
        control[j].value = V4L2_EXPOSURE_SHUTTER_PRIORITY;
        ioctl(fd[j], VIDIOC_S_CTRL, &control[j]);

        control[j].id = V4L2_CID_EXPOSURE_ABSOLUTE;
        control[j].value = exposure;
        ioctl(fd[j], VIDIOC_S_CTRL, &control[j]);

        /* #################### FORMAT #################### */

        ioctl(fd[j], VIDIOC_G_FMT, &format[j]);
        format[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        format[j].fmt.pix.width = xRes;
        format[j].fmt.pix.height = yRes;
        //format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        format[j].fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
        ioctl(fd[j], VIDIOC_S_FMT, &format[j]);

        /* #################### REQ BUF #################### */

        req[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req[j].count = 4;
        req[j].memory = V4L2_MEMORY_MMAP;
        ioctl(fd[j], VIDIOC_REQBUFS, &req[j]);
        mem[j] = malloc(req[j].count * sizeof(*mem));

        /* #################### MMAP #################### */

        for (i = 0; i < req[j].count; ++i) {
            buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer[j].memory = V4L2_MEMORY_MMAP;
            buffer[j].index = i;
            ioctl(fd[j], VIDIOC_QUERYBUF, &buffer[j]);
            mem[j][i] = mmap(0, buffer[j].length,
                    PROT_READ|PROT_WRITE,
                    MAP_SHARED, fd[j], buffer[j].m.offset);
        }

        /* #################### CREATE QUEUE #################### */

        for (i = 0; i < req[j].count; ++i) {
            buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer[j].memory = V4L2_MEMORY_MMAP;
            buffer[j].index = i;
            ioctl(fd[j], VIDIOC_QBUF, &buffer[j]);
        }

    } /* ### ### end of camera init ### ### */

    /* ##################### STREAM ON #################### */
    for (j = 0; j < numOfCameras; ++j) {

        ioctl(fd[j], VIDIOC_STREAMON, &type);
    }


    /* ##################### GET FRAME ##################### */

    k = 0;
    while (!kbhit()){
        k ++;

        for (j = 0; j < numOfCameras; j++) {

            buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer[j].memory = V4L2_MEMORY_MMAP;
            usleep(100000);
            ioctl(fd[j], VIDIOC_DQBUF, &buffer[j]);

            // create filename
            sprintf(fileName, "./output/image %03d from camera %d.PNG", k, j);
            // save as PNG file
            saveToPng(mem[j][buffer[j].index], fileName, xRes, yRes);

            ioctl(fd[j], VIDIOC_QBUF, &buffer[j]);

            sleep(timeBetweenSnapshots);
        }
    }

    /* ##################### STREAM OFF ##################### */
    for (j = 0; j < numOfCameras; ++j) {

        ioctl(fd[j], VIDIOC_STREAMOFF, &type);
    }

    /* ##################### CLEANUP ##################### */

    for (j = 0; j < numOfCameras; ++j) {

        close(fd[j]);
        free(mem[j]);
    }

    return (0);
}

**Tags:** video, capturing, video-capture

> **Comments:**
> **username_1**: This is a very borderline question for this SE, anything programming related should be asked on StackOverflow instead.  
> **username_2**: Are you sure that the frame rate and frame dimensions are uniform between the cameras?  That looks suspiciously like improper line timing, which would result from having the wrong height and width and/or frame rate.  

---

## 2 answers

### Answer by username_1 on 2014-09-02. Score: 1 | Accepted answer

Your issue is probably that you don't have enough USB bandwidth available, if your webcams support it switch to MJPEG instead of uncompressed frames. Usually any webcam supports MJPEG encoding to deliver frames to your PC.

Here a similar question on SO <https://stackoverflow.com/questions/9781770/capturing-multiple-webcams-uvcvideo-with-opencv-on-linux>


---

### Answer by username_3 on 2016-07-01. Score: 0

I am fairly certain you are getting the corruption because of the usleep(100000); - This is based on the fact I have achieved similar corruption using one webcam by adding usleep(100000) to my code.

My usleep(100000); is substitution for running an opencl kernel, meaning this point I know the problem is that the usleep(100000) affects the video frame delivery in some way (this happens in my code if I strip out all other code, and just save the frames to disk as ppm files).

What I don't know is why ....

I can put the usleep anywhere in my code, the affect is always the same.

Perhaps the video4linux webcam code needs to be on a different pthread ..


---

