user6426: 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, &cap[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);
}


user3295: 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

6426: <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.stack.imgur.com/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.stack.imgur.com/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>
 3295: <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>
