From dadce6994403939ade24689be293c5cb6216a8b7 Mon Sep 17 00:00:00 2001
From: Jan Grewe <jan.grewe@g-node.org>
Date: Thu, 14 Mar 2024 15:14:47 +0100
Subject: [PATCH] [dualcam] properly read rois

---
 dualcamgrabber.cpp | 36 +++++++++++++++++++++++++++++++++---
 dualcamwrapper.cpp | 44 ++++++++++++++++++++++++++++++--------------
 dualcamwrapper.h   |  2 +-
 3 files changed, 64 insertions(+), 18 deletions(-)

diff --git a/dualcamgrabber.cpp b/dualcamgrabber.cpp
index 15b9de3..8407695 100644
--- a/dualcamgrabber.cpp
+++ b/dualcamgrabber.cpp
@@ -2,6 +2,11 @@
 #include <iostream>
 #include <pylon/PylonIncludes.h>
 #include <stitchimage.h>
+#include <chrono>
+using namespace std::chrono;
+typedef high_resolution_clock Time;
+typedef milliseconds ms;
+typedef duration<float> fsec;
 
 void DualcamGrabber::run() {
   stop_request = false;
@@ -9,9 +14,10 @@ void DualcamGrabber::run() {
 
   if (wrapper->isOpen()) {
       Pylon::CInstantCameraArray &cameras = wrapper->getCameraArray();
-      wrapper->frameRate(static_cast<uint>(framerate));
+      wrapper->frameRate(static_cast<uint>(framerate), -1);
       wrapper->exposureTime(exposure);
       wrapper->gain(gain);
+
       cameras.StartGrabbing();
       Pylon::CGrabResultPtr frame0, frame1;
       Pylon::CPylonImage leftImage;
@@ -19,14 +25,27 @@ void DualcamGrabber::run() {
       Pylon::CPylonImage stitchedImage;
       std::string errorMessage = "";
 
+      // int ifi = 0;
+      // int deviation = 0;
+      // std::cerr << wrapper->frameRate(0) << "\t" << wrapper->frameRate(1) << "\t" << framerate << std::endl;
+      // int desired_ifi = (1./wrapper->frameRate(0) * 1000000);
+      // auto framestart = high_resolution_clock::now();
       while (cameras.IsGrabbing() && !stop_request) {
+        // if (counter > 0) {
+        //   deviation = desired_ifi - ifi;
+        //   if (deviation > 0)
+        //     // usleep(deviation);
+        //     std::cerr << desired_ifi << "\t" << deviation << std::endl;
+        // }
+          // auto start = high_resolution_clock::now();
           MyImage *img = new MyImage();
+          // auto stop1 = high_resolution_clock::now();
           cameras[0].RetrieveResult( 5000, frame0, Pylon::TimeoutHandling_ThrowException );
+          // auto stop2 = high_resolution_clock::now();
           cameras[1].RetrieveResult( 5000, frame1, Pylon::TimeoutHandling_ThrowException );
-
+          // auto stop3 = high_resolution_clock::now();
           leftImage.AttachGrabResultBuffer( frame0 );
           rightImage.AttachGrabResultBuffer( frame1 );
-
           if (leftImage.IsValid() && rightImage.IsValid()) {
             try {
               StitchImage::StitchToRight(leftImage, rightImage, &stitchedImage, errorMessage);
@@ -36,6 +55,17 @@ void DualcamGrabber::run() {
               std::cerr << e.what() << '\n';
             }
           }
+          // auto stop4 = high_resolution_clock::now();
+          // auto duration1 = duration_cast<microseconds>(stop1 - start);
+          // auto duration2 = duration_cast<microseconds>(stop2 - stop1);
+          // auto duration3 = duration_cast<microseconds>(stop3 - stop2);
+          // auto duration4 = duration_cast<microseconds>(stop4 - stop3);
+          // std::cerr << "framecount: " << counter << " image constr: " << duration1.count() << "\t" << " retrieve1: " << duration2.count() << "\t" << " retrieve2: " << duration3.count() << "\t" << "conversion: " << duration4.count() << std::endl;
+          // ifi = duration_cast<microseconds>(stop4 - framestart).count();
+          // framestart = stop4;
+          // if (counter > 0) {
+          //   std::cerr << "frame " << counter << " inter frame interval: " << ifi << "microseconds" << std::endl;
+          // } 
           counter += 1;
       }
       cameras.StopGrabbing();
diff --git a/dualcamwrapper.cpp b/dualcamwrapper.cpp
index 0af1e9c..9c7e7fb 100644
--- a/dualcamwrapper.cpp
+++ b/dualcamwrapper.cpp
@@ -54,8 +54,8 @@ bool DualcamWrapper::frameRate(uint new_framerate, int camindex) {
         frameRate(new_framerate, 0);
         frameRate(new_framerate, 1);
         return true;
-      } else if (camindex == 0 && camindex ==1) {
-        GenApi::INodeMap& nodemap = getNodemap(0);
+      } else if (camindex >= 0 && camindex < 2) {
+        GenApi::INodeMap& nodemap = getNodemap(camindex);
         GenApi::INode* n = nodemap.GetNode( "AcquisitionFrameRateEnable" );
         Pylon::CBooleanParameter enableframerate(n);
         enableframerate.SetValue(true);
@@ -72,7 +72,7 @@ bool DualcamWrapper::frameRate(uint new_framerate, int camindex) {
 
 
 double DualcamWrapper::frameRate(int camindex) {
-  assert(camindex > 0 && camindex < 2);
+  assert(camindex >= 0 && camindex < 2);
   double rate = -1.;
   if (valid) {
       GenApi::INodeMap& nodemap = getNodemap(camindex);
@@ -173,14 +173,14 @@ bool DualcamWrapper::grabFrame(MyImage &img, int camindex) {
   qDebug() << "grabFrame from camera " << camindex;
   if (valid) {
     GenApi::INodeMap &nodemap = getNodemap(camindex);
-    qDebug() << "Setting width" << layout.rois[0].width;
-    Pylon::CIntegerParameter(nodemap, "Width").SetValue(layout.rois[0].width);
+    qDebug() << "Setting width" << layout.rois[camindex].width;
+    Pylon::CIntegerParameter(nodemap, "Width").SetValue(layout.rois[camindex].width);
     qDebug() << "Setting height" << layout.rois[0].height;
-    Pylon::CIntegerParameter(nodemap, "Height").SetValue(layout.rois[0].height);
-    qDebug() << "Setting xoffset" << layout.rois[0].x;
-    Pylon::CIntegerParameter(nodemap, "OffsetX").SetValue(layout.rois[0].x);
-    qDebug() << "Setting yoffset" << layout.rois[0].y;
-    Pylon::CIntegerParameter(nodemap, "OffsetY").SetValue(layout.rois[0].y);
+    Pylon::CIntegerParameter(nodemap, "Height").SetValue(layout.rois[camindex].height);
+    qDebug() << "Setting xoffset" << layout.rois[camindex].x;
+    Pylon::CIntegerParameter(nodemap, "OffsetX").SetValue(layout.rois[camindex].x);
+    qDebug() << "Setting yoffset" << layout.rois[camindex].y;
+    Pylon::CIntegerParameter(nodemap, "OffsetY").SetValue(layout.rois[camindex].y);
 
     camera->StartGrabbing();
     camera->RetrieveResult( 5000, frame, Pylon::TimeoutHandling_ThrowException);
@@ -191,15 +191,30 @@ bool DualcamWrapper::grabFrame(MyImage &img, int camindex) {
 }
 
 
+void DualcamWrapper::setROI() {
+  std::cerr << "Setting ROI" << std::endl;
+  for (int camindex = 0; camindex < 2; camindex++){
+    std::cerr << "\t" << camindex << std::endl;
+    GenApi::INodeMap &nodemap = getNodemap(camindex);
+    qDebug() << "Setting width" << layout.rois[camindex].width;
+    Pylon::CIntegerParameter(nodemap, "Width").SetValue(layout.rois[camindex].width);
+    qDebug() << "Setting height" << layout.rois[0].height;
+    Pylon::CIntegerParameter(nodemap, "Height").SetValue(layout.rois[camindex].height);
+    qDebug() << "Setting xoffset" << layout.rois[camindex].x;
+    Pylon::CIntegerParameter(nodemap, "OffsetX").SetValue(layout.rois[camindex].x);
+    qDebug() << "Setting yoffset" << layout.rois[camindex].y;
+    Pylon::CIntegerParameter(nodemap, "OffsetY").SetValue(layout.rois[camindex].y);
+  }
+}
+
+
 void DualcamWrapper::resetCamera(int camindex) {
     GenApi::INodeMap &nodemap = getNodemap( camindex );
     int64_t dfltWidth = 2048;
     int64_t dfltHeight = 1536;
   qDebug() << "resetting camera to default ROI (" << dfltWidth << ", " << dfltHeight << ")";
   try {
-    // std::cerr << "MaxWidth: " << Pylon::CIntegerParameter(nodemap, "WidthMax").GetValue() << std::endl;
     Pylon::CIntegerParameter(nodemap, "Width").SetValue(dfltWidth, false);
-    // std::cerr << "MaxHeight: " << Pylon::CIntegerParameter(nodemap, "HeightMax").GetValue() << std::endl;
     Pylon::CIntegerParameter(nodemap, "Height").SetValue(dfltHeight, false);
     Pylon::CIntegerParameter(nodemap, "OffsetX").SetValue(0);
     Pylon::CIntegerParameter(nodemap, "OffsetY").SetValue(0);
@@ -229,8 +244,9 @@ bool DualcamWrapper::openCameras(std::string &message) {
         valid = false;
         return valid;
     }
-    resetCamera(0);
-    resetCamera(1);
+    // resetCamera(0);
+    // resetCamera(1);
+    setROI();
     return valid;
 }
 
diff --git a/dualcamwrapper.h b/dualcamwrapper.h
index 8c48757..284e1e8 100644
--- a/dualcamwrapper.h
+++ b/dualcamwrapper.h
@@ -15,7 +15,6 @@ public:
     DualcamWrapper(const CameraLayout &layout);
     ~DualcamWrapper();
 
-
     ImageSettings getImageSettings(int camindex);
     bool isOpen();
     void terminate();
@@ -35,6 +34,7 @@ private:
     void resetCamera(int camindex);
     Pylon::CInstantCameraArray cameras;
     GenApi::INodeMap& getNodemap(int camindex);
+    void setROI();
     bool valid, withLayout;
     CameraLayout layout;