Repeating lines in image with increased resolution

In this example GitHub - edward-ardu/libcamera-cpp-demo: libcamera c++ demo when i set the resoultion larger than 1920x1080 i get distorted image. it is as if same data is being repeated to fill the image causeing these lines. with res 1920x1080 and 1280x720 its fine

How to fix this?

@henri

I updated the code.

Thanks for your advice

yes, this fixes it in your example. But when i tried to integrate it into my codebase it gets stuck at while loop because framedata is always null. i was able to capture pictures before adding cam.VideoStream
All i need is to have 2 cameras capture still images and save them to file. Im not using the opencv Mat imwrite to save image because i was unable to properly link opencv into my cross-compilation project
Anyways this is the method i call for both cameras

QFuture<CameraCapture>
ArducamCamera::capturePicture(InternalFilesystem *fs, QString fileName)
{
    qDebug() << "capture picture " +id;
    // Make sure no other capture is running currently:
   // if (captureWatcher.isRunning())
   // {
     //   QLOG_WARN() << "Tried to capture a picture while another capture is still in progress.";
       // throw CameraError("Another capture is already in progress.");
    //}

    QLOG_TRACE() << "Capturing picture from the camera.";

    QString tempId = id;

    if(tempId.contains("/")){
        tempId = tempId.remove("/");//.mid(tempId.lastIndexOf("/",tempId.length()-1));
    }

    QString prefix = QString("capture_%1").arg(tempId);

    MountedNodePtr node = fs->getTmpDir(prefix);
    if (node.isNull())
        throw CameraError("Failed to initialize a temporary file.");
    QLOG_TRACE() << "Temporary file for captured arducam image:" << node->getPath();


    QString path = node->getPath();


    width = 1280;
    height = 720;
    uint32_t stride;

    int ret = cam.initCamera(cm_, id);
    cam.configureStill(width, height, formats::RGB888, 1, 0); //TODO 0 is rotation, rotation can be made here already
    ControlList controls_;
    int64_t frame_time = 1000000 / 30;
    // Set frame rate
    controls_.set(controls::FrameDurationLimits, libcamera::Span<const int64_t, 2>({ frame_time, frame_time }));
    // Adjust the brightness of the output images, in the range -1.0 to 1.0
    controls_.set(controls::Brightness, 0.5);
    // Adjust the contrast of the output image, where 1.0 = normal contrast
    controls_.set(controls::Contrast, 1.5);
    // Set the exposure time
    //controls_.set(controls::ExposureTime, 20000);
    cam.set(controls_);

    time_t start_time = time(0);
    int frame_count = 0;
    float lens_position = 100;
    float focus_step = 50;
    char key;
   // if (!ret) {
        bool flag;
        LibcameraOutData frameData;
        cam.startCamera();
        cam.VideoStream(&width,&height,&stride);
        while (true) {
            //qDebug() << "starting to read frame";
            flag = cam.readFrame(&frameData);
            if (!flag){
                //qDebug() << "failed reading frame";
                continue;
            }
            qDebug() << "frame read success";

            QImage image(frameData.imageData, width, height, QImage::Format_RGB888);
            QPixmap pixmap = QPixmap::fromImage(image);

            // Save the frame as a JPEG image
            QString filename = node->getPath();
            QFile file(filename);
            if (file.open(QIODevice::WriteOnly)) {
                QByteArray byteArray;
                QBuffer buffer(&byteArray);
                buffer.open(QIODevice::WriteOnly);
                pixmap.save(&buffer, "JPEG");
                file.write(byteArray);
                file.close();
            }

            if (key == 'q') {
                break;
            } else if (key == 'f') {
                ControlList controls;
                controls.set(controls::AfMode, controls::AfModeAuto);
                controls.set(controls::AfTrigger, 0);
                cam.set(controls);
            } else if (key == 'a' || key == 'A') {
                lens_position += focus_step;
            } else if (key == 'd' || key == 'D') {
                lens_position -= focus_step;
            }

            // To use the manual focus function, libcamera-dev needs to be updated to version 0.0.10 and above.
            if (key == 'a' || key == 'A' || key == 'd' || key == 'D') {
                ControlList controls;
                controls.set(controls::AfMode, controls::AfModeManual);
                controls.set(controls::LensPosition, lens_position);
                cam.set(controls);
            }

            frame_count++;
            if ((time(0) - start_time) >= 1){
                printf("fps: %d\n", frame_count);
                frame_count = 0;
                start_time = time(0);
            }
            cam.returnFrameBuffer(frameData);
            break;
        }

        cam.stopCamera();
  //  }
    //cam.closeCamera();

    QFuture<CameraCapture> future =
            QtConcurrent::run(this, &ArducamCamera::copyPicture, node, node->getName());
    captureWatcher.setFuture(future);

    return future;
}

Also i have another problem with earlier version of this code - it would only work once and when i tried to capture images again it would get stuck in the while loop unable to get frame data.
Maybe you can have a look and have some ideas how to fix this?

getting stuck happened because i called startCamera() before capturing each image so i had to add a check for if camera is already started then not to call it.

regarding scan lines, since i use QImage i have to use these constructors to specify stride:
QImage(uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr);
QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr);

1 Like