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
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);