diff --git a/b b/b index f357a09457a5acd2704bffe3d9b0de6e2d73f7b2..ae17fc6dacf86b63b3f2ef65f819145c0fc3b94c 160000 --- a/b +++ b/b @@ -1 +1 @@ -Subproject commit f357a09457a5acd2704bffe3d9b0de6e2d73f7b2 +Subproject commit ae17fc6dacf86b63b3f2ef65f819145c0fc3b94c diff --git a/dox/Screenshot_camtron1_ip.png b/dox/Screenshot_camtron1_ip.png new file mode 100644 index 0000000000000000000000000000000000000000..fe4c891310e1dbc0c429bf15e68a6de97f045199 Binary files /dev/null and b/dox/Screenshot_camtron1_ip.png differ diff --git a/dox/general_questions b/dox/general_questions deleted file mode 100644 index 6caacafb9d14487f471efdde0fc1b2c0117ca2f9..0000000000000000000000000000000000000000 --- a/dox/general_questions +++ /dev/null @@ -1,9 +0,0 @@ -> !! if beetle runs in circle it is in "escape/panic mode" which doesn't represent "natural" behaviour (explore, forage, quick move from a to b) - -> think about different setup. Bigger Arena? ---> ! beetle needs to be small enough to not be limited by constrained size of the arena - -> how much time for beetle to calm down / aclimatize? 10mins? -> 10 minutes is enough to analyze movement -> 8 fps could be enough to reduce mean error - - diff --git a/dox/misc2 b/dox/misc2 index cfbef0425eee563e012a5b9b0d0cd2e6075031e9..0aa41073fce1a7b663bd30eb18be4e470ea465e4 100644 --- a/dox/misc2 +++ b/dox/misc2 @@ -39,10 +39,14 @@ check: ## Emilio general critique ############################### - > !! if beetle runs in circle it is in "escape mode" which doesnt represent "natural" behaviour (explore, quick move from a to b) - -> think about different setup. Bigger Arena? - > fps can be low. Try 3! +> !! if beetle runs in circle it is in "escape/panic mode" which doesn't represent "natural" behaviour (explore, forage, quick move from a to b) + -> think about different setup. Bigger Arena? +--> ! beetle needs to be small enough to not be limited by constrained size of the arena + +> how much time for beetle to calm down / aclimatize? 10mins? +> 10 minutes is enough to analyze movement +> 8 fps could be enough to reduce mean error Depends on movement speed and estimated error calc error by comparing distance of 40fps with 3fps - > duration of video can be short. eg 10 minutes. - -> no need for many fridges + + diff --git a/dox/notes_b b/dox/notes_b index a703a4d9abe3444563bd0a17f0691531a7a4ad81..2cde7a482a1d497600b5053c4e82e8f7b57dd39f 100644 --- a/dox/notes_b +++ b/dox/notes_b @@ -9,6 +9,9 @@ Does use opencv to convert raw cam images into JPEG pixel format ############################### +convert timestamp in ns +date +%F_%T -d @$(echo 2246782775624200 / 1000000000 | bc) + VmbSystem::RegisterCameraListObserver diff --git a/dox/scrap b/dox/scrap index 2ab804b197acedab18995487fc63c7417ea858c0..655c459a733682d5b7d87dacae61835cfd84f844 100644 --- a/dox/scrap +++ b/dox/scrap @@ -1,273 +1,22 @@ -use as cali? -sightcalibrator/jammy 21.0.0-4 amd64 - Camera calibration software - ###############################console non block input + read user input - // // Non-blocking input -#include <unistd.h> -#include <fcntl.h> -void setNonBlockingMode() { - int flags = fcntl(STDIN_FILENO, F_GETFL, 0); - if (flags != -1) { - fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); - } -} -void restoreBlockingMode() { - int flags = fcntl(STDIN_FILENO, F_GETFL, 0); - if (flags != -1) { - fcntl(STDIN_FILENO, F_SETFL, flags & ~O_NONBLOCK); - } -} -////would need to change -setNonBlockingMode(); -std::string input; -char c; -bool hasInput = false; - -while (running) { - // Check if there's any input available - if (read(STDIN_FILENO, &c, 1) > 0) { - // Append the character to the input string - input.push_back(c); - hasInput = true; - } else if (hasInput) { - // If there was previous input and no more input available, - // process the input - if (input == "q\n") { // Check for 'q' followed by newline - qDebug() << "User requested exit"; - running = false; - QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection); - break; - } else if (!input.empty()) { - // Process the input here - qDebug() << "Received input:" << QString::fromStdString(input); - } - input.clear(); // Clear the input buffer - hasInput = false; - } - // Add a small delay to avoid busy-waiting - QThread::msleep(100); - } - - restoreBlockingMode(); // Revert back to blocking mode before exiting - -############################### -QString randomString() -{ - QStringList list{"a", "b", "c", "d", "e", "f", "g"}; - //, "h", "i", "j", "k", "l", "m"}; - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(list.begin(), list.end(), g); - QString randomString = list.join(""); - qDebug() << "Random string:" << randomString; - return randomString; -} - -bool maybeCreateDir(QDir out_dir) -{ - if( !out_dir.exists() ) - { - qDebug() << "out_dir (" << out_dir.absolutePath() << ") doesn't exist. Should I Create it? ['y'-yes, '?'-no]"; - char c='y'; - std::cin >> c; - if( c == 'y' ) - { - qDebug() << "u pressed yes"; - if( out_dir.mkpath(out_dir.absolutePath())) { - qDebug() << "created out_dir"; - } - else - { - std::cerr << "failed to create out_dir '" << out_dir.absolutePath().toStdString() << "'" << std::endl; - return false; - } - } - else - { - qDebug() << "u pressed no"; - return false; - } - } - qDebug() << "out_dir: " << out_dir.dirName(); - return true; -} ############################### -updateCameras() - // CameraPtrVector vmbCameras; - // if ( f(_sys.GetCameras( vmbCameras ), "update cameras") ) - // return; - - // if( (int)vmbCameras.size() != ncam() ) //update number of cameras - // error(QString("Expected %1 cams!").arg(ncam()),errLessCamsThanExpected); //XXX warning - - // // vector< shared_ptr<Camera> > vmbCameras - // // vector< shared_ptr<Cam> > _cameras - - // // Add new cameras - // for (const auto& vcam : vmbCameras) - // { - // bool found = false; - // for (const auto& cam : _cameras) - // { - // if (cam->getCameraPtr() == vcam) - // { - // found = true; - // break; - // } - // } - // if (!found) - // { - // _cameras.push_back(std::make_shared<Cam>(vcam)); //create Cam() from CameraPtr vcam - // print(QString("cam connected: %1").arg(_cameras.back()->id())); - // } - // } - - // // Remove cameras that are no longer present - // auto it = _cameras.begin(); - // while (it != _cameras.end()) - // { - // // qDebug() << "check " << (*it)->id(); - - // bool found = false; - // for (const auto& vcam : vmbCameras) - // { - // if ((*it)->getCameraPtr() == vcam) - // { - // found = true; - // ++it; - // break; - // } - // } - - // if (!found) - // { - // qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << " !!! "; - // print({"cam disconnected",(*it)->id()}); - // it = _cameras.erase(it); - // } - // } -} // now ~Camera() should be called on removed cams. >> triggers camObserver - -//############################### -// -// We create a FrameProcessor class that subclasses QObject and defines a slot processFrame() to handle frame processing. -// We create a FrameObserver class that subclasses IFrameObserver. In its constructor, we create an instance of FrameProcessor and move it to a worker thread. -// We connect the FrameObserver::frameReceived signal to the FrameProcessor::processFrame slot, so frame processing happens asynchronously in the worker thread. -// In the FrameObserver::FrameReceived function, we emit the frameReceived signal with the received frame, triggering asynchronous frame processing. -// -// This way, frame processing occurs asynchronously in another thread, separate from the GUI thread. Adjust the code as needed to fit your application's requirements. -// -//############################### -#include <QtCore> -#include <VimbaCPP/Include/VimbaCPP.h> -#include <opencv2/opencv.hpp> - -using namespace AVT::VmbAPI; - -class FrameProcessor : public QObject -{ - Q_OBJECT - -public slots: - void processFrame(FramePtr pFrame) - { - VmbUint64_t timestamp; - if (VmbErrorSuccess == pFrame->GetTimestamp(timestamp)) - { - // Convert timestamp to QDateTime for better handling with Qt - QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(timestamp / 1000); - - // Convert QDateTime to a string format - QString timestampStr = dateTime.toString("yyyy-MM-dd_HH-mm-ss"); - - // Process the frame - VmbUchar_t *buffer; - if (VmbErrorSuccess == pFrame->GetImage(buffer)) - { - int width, height; - VmbUint32_t imageSize; - pFrame->GetWidth(width); - pFrame->GetHeight(height); - pFrame->GetImageSize(imageSize); - - cv::Mat image(height, width, CV_8UC1, buffer); - - // Save the frame with timestamp using Qt functions - QString filename = "camera_image_" + timestampStr + ".jpg"; - cv::imwrite(filename.toStdString(), image); - } - } - } -}; - -class FrameObserver : public IFrameObserver -{ -public: - FrameObserver(CameraPtr pCamera, QObject *parent = nullptr) : IFrameObserver(pCamera), m_processor(new FrameProcessor), m_thread(new QThread(parent)) - { - m_processor->moveToThread(m_thread); - connect(this, &FrameObserver::frameReceived, m_processor, &FrameProcessor::processFrame); - m_thread->start(); - } - - ~FrameObserver() - { - m_thread->quit(); - m_thread->wait(); - delete m_thread; - } - - void FrameReceived(const FramePtr pFrame) override - { - emit frameReceived(pFrame); - } - -signals: - void frameReceived(FramePtr pFrame); - -private: - FrameProcessor *m_processor; - QThread *m_thread; -}; +## unplanned termination (ctrl-c, kill) +// std::signal(SIGINT, signalHandler); +// std::signal(SIGTERM, signalHandler); ############################### -## FrameReceived with storing images along with timestamps -#include <QtCore> -#include <VimbaCPP/Include/VimbaCPP.h> -#include <opencv2/opencv.hpp> - -using namespace AVT::VmbAPI; - -void FrameObserver::FrameReceived(const FramePtr pFrame) -{ - VmbUint64_t timestamp; - if (VmbErrorSuccess == pFrame->GetTimestamp(timestamp)) - { - // Convert timestamp to QDateTime for better handling with Qt - QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(timestamp / 1000); - - // Convert QDateTime to a string format - QString timestampStr = dateTime.toString("yyyy-MM-dd_HH-mm-ss"); - - // Process the frame - VmbUchar_t *buffer; - if (VmbErrorSuccess == pFrame->GetImage(buffer)) - { - int width, height; - VmbUint32_t imageSize; - pFrame->GetWidth(width); - pFrame->GetHeight(height); - pFrame->GetImageSize(imageSize); - - cv::Mat image(height, width, CV_8UC1, buffer); - - // Save the frame with timestamp using Qt functions - QString filename = "camera_image_" + timestampStr + ".jpg"; - cv::imwrite(filename.toStdString(), image); - } - } -} +## limit THREADS +//use tools to analyze +// gdb -p <pid> +// or +// info threads +// strace -f -p <pid> +// int idealThreadCount = QThread::idealThreadCount(); +// int threadPoolMaxCount = QThreadPool::globalInstance()->maxThreadCount(); +// QThreadPool::globalInstance()->setMaxThreadCount(idealThreadCount); + +// qDebug() << "Ideal Thread Count:" << idealThreadCount; +// qDebug() << "Thread Pool Max Count:" << threadPoolMaxCount; ############################### ## IsCommandDone @@ -284,342 +33,3 @@ err = feature->RunCommand(); } while (commandDone == false); } ############################### - -#include <VimbaC/Include/VimbaC.h> -#include <iostream> -#include <chrono> - -using namespace std; -using namespace chrono; - -class Camera { -public: - Camera(); - ~Camera(); - - bool initialize(); - bool open(); - void close(); - bool startCapture(); - void stopCapture(); - bool captureFrame(); - -private: - VmbHandle_t cameraHandle; -}; - -Camera::Camera() : cameraHandle(nullptr) {} - -Camera::~Camera() { - close(); -} - -bool Camera::initialize() { - return VmbErrorSuccess == VmbStartup(); -} - -bool Camera::open() { - VmbError_t err; - - VmbCameraInfo_t* pCameraList = nullptr; - VmbUint32_t nCount = 0; - - err = VmbCamerasList(nullptr, 0, &nCount, sizeof(VmbCameraInfo_t)); - if (err != VmbErrorSuccess || nCount == 0) { - cout << "No cameras found or error listing cameras" << endl; - return false; - } - - pCameraList = new VmbCameraInfo_t[nCount]; - err = VmbCamerasList(pCameraList, nCount, &nCount, sizeof(VmbCameraInfo_t)); - if (err != VmbErrorSuccess) { - cout << "Error retrieving camera list" << endl; - delete[] pCameraList; - return false; - } - - if (nCount == 0) { - cout << "No cameras found" << endl; - delete[] pCameraList; - return false; - } - - err = VmbCameraOpen(pCameraList[0].cameraIdString, VmbAccessModeFull, &cameraHandle); - delete[] pCameraList; - - return err == VmbErrorSuccess; -} - -void Camera::close() { - if (cameraHandle != nullptr) { - VmbCameraClose(cameraHandle); - cameraHandle = nullptr; - } -} - -bool Camera::startCapture() { - return VmbErrorSuccess == VmbCaptureStart(cameraHandle); -} - -void Camera::stopCapture() { - VmbCaptureEnd(cameraHandle); -} - -bool Camera::captureFrame() { - VmbError_t err; - - VmbFrame_t frame; - err = VmbFrameAnnounce(cameraHandle, &frame, sizeof(VmbFrame_t)); - if (err != VmbErrorSuccess) { - cout << "Error announcing frame" << endl; - return false; - } - - err = VmbCaptureFrameQueue(cameraHandle, &frame, nullptr); - if (err != VmbErrorSuccess) { - cout << "Error queuing frame" << endl; - return false; - } - - err = VmbCaptureFrameWait(cameraHandle, &frame, VMB_INFINITE); - if (err != VmbErrorSuccess) { - cout << "Error waiting for frame" << endl; - return false; - } - - // Get timestamp - VmbUint64_t timestamp; - err = VmbFrameGetTimestamp(cameraHandle, frame, ×tamp); - if (err == VmbErrorSuccess) { - auto duration = duration_cast<milliseconds>(nanoseconds(timestamp)); - cout << "Frame captured at timestamp: " << duration.count() << "ms" << endl; - } - - err = VmbFrameRevoke(cameraHandle, &frame); - if (err != VmbErrorSuccess) { - cout << "Error revoking frame" << endl; - return false; - } - - return true; -} - -int main() { - Camera camera; - - if (!camera.initialize()) { - cout << "Failed to initialize Vimba" << endl; - return -1; - } - - if (!camera.open()) { - cout << "Failed to open camera" << endl; - return -1; - } - - if (!camera.startCapture()) { - cout << "Failed to start capture" << endl; - return -1; - } - - // Capture frames and perform processing - - // For demonstration purposes, let's capture 10 frames - for (int i = 0; i < 10; ++i) { - if (!camera.captureFrame()) { - cout << "Error capturing frame" << endl; - break; - } - // Add your processing logic here - } - - camera.stopCapture(); - camera.close(); - - VmbShutdown(); - - return 0; -} - -############################### -#include <QCoreApplication> -#include <QDebug> -#include <QString> -#include <QDateTime> -#include <QThread> -#include <VimbaC/Include/VimbaC.h> -#include <opencv2/opencv.hpp> - -class VimbaCamera : public QObject { - Q_OBJECT - -public: - VimbaCamera(QObject *parent = nullptr); - ~VimbaCamera(); - - bool initialize(); - bool open(); - void close(); - bool startCapture(); - void stopCapture(); - bool captureFrame(); - -signals: - void frameCaptured(const QString ×tamp, const cv::Mat &image); - -private: - VmbHandle_t cameraHandle; - VmbFrame_t frame; - // Add other camera-related members here -}; - -VimbaCamera::VimbaCamera(QObject *parent) : QObject(parent), cameraHandle(nullptr) {} - -VimbaCamera::~VimbaCamera() { - close(); -} - -bool VimbaCamera::initialize() { - return VmbErrorSuccess == VmbStartup(); -} - -bool VimbaCamera::open() { - VmbError_t err; - - // Add code to list and open the Vimba camera - // ... - - return err == VmbErrorSuccess; -} - -void VimbaCamera::close() { - if (cameraHandle != nullptr) { - // Add code to close the Vimba camera - // ... - cameraHandle = nullptr; - } -} - -bool VimbaCamera::startCapture() { - VmbError_t err; - - // Add code to configure camera settings for capturing - // ... - - // Announce the frame - err = VmbFrameAnnounce(cameraHandle, &frame, sizeof(VmbFrame_t)); - if (err != VmbErrorSuccess) { - qDebug() << "Error announcing frame"; - return false; - } - - // Add code to start capturing frames using Vimba API - // ... - - return true; -} - -void VimbaCamera::stopCapture() { - // Add code to stop capturing frames using Vimba API - // ... - - // Revoke the frame - VmbError_t err = VmbFrameRevoke(cameraHandle, &frame); - if (err != VmbErrorSuccess) { - qDebug() << "Error revoking frame"; - } -} - -bool VimbaCamera::captureFrame() { - VmbError_t err; - - // Add code to capture a frame with timestamp using Vimba API - // ... - - err = VmbCaptureFrameWait(cameraHandle, &frame, VMB_INFINITE); - if (err != VmbErrorSuccess) { - qDebug() << "Error waiting for frame"; - return false; - } - - // Get timestamp - VmbUint64_t timestamp; - err = VmbFrameGetTimestamp(cameraHandle, frame, ×tamp); - if (err == VmbErrorSuccess) { - auto duration = QDateTime::fromMSecsSinceEpoch(timestamp / 1000000); // Convert microseconds to milliseconds - qDebug() << "Frame captured at timestamp:" << duration.toString("yyyy-MM-dd hh:mm:ss.zzz"); - - // Convert the frame to a QImage and emit the signal - cv::Mat image(frame.height, frame.width, CV_8UC1, frame.buffer); - emit frameCaptured(duration.toString("yyyy-MM-dd_hhmmsszzz"), image.clone()); - } - - // Revoke the frame - err = VmbFrameRevoke(cameraHandle, &frame); - if (err != VmbErrorSuccess) { - qDebug() << "Error revoking frame"; - return false; - } - - return true; -} - -class CameraThread : public QThread { - Q_OBJECT - -public: - CameraThread(int cameraIndex, QObject *parent = nullptr) : QThread(parent), cameraIndex(cameraIndex) {} - -protected: - void run() override { - VimbaCamera camera; - connect(&camera, &VimbaCamera::frameCaptured, this, &CameraThread::handleFrameCaptured); - - if (!camera.initialize()) { - qDebug() << "Camera" << cameraIndex << "Failed to initialize Vimba"; - return; - } - - if (!camera.open()) { - qDebug() << "Camera" << cameraIndex << "Failed to open Vimba camera"; - return; - } - - if (!camera.startCapture()) { - qDebug() << "Camera" << cameraIndex << "Failed to start capturing frames"; - return; - } - - exec(); // Start the thread event loop - } - -private: - int cameraIndex; - -private slots: - void handleFrameCaptured(const QString ×tamp, const cv::Mat &image) { - // Handle the captured frame (e.g., save as JPEG) - QString filename = "camera" + QString::number(cameraIndex) + "_" + timestamp + ".jpg"; - cv::imwrite(filename.toStdString(), image); - qDebug() << "Camera" << cameraIndex << "Frame saved as:" << filename; - } -}; - -int main(int argc, char *argv[]) { - QCoreApplication a(argc, argv); - - // For demonstration purposes, create two camera threads - CameraThread cameraThread1(1); - CameraThread cameraThread2(2); - - // Start the camera threads - cameraThread1.start(); - cameraThread2.start(); - - // Wait for the threads to finish (this won't block the main thread event loop) - cameraThread1.wait(); - cameraThread2.wait(); - - return a.exec(); -} - diff --git a/dox/todo_ct b/dox/todo_ct index 728debd3d459b0d9e4a8d63724925e2d8e5129c9..d1b771ea2c07c39ead6f49cde9cffa5736c642ab 100644 --- a/dox/todo_ct +++ b/dox/todo_ct @@ -1,5 +1,4 @@ -CAMTRON PROCESSING PIPELINE -########################### +[########################### A) setup / preparation B) recorder C) background-subtraction @@ -11,27 +10,31 @@ CAMTRON PROCESSING PIPELINE A) ########################### - eval vm performance - - ‼️ ❺ light - - day + night + dirt (later) - - find ecolux hw (Boxes, DMX per unit, DMX splitter/controller, PIs) - - ‼️ ❶ eval arena 3D-printed + attach camo > if good order 5more - - camo pattern print+create + - light + - alban: get ecolux hw from badlauchstaedt (Boxes, DMX per unit, DMX splitter/controller) + > ‼️ write mail to angry alban to get lighthw in september! + - get 1 PI for ecolux + - day + night + dirt + - IR leds (later) + - tape camo to arenas - floor: find big white paperrolle in BUG/Storage B) recorder - camera produces frames and timestamps ########################### - - ‼️ ❸ BUG occasionaly frames are incomplete -> calling VV once fixes issues. why? maybe PACKSIZE ADjustment? - - ‼️ ❷ BUG files are not closed, causing OS limit crash (ulimit -n, too many open files...). why? + - ‼️ _rec->showProgress(); //xxx string to add to camInfo - ‼️ + checkDiskSpace() -> when invoked? check how long it takes to get disk + size test: checkDiskspace(), stats(), pb(), ... if long: init once if + short: before startrecord - ‼️ stats() / progressBar -> invoked: by + user,at end of rec,listcameras, ... every 1s timer (toggle by user) + + - settime() - test with 1 cam - test with x cams + - occasionaly frames are incomplete/dropped + - sometimes PacketSize gets changed and then no frames are rcv -> calling VV once fixes issues >> adjust PACKETSIZE ============================ CORE - - framerate, brightness ... - - opencv or vimba? - - app settings: - - out_dir, threads_per_cam, - - record duration - - ‼️ ❹ calibrate + - ‼️ calibrate - see opencv tut + code/bash cali example - ada-HPC-CALISW @@ -73,7 +76,7 @@ C) background subtraction D) process scripts ########################### - ctd - calculated the mean speed in pixel / millisecond + ctd - calculated the mean speed in pixel / millisecond * can i reduce size of data (reduce length|fps|res) >- calc D) for test data set (get data from joerdis?) -- with all frames @@ -119,4 +122,14 @@ ctb Done ####################### + - set duration for 1 or all cams + - info() - dbg + - files, threads, settings, dirs, ... + - print global vars (dur,,fps,framesize,dir,threads,ncam,...) + - record class (extract cam stuff into own class) + - BUG files are not closed, causing OS limit crash (ulimit -n, too many open files...). why? + open files (-n) 1024 + - eval arena 3D-printed + attach camo + - config: record duration, out_dir, threads_per_cam, ncam + - camo pattern print+create