Add flag frame_keep_distortion, improved calib doc

This commit is contained in:
gineshidalgo99
2018-05-24 20:59:24 -04:00
parent 47894c9344
commit f4237dca41
20 changed files with 286 additions and 171 deletions
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
%PDF-1.2␍1 0 obj␍<< ␍/Creator (Adobe Illustrator_TM_ 7.0)␍/Producer (Acrobat PDF File Format 1.1 for Macintosh)␍>> ␍endobj␍2 0 obj␍<< ␍/Pages 4 0 R ␍/Type /Catalog ␍/Outlines 7 0 R ␍>> ␍endobj␍3 0 obj␍<< ␍/Type /Page ␍/Parent 4 0 R ␍/Resources << /ProcSet [ /PDF /Text ] >> ␍/Contents 5 0 R ␍>> ␍endobj␍4 0 obj␍<< ␍/Kids [ 3 0 R ] ␍/Count 1 ␍/Type /Pages ␍/MediaBox [ 0 0 612 792 ] ␍>> ␍endobj␍5 0 obj␍<< /Length 6 0 R >> ␍stream␍␍endstream␍endobj␍6 0 obj␍0 ␍endobj␍7 0 obj␍<< ␍/Count 0 ␍/Type /Outlines ␍>> ␍endobj␍xref␍0 8 ␍0000000000 65535 f ␍0000000009 00000 n ␍0000000123 00000 n ␍0000000193 00000 n ␍0000000303 00000 n ␍0000000394 00000 n ␍0000000448 00000 n ␍0000000466 00000 n ␍trailer␍<<␍/Size 8␍/Info 1 0 R ␍/Root 2 0 R ␍>>␍startxref␍516␍%%EOF␍8 0 obj␍<<␍/Length 9 0 R␍>>␍stream␍1 0 0 1 0 -1 cm␍BX␍/Layer << /Title (Layer 1)␍ /Visible true ␍ /Preview true ␍ /Editable true ␍ /Printed true ␍ /Dimmed false ␍ /Color [20224 32768 65535 ]␍>> BDC␍0 0 0 1 k␍0 0 0 1 K␍0 w␍[ ] 0 d␍0 J␍0 j␍4 M␍0 i␍%%Note: ␍93.5508 269.7693 m␍8.5254 269.7693 l␍8.5254 184.7419 l␍93.5508 184.7419 l␍93.5508 269.7693 l␍b␍93.5508 439.8240 m␍8.5254 439.8240 l␍8.5254 354.7967 l␍93.5508 354.7967 l␍93.5508 439.8240 l␍b␍178.5585 184.7508 m␍93.5332 184.7508 l␍93.5332 99.7235 l␍178.5585 99.7235 l␍178.5585 184.7508 l␍b␍263.6016 269.7959 m␍178.5762 269.7959 l␍178.5762 184.7685 l␍263.6016 184.7685 l␍263.6016 269.7959 l␍b␍178.5940 354.7701 m␍93.5685 354.7701 l␍93.5685 269.7427 l␍178.5940 269.7427 l␍178.5940 354.7701 l␍b␍263.6016 439.8507 m␍178.5762 439.8507 l␍178.5762 354.8232 l␍263.6016 354.8232 l␍263.6016 439.8507 l␍b␍93.5863 609.9053 m␍8.5608 609.9053 l␍8.5608 524.8779 l␍93.5863 524.8779 l␍93.5863 609.9053 l␍b␍93.5863 779.9600 m␍8.5608 779.9600 l␍8.5608 694.9327 l␍93.5863 694.9327 l␍93.5863 779.9600 l␍b␍178.5940 524.8868 m␍93.5685 524.8868 l␍93.5685 439.8594 l␍178.5940 439.8594 l␍178.5940 524.8868 l␍b␍263.6371 609.9319 m␍178.6116 609.9319 l␍178.6116 524.9045 l␍263.6371 524.9045 l␍263.6371 609.9319 l␍b␍178.6293 694.9062 m␍93.6040 694.9062 l␍93.6040 609.8788 l␍178.6293 609.8788 l␍178.6293 694.9062 l␍b␍263.6371 779.9866 m␍178.6116 779.9866 l␍178.6116 694.9592 l␍263.6371 694.9592 l␍263.6371 779.9866 l␍b␍348.6624 184.7375 m␍263.6371 184.7375 l␍263.6371 99.7102 l␍348.6624 99.7102 l␍348.6624 184.7375 l␍b␍433.7055 269.7826 m␍348.6802 269.7826 l␍348.6802 184.7552 l␍433.7055 184.7552 l␍433.7055 269.7826 l␍b␍348.6447 354.8100 m␍263.6193 354.8100 l␍263.6193 269.7826 l␍348.6447 269.7826 l␍348.6447 354.8100 l␍b␍433.7055 439.8374 m␍348.6802 439.8374 l␍348.6802 354.8100 l␍433.7055 354.8100 l␍433.7055 439.8374 l␍b␍518.7132 184.7641 m␍433.6879 184.7641 l␍433.6879 99.7368 l␍518.7132 99.7368 l␍518.7132 184.7641 l␍b␍603.7563 269.8092 m␍518.7310 269.8092 l␍518.7310 184.7818 l␍603.7563 184.7818 l␍603.7563 269.8092 l␍b␍518.7487 354.7834 m␍433.7232 354.7834 l␍433.7232 269.7560 l␍518.7487 269.7560 l␍518.7487 354.7834 l␍b␍603.7563 439.8639 m␍518.7310 439.8639 l␍518.7310 354.8365 l␍603.7563 354.8365 l␍603.7563 439.8639 l␍b␍348.6979 524.8735 m␍263.6725 524.8735 l␍263.6725 439.8462 l␍348.6979 439.8462 l␍348.6979 524.8735 l␍b␍433.7410 609.9185 m␍348.7156 609.9185 l␍348.7156 524.8913 l␍433.7410 524.8913 l␍433.7410 609.9185 l␍b␍348.6802 694.9460 m␍263.6548 694.9460 l␍263.6548 609.9185 l␍348.6802 609.9185 l␍348.6802 694.9460 l␍b␍433.7410 779.9733 m␍348.7156 779.9733 l␍348.7156 694.9460 l␍433.7410 694.9460 l␍433.7410 779.9733 l␍b␍518.7487 524.9001 m␍433.7232 524.9001 l␍433.7232 439.8727 l␍518.7487 439.8727 l␍518.7487 524.9001 l␍b␍603.7918 609.9452 m␍518.7664 609.9452 l␍518.7664 524.9178 l␍603.7918 524.9178 l␍603.7918 609.9452 l␍b␍518.7841 694.9194 m␍433.7587 694.9194 l␍433.7587 609.8920 l␍518.7841 609.8920 l␍518.7841 694.9194 l␍b␍603.7918 779.9999 m␍518.7664 779.9999 l␍518.7664 694.9725 l␍603.7918 694.9725 l␍603.7918 779.9999 l␍b␍93.5608 99.6839 m␍8.5355 99.6839 l␍8.5355 14.6566 l␍93.5608 14.6566 l␍93.5608 99.6839 l␍b␍263.6116 99.7106 m␍178.5862 99.7106 l␍178.5862 14.6832 l␍263.6116 14.6832 l␍263.6116 99.7106 l␍b␍433.7155 99.6972 m␍348.6902 99.6972 l␍348.6902 14.6699 l␍433.7155 14.6699 l␍433.7155 99.6972 l␍b␍603.7663 99.7239 m␍518.7410 99.7239 l␍518.7410 14.6965 l␍603.7663 14.6965 l␍603.7663 99.7239 l␍b␍EMC␍EX␍␍endstream␍endobj␍9 0 obj␍3422 ␍endobj␍3 0 obj␍<<␍/Type /Page␍/Parent 4 0 R␍/Contents 8 0 R␍/Resources <<␍/ProcSet [ /PDF ]␍>>␍/Rotate 0␍/MediaBox [ 0 0 612 792 ]␍/CropBox [ 0 0 612 792 ]␍/PieceInfo <</Illustrator7.0 <</LastModified (D:19990908151621)>> >>␍>>␍endobj␍1 0 obj␍<<␍/CreationDate (D:19990908151621)␍/ModDate (D:19990908151621)␍/Creator (Adobe Illustrator 7.0)␍/Producer (Acrobat PDF File Format 1.1 for Windows)␍/Author (Unknown)␍>>␍endobj␍xref␍0 1 ␍0000000000 65535 f ␍1 1 ␍0000004478 00000 n ␍3 1 ␍0000004250 00000 n ␍8 2 ␍0000000754 00000 n ␍0000004229 00000 n ␍trailer␍<<␍/Size 10 ␍/Prev 516 ␍/Root 2 0 R␍/Info 1 0 R␍>>␍startxref␍4663 ␍%%EOF␍
+12 -4
View File
@@ -5,18 +5,19 @@ OpenPose Calibration Module and Demo
1. [Introduction](#introduction)
2. [Installing the Calibration Module](#installing-the-calibration-module)
3. [Quick Start](#quick-start)
4. [Using a Different Camera Brand](#using-a-different-camera-brand)
## Introduction
This experimental module performs camera calibration (distortion, intrinsic, and extrinsic camera parameter extraction). It computes and saves the intrinsics parameters of the input images. It is built on top of OpenCV, but aimed to simplify the process for people with no calibration or computer vision background at all (or for lazy people like myself).
Note: We are not aiming to have the best calibration toolbox, but the simplest one. If very high quality calibration is required, I am sure there must exist many other toolboxs with better extrinsic parameter estimation tools.
## Installing the OpenPose 3-D Reconstruction Module
Install OpenPose following [doc/installation.md](./installation.md#3d-reconstruction-module). In addition, you must enable the `WITH_EIGEN` flag when running CMake. You can either set it to:
1. `APT_GET` if you download it with `sudo apt-get install libeigen3-dev` (Ubuntu only).
2. `BUILD` if you want to let OpenPose download it and keep it inside the OpenPose folder (no installation nor extra steps required).
Check [doc/installation.md#calibration-module](./installation.md#calibration-module) for installation steps.
@@ -25,7 +26,7 @@ Note: This example will assume that the target are 3 Flir/Point Grey cameras, bu
1. Distortion and intrinsic parameter calibration:
1. Run OpenPose and save images for your desired camera. Use a grid (chessboard) pattern and move around all the image area. I.e., cover several distances, and within each distance, cover all parts of the image view (all corners and center). You should get at least 100-150 images for a good calibration. Note: we recommend saving the images in PNG format (default behavior) in order to improve calibration quality.
1. Webcam calibration: `./build/examples/openpose/openpose.bin --num_gpu 0 --write_images {intrinsic_images_folder_path}`.
1. Webcam calibration: `./build/examples/openpose/openpose.bin --num_gpu 0 --frame_keep_distortion --write_images {intrinsic_images_folder_path}`.
2. Flir camera calibration: Add the flags `--flir_camera --flir_camera_index 0` (or the desired flir camera index) to the webcam command.
3. Calibration from video sequence: Add the flag `--video {video_path}` to the webcam command.
4. Any other camera brand: Simply save your images in {intrinsic_images_folder_path}, file names are not relevant.
@@ -39,6 +40,13 @@ Note: This example will assume that the target are 3 Flir/Point Grey cameras, bu
```
4. In this case, the intrinsic parameters would have been generated as {intrinsic_images_folder_path}/18079958.xml.
5. Run steps 1-4 for each one of your cameras.
6. After you calibrate the camera intrinsics, when you run OpenPose with those cameras, you should see the lines in real-life to be (almost) perfect lines in the image. Otherwise, the calibration was not good. Try checking straight patterns such us wall corners or ceilings:
```
# With distortion (lines might seem with a more circular shape)
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 0 --frame_keep_distortion
# Without distortion (lines should look as lines)
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 0
```
2. Extrinsic parameter calibration:
1. We are still implementing this part. Documentation will be available after completing it.
+1 -1
View File
@@ -150,7 +150,7 @@ Each flag is divided into flag name, default value, and description.
- DEFINE_bool(frames_repeat, false, "Repeat frames when finished.");
- DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is too long, it will skip frames. If it is too fast, it will slow it down.");
- DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
- DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e., it will leave it as it is.");
3. OpenPose
- DEFINE_string(model_folder, "models/", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
- DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the input image resolution.");
+20 -5
View File
@@ -15,11 +15,12 @@ OpenPose - Installation
2. [MPI Model](#mpi-model)
3. [CPU Version](#cpu-version)
4. [3D Reconstruction Module](#3d-reconstruction-module)
5. [Compiling without cuDNN](#compiling-without-cudnn)
6. [Custom Caffe (Ubuntu Only)](#custom-caffe-ubuntu-only)
7. [Custom OpenCV (Ubuntu Only)](#custom-opencv-ubuntu-only)
8. [Doxygen Documentation Autogeneration (Ubuntu Only)](#doxygen-documentation-autogeneration-ubuntu-only)
9. [CMake Command Line Configuration (Ubuntu Only)](#cmake-command-line-configuration-ubuntu-only)
5. [Calibration Module](#calibration-module)
6. [Compiling without cuDNN](#compiling-without-cudnn)
7. [Custom Caffe (Ubuntu Only)](#custom-caffe-ubuntu-only)
8. [Custom OpenCV (Ubuntu Only)](#custom-opencv-ubuntu-only)
9. [Doxygen Documentation Autogeneration (Ubuntu Only)](#doxygen-documentation-autogeneration-ubuntu-only)
10. [CMake Command Line Configuration (Ubuntu Only)](#cmake-command-line-configuration-ubuntu-only)
@@ -119,6 +120,13 @@ The instructions in this section describe the steps to build OpenPose using CMak
- [Caffe](http://posefs1.perception.cs.cmu.edu/OpenPose/3rdparty/windows/caffe_2018_01_18.zip): Unzip as `3rdparty/windows/caffe/`.
- [Caffe dependencies](http://posefs1.perception.cs.cmu.edu/OpenPose/3rdparty/windows/caffe3rdparty_2017_07_14.zip): Unzip as `3rdparty/windows/caffe3rdparty/`.
- [OpenCV 3.1](http://posefs1.perception.cs.cmu.edu/OpenPose/3rdparty/windows/opencv_310.zip): Unzip as `3rdparty/windows/opencv/`.
5. **Eigen prerequisite**:
- Note: This step is optional, only required for some specific extra functionality, such as extrinsic camera calibration.
- If you enable the `WITH_EIGEN` flag when running CMake. You can either:
1. Do not do anything if you set the `WITH_EIGEN` flag to `BUILD`, CMake will automatically download Eigen. Alternatively, you might prefer to download it manually:
- [Eigen3](http://posefs1.perception.cs.cmu.edu/OpenPose/3rdparty/eigen_2018_05_23.zip): Unzip as `3rdparty/eigen/`.
2. Run `sudo apt-get install libeigen3-dev` (Ubuntu only) if you prefer to set `WITH_EIGEN` to `APT_GET` (Ubuntu only).
3. Use your own version of Eigen by setting `WITH_EIGEN` to `BUILD`, run CMake so that OpenPose downloads the zip file, and then replace the contents of `3rdparty/eigen/` by your own version.
@@ -276,6 +284,13 @@ After installation, check the [doc/3d_reconstruction_demo.md](./3d_reconstructio
#### Calibration Module
The calibration module is included by default, but you must also enable `WITH_EIGEN` if you intend to use the extrinsic camera parameter estimation tool. You can set that flag to 2 different values: `APT_GET` or `BUILD`, check [Requirements](#requirements) for more information.
After installation, check the [doc/calibration_demo.md](./calibration_demo.md) instructions.
#### Compiling without cuDNN
The [cuDNN](https://developer.nvidia.com/cudnn) library is not mandatory, but required for full keypoint detection accuracy. In case your graphics card is not compatible with cuDNN, you can disable it by unchecking `USE_CUDNN` in CMake.
+10 -8
View File
@@ -217,14 +217,15 @@ OpenPose Library - Release Notes
2. Flir cameras: Added software trigger and a dedicated thread to keep reading images so latency is removed and runtime is faster (analogously to webcamReader).
3. Flir cameras: Undistortion of the images is x3.5 faster per camera, i.e., x3.5 Flir camera producer reading (it was multi-threaded).
4. Flir cameras: Added flag `flir_camera_index` to allow running on all the cameras at once, or only on 1 camera at the time.
5. 3-D reconstruction: Added non-linear minimization to further improve 3-D triangulation accuracy by ~5% (Ubuntu only).
6. CMake: All libraries as single variable (simpler to add/remove libraries).
7. Datum includes extrinsic and intrinsic camera parameters.
8. Function `scaleKeypoints(Array<float>& keypoints, const float scale)` also accepts 3D keypoints.
9. 3D keypoints and camera parameters in meters (instead of millimeters) in order to reduce numerical errors.
10. New `PoseExtractor` class to contain future ID and tracking algorithms as well as the current OpenPose keypoint detection algorithm.
11. Added initial alpha versions of the `tracking` and `identification` modules (for now disabled but available in the source code), including `PersonIdExtractor` and `PersonTracker`. `PersonIdExtractor` includes greedy matrix OP-LK matching.
12. Added catchs to all demos for higher debug information.
5. Flir cameras: Added flag `frame_keep_distortion` not to undistort the images. E.g., useful when recording images for camera calibration.
6. 3-D reconstruction: Added non-linear minimization to further improve 3-D triangulation accuracy by ~5% (Ubuntu only).
7. CMake: All libraries as single variable (simpler to add/remove libraries).
8. Datum includes extrinsic and intrinsic camera parameters.
9. Function `scaleKeypoints(Array<float>& keypoints, const float scale)` also accepts 3D keypoints.
10. 3D keypoints and camera parameters in meters (instead of millimeters) in order to reduce numerical errors.
11. New `PoseExtractor` class to contain future ID and tracking algorithms as well as the current OpenPose keypoint detection algorithm.
12. Added initial alpha versions of the `tracking` and `identification` modules (for now disabled but available in the source code), including `PersonIdExtractor` and `PersonTracker`. `PersonIdExtractor` includes greedy matrix OP-LK matching.
13. Added catchs to all demos for higher debug information.
2. Functions or parameters renamed:
1. Removed scale parameter from hand and face rectangle extractor (causing wrong results if custom `--output_resolution`).
2. Functions `scaleKeypoints`, other than `scaleKeypoints(Array<float>& keypoints, const float scale)`, renamed as `scaleKeypoints2d`.
@@ -234,6 +235,7 @@ OpenPose Library - Release Notes
1. Fixed hand and face extraction and rendering scaling issues when `--output_resolution` is not the default one.
2. Part candidates (`--part_candidates`) are saved with the same scale than the final keypoints itself.
3. Fixed bug in keepTopNPeople.hpp (`--number_people_max`) that provoked core dumped if lots of values equal to the threshold.
4. Flir cameras: Cameras sorted by serial number. Video and images recorded from flir cameras were (and are) assigned the camera parameters based on serial number order, so it would fail if the cameras order was not the same than if sorted by serial number.
+4 -1
View File
@@ -68,6 +68,9 @@ DEFINE_bool(frames_repeat, false, "Repeat frames when fini
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(model_folder, "models/", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
@@ -253,7 +256,7 @@ int openPoseDemo()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
// poseModel
const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
@@ -77,6 +77,9 @@ DEFINE_bool(frames_repeat, false, "Repeat frames when fini
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(model_folder, "models/", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
@@ -251,7 +254,7 @@ int openPoseTutorialWrapper4()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
// poseModel
const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
@@ -48,6 +48,9 @@ DEFINE_string(ip_camera, "", "String with the IP came
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
" input image resolution.");
@@ -78,7 +81,7 @@ int openPoseTutorialThread1()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
const auto displayProducerFpsMode = (FLAGS_process_real_time
? op::ProducerFpsMode::OriginalFps : op::ProducerFpsMode::RetrievalFps);
@@ -49,6 +49,9 @@ DEFINE_string(ip_camera, "", "String with the IP came
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
" input image resolution.");
@@ -112,7 +115,7 @@ int openPoseTutorialThread2()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
const auto displayProducerFpsMode = (FLAGS_process_real_time
? op::ProducerFpsMode::OriginalFps : op::ProducerFpsMode::RetrievalFps);
@@ -68,6 +68,9 @@ DEFINE_bool(frames_repeat, false, "Repeat frames when fini
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(model_folder, "models/", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
@@ -296,7 +299,7 @@ int openPoseDemo()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
// poseModel
const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
@@ -68,6 +68,9 @@ DEFINE_bool(frames_repeat, false, "Repeat frames when fini
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(model_folder, "models/", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
@@ -331,7 +334,7 @@ int openPoseDemo()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
// poseModel
const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
@@ -68,6 +68,9 @@ DEFINE_bool(frames_repeat, false, "Repeat frames when fini
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(model_folder, "models/", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
@@ -343,7 +346,7 @@ int openPoseDemo()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
// poseModel
const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
@@ -67,6 +67,9 @@ DEFINE_bool(frames_repeat, false, "Repeat frames when fini
DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is"
" too long, it will skip frames. If it is too fast, it will slow it down.");
DEFINE_string(camera_parameter_folder, "models/cameraParameters/flir/", "String with the folder where the camera parameters are located.");
DEFINE_bool(frame_keep_distortion, false, "If false (default), it will undistortionate the image based on the"
" `camera_parameter_folder` camera parameters; if true, it will not undistortionate, i.e.,"
" it will leave it as it is.");
// OpenPose
DEFINE_string(model_folder, "models/", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
DEFINE_string(output_resolution, "-1x-1", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
@@ -326,7 +329,7 @@ int openPoseTutorialWrapper1()
// producerType
const auto producerSharedPtr = op::flagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_ip_camera, FLAGS_camera,
FLAGS_flir_camera, FLAGS_camera_resolution, FLAGS_camera_fps,
FLAGS_camera_parameter_folder,
FLAGS_camera_parameter_folder, !FLAGS_frame_keep_distortion,
(unsigned int) FLAGS_3d_views, FLAGS_flir_camera_index);
// poseModel
const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
+2 -3
View File
@@ -18,12 +18,11 @@ namespace op
/**
* Constructor of FlirReader. It opens all the available FLIR cameras
*/
explicit FlirReader(const std::string& cameraParametersPath, const Point<int>& cameraResolution);
explicit FlirReader(const std::string& cameraParametersPath, const Point<int>& cameraResolution,
const bool undistortImage = true, const int cameraIndex = -1);
~FlirReader();
void setCameraIndex(const int cameraIndex);
std::vector<cv::Mat> getCameraMatrices();
std::vector<cv::Mat> getCameraExtrinsics();
@@ -14,13 +14,13 @@ namespace op
public:
/**
* Constructor of SpinnakerWrapper. It opens all the available FLIR cameras
* cameraIndex = -1 means that all cameras are taken
*/
explicit SpinnakerWrapper(const std::string& cameraParameterPath, const Point<int>& cameraResolution);
explicit SpinnakerWrapper(const std::string& cameraParameterPath, const Point<int>& cameraResolution,
const bool undistortImage, const int cameraIndex = -1);
~SpinnakerWrapper();
void setCameraIndex(const int cameraIndex);
std::vector<cv::Mat> getRawFrames();
std::vector<cv::Mat> getCameraMatrices() const;
@@ -26,6 +26,7 @@ namespace op
const std::string& cameraResolution = "-1x-1",
const double webcamFps = 30.,
const std::string& cameraParameterPath = "models/cameraParameters/",
const bool undistortImage = true,
const unsigned int imageDirectoryStereo = 1,
const int flirCameraIndex = -1);
+3 -14
View File
@@ -4,9 +4,10 @@
namespace op
{
FlirReader::FlirReader(const std::string& cameraParametersPath, const Point<int>& cameraResolution) :
FlirReader::FlirReader(const std::string& cameraParametersPath, const Point<int>& cameraResolution,
const bool undistortImage, const int cameraIndex) :
Producer{ProducerType::FlirCamera},
mSpinnakerWrapper{cameraParametersPath, cameraResolution},
mSpinnakerWrapper{cameraParametersPath, cameraResolution, undistortImage, cameraIndex},
mFrameNameCounter{0}
{
try
@@ -35,18 +36,6 @@ namespace op
}
}
void FlirReader::setCameraIndex(const int cameraIndex)
{
try
{
return mSpinnakerWrapper.setCameraIndex(cameraIndex);
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
std::vector<cv::Mat> FlirReader::getCameraMatrices()
{
try
+197 -121
View File
@@ -11,35 +11,97 @@
namespace op
{
#ifdef WITH_FLIR_CAMERA
std::vector<std::string> getSerialNumbers(const Spinnaker::CameraList& cameraList,
const bool sorted)
{
try
{
// Get strSerialNumbers
std::vector<Spinnaker::GenICam::gcstring> strSerialNumbers(cameraList.GetSize());
for (auto i = 0u; i < strSerialNumbers.size(); i++)
{
// Select camera
auto cameraPtr = cameraList.GetByIndex(i);
strSerialNumbers[i] = "";
Spinnaker::GenApi::CStringPtr ptrStringSerial = cameraPtr->GetTLDeviceNodeMap().GetNode(
"DeviceSerialNumber"
);
if (Spinnaker::GenApi::IsAvailable(ptrStringSerial)
&& Spinnaker::GenApi::IsReadable(ptrStringSerial))
{
strSerialNumbers[i] = ptrStringSerial->GetValue();
}
}
// Spinnaker::GenICam::gcstring to std::string
std::vector<std::string> serialNumbers(strSerialNumbers.size());
for (auto i = 0u ; i < serialNumbers.size() ; i++)
serialNumbers[i] = strSerialNumbers[i];
// Sort serial numbers
if (sorted)
std::sort(serialNumbers.begin(), serialNumbers.end());
// Return result
return serialNumbers;
}
catch (Spinnaker::Exception &e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
return {};
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
return {};
}
}
// This function prints the device information of the camera from the transport
// layer; please see NodeMapInfo example for more in-depth comments on printing
// device information from the nodemap.
int printDeviceInfo(Spinnaker::GenApi::INodeMap &iNodeMap, const unsigned int camNum)
{
int result = 0;
log("Printing device information for camera " + std::to_string(camNum) + "...\n", Priority::High);
Spinnaker::GenApi::FeatureList_t features;
Spinnaker::GenApi::CCategoryPtr cCategoryPtr = iNodeMap.GetNode("DeviceInformation");
if (Spinnaker::GenApi::IsAvailable(cCategoryPtr) && Spinnaker::GenApi::IsReadable(cCategoryPtr))
try
{
cCategoryPtr->GetFeatures(features);
int result = 0;
Spinnaker::GenApi::FeatureList_t::const_iterator it;
for (it = features.begin(); it != features.end(); ++it)
log("Printing device information for camera " + std::to_string(camNum) + "...\n", Priority::High);
Spinnaker::GenApi::FeatureList_t features;
Spinnaker::GenApi::CCategoryPtr cCategoryPtr = iNodeMap.GetNode("DeviceInformation");
if (Spinnaker::GenApi::IsAvailable(cCategoryPtr) && Spinnaker::GenApi::IsReadable(cCategoryPtr))
{
Spinnaker::GenApi::CNodePtr pfeatureNode = *it;
const auto cValuePtr = (Spinnaker::GenApi::CValuePtr)pfeatureNode;
log(pfeatureNode->GetName() + " : " +
(IsReadable(cValuePtr) ? cValuePtr->ToString() : "Node not readable"), Priority::High);
}
}
else
log("Device control information not available.", Priority::High);
log(" ", Priority::High);
cCategoryPtr->GetFeatures(features);
return result;
Spinnaker::GenApi::FeatureList_t::const_iterator it;
for (it = features.begin(); it != features.end(); ++it)
{
Spinnaker::GenApi::CNodePtr pfeatureNode = *it;
const auto cValuePtr = (Spinnaker::GenApi::CValuePtr)pfeatureNode;
log(pfeatureNode->GetName() + " : " +
(IsReadable(cValuePtr) ? cValuePtr->ToString() : "Node not readable"), Priority::High);
}
}
else
log("Device control information not available.", Priority::High);
log(" ", Priority::High);
return result;
}
catch (Spinnaker::Exception &e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
return -1;
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
return -1;
}
}
// This function returns the camera to a normal state by turning off trigger
@@ -287,9 +349,11 @@ namespace op
Spinnaker::CameraList mCameraList;
Spinnaker::SystemPtr mSystemPtr;
std::vector<cv::Mat> mCvMats;
std::vector<std::string> mSerialNumbers;
// Camera index
int mCameraIndex;
const int mCameraIndex;
// Undistortion
const bool mUndistortImage;
std::vector<cv::Mat> mRemoveDistortionMaps1;
std::vector<cv::Mat> mRemoveDistortionMaps2;
// Thread
@@ -299,14 +363,16 @@ namespace op
std::atomic<bool> mCloseThread;
std::thread mThread;
ImplSpinnakerWrapper() :
ImplSpinnakerWrapper(const bool undistortImage, const int cameraIndex) :
mInitialized{false},
mCameraIndex{-1}
mCameraIndex{cameraIndex},
mUndistortImage{undistortImage}
{
}
void undistortImage(const int i, const Spinnaker::ImagePtr& imagePtr,
const cv::Mat& cameraIntrinsics, const cv::Mat& cameraDistorsions)
void readAndUndistortImage(const int i, const Spinnaker::ImagePtr& imagePtr,
const cv::Mat& cameraIntrinsics = cv::Mat(),
const cv::Mat& cameraDistorsions = cv::Mat())
{
try
{
@@ -315,42 +381,49 @@ namespace op
// Spinnaker to cv::Mat
const auto cvMatDistorted = spinnakerWrapperToCvMat(imagePtrColor);
// const auto cvMatDistorted = spinnakerWrapperToCvMat(imagePtr);
// Baseline
// mCvMats[i] = cvMatDistorted.clone();
// Undistort
// // Option a - 80 ms / 3 images
// // http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#undistort
// cv::undistort(cvMatDistorted, mCvMats[i], cameraIntrinsics, cameraDistorsions);
// // In OpenCV 2.4, cv::undistort is exactly equal than cv::initUndistortRectifyMap
// (with CV_16SC2) + cv::remap (with LINEAR). I.e., log(cv::norm(cvMatMethod1-cvMatMethod2)) = 0.
// Option b - 15 ms / 3 images (LINEAR) or 25 ms (CUBIC)
// Distorsion removal - not required and more expensive (applied to the whole image instead of
// only to our interest points)
if (mRemoveDistortionMaps1[i].empty() || mRemoveDistortionMaps2[i].empty())
if (mUndistortImage)
{
const auto imageSize = cvMatDistorted.size();
cv::initUndistortRectifyMap(cameraIntrinsics,
cameraDistorsions,
cv::Mat(),
// cameraIntrinsics instead of cv::getOptimalNewCameraMatrix to
// avoid black borders
cameraIntrinsics,
// cv::getOptimalNewCameraMatrix(cameraIntrinsics,
// cameraDistorsions,
// imageSize, 1,
// imageSize, 0),
imageSize,
CV_16SC2, // Faster, less memory
// CV_32FC1, // More accurate
mRemoveDistortionMaps1[i],
mRemoveDistortionMaps2[i]);
// Security check
if (cameraIntrinsics.empty() || cameraDistorsions.empty())
error("Camera intrinsics/distortions were empty.", __LINE__, __FUNCTION__, __FILE__);
// // Option a - 80 ms / 3 images
// // http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#undistort
// cv::undistort(cvMatDistorted, mCvMats[i], cameraIntrinsics, cameraDistorsions);
// // In OpenCV 2.4, cv::undistort is exactly equal than cv::initUndistortRectifyMap
// (with CV_16SC2) + cv::remap (with LINEAR). I.e., log(cv::norm(cvMatMethod1-cvMatMethod2)) = 0.
// Option b - 15 ms / 3 images (LINEAR) or 25 ms (CUBIC)
// Distorsion removal - not required and more expensive (applied to the whole image instead of
// only to our interest points)
if (mRemoveDistortionMaps1[i].empty() || mRemoveDistortionMaps2[i].empty())
{
const auto imageSize = cvMatDistorted.size();
cv::initUndistortRectifyMap(cameraIntrinsics,
cameraDistorsions,
cv::Mat(),
// cameraIntrinsics instead of cv::getOptimalNewCameraMatrix to
// avoid black borders
cameraIntrinsics,
// cv::getOptimalNewCameraMatrix(cameraIntrinsics,
// cameraDistorsions,
// imageSize, 1,
// imageSize, 0),
imageSize,
CV_16SC2, // Faster, less memory
// CV_32FC1, // More accurate
mRemoveDistortionMaps1[i],
mRemoveDistortionMaps2[i]);
}
cv::remap(cvMatDistorted, mCvMats[i],
mRemoveDistortionMaps1[i], mRemoveDistortionMaps2[i],
// cv::INTER_NEAREST);
cv::INTER_LINEAR);
// cv::INTER_CUBIC);
// cv::INTER_LANCZOS4); // Smoother, but we do not need this quality & its >>expensive
}
cv::remap(cvMatDistorted, mCvMats[i],
mRemoveDistortionMaps1[i], mRemoveDistortionMaps2[i],
// cv::INTER_NEAREST);
cv::INTER_LINEAR);
// cv::INTER_CUBIC);
// cv::INTER_LANCZOS4); // Smoother, but we do not need this quality & its >>expensive
// Baseline (do not undistort)
else
mCvMats[i] = cvMatDistorted.clone();
}
catch (const std::exception& e)
{
@@ -367,7 +440,8 @@ namespace op
// Get cameras - ~0.005 ms (3 cameras)
std::vector<Spinnaker::CameraPtr> cameraPtrs(mCameraList.GetSize());
for (auto i = 0u; i < cameraPtrs.size(); i++)
cameraPtrs.at(i) = mCameraList.GetByIndex(i);
cameraPtrs.at(i) = mCameraList.GetBySerial(mSerialNumbers.at(i)); // Sorted by Serial Number
// cameraPtrs.at(i) = mCameraList.GetByIndex(i); // Sorted by however Spinnaker decided
while (!mCloseThread)
{
// Trigger
@@ -495,22 +569,32 @@ namespace op
// All cameras
if (cameraIndex < 0)
{
std::vector<std::thread> threads(imagePtrs.size()-1);
for (auto i = 0u; i < imagePtrs.size()-1; i++)
// Undistort image
if (mUndistortImage)
{
// Multi-thread option
threads.at(i) = std::thread{&ImplSpinnakerWrapper::undistortImage, this, i,
imagePtrs.at(i), cameraIntrinsics.at(i),
cameraDistorsions.at(i)};
// // Single-thread option
// undistortImage(i, imagePtrs.at(i), cameraIntrinsics.at(i), cameraDistorsions.at(i));
std::vector<std::thread> threads(imagePtrs.size()-1);
for (auto i = 0u; i < imagePtrs.size()-1; i++)
{
// Multi-thread option
threads.at(i) = std::thread{&ImplSpinnakerWrapper::readAndUndistortImage, this, i,
imagePtrs.at(i), cameraIntrinsics.at(i),
cameraDistorsions.at(i)};
// // Single-thread option
// readAndUndistortImage(i, imagePtrs.at(i), cameraIntrinsics.at(i), cameraDistorsions.at(i));
}
readAndUndistortImage(imagePtrs.size()-1, imagePtrs.back(), cameraIntrinsics.back(),
cameraDistorsions.back());
// Close threads
for (auto& thread : threads)
if (thread.joinable())
thread.join();
}
// Do not undistort image
else
{
for (auto i = 0u; i < imagePtrs.size(); i++)
readAndUndistortImage(i, imagePtrs.at(i));
}
undistortImage(imagePtrs.size()-1, imagePtrs.back(), cameraIntrinsics.back(),
cameraDistorsions.back());
// Close threads
for (auto& thread : threads)
if (thread.joinable())
thread.join();
}
// Only 1 camera
else
@@ -523,8 +607,12 @@ namespace op
+ std::to_string(cameraIndex) +"`), which doesn't exist. Note that the index is"
+ " 0-based.", __LINE__, __FUNCTION__, __FILE__);
// Undistort image
undistortImage(cameraIndex, imagePtrs.at(cameraIndex), cameraIntrinsics.at(cameraIndex),
cameraDistorsions.at(cameraIndex));
if (mUndistortImage)
readAndUndistortImage(cameraIndex, imagePtrs.at(cameraIndex), cameraIntrinsics.at(cameraIndex),
cameraDistorsions.at(cameraIndex));
// Do not undistort image
else
readAndUndistortImage(cameraIndex, imagePtrs.at(cameraIndex));
mCvMats = std::vector<cv::Mat>{mCvMats[cameraIndex]};
}
}
@@ -544,9 +632,10 @@ namespace op
#endif
};
SpinnakerWrapper::SpinnakerWrapper(const std::string& cameraParameterPath, const Point<int>& resolution)
SpinnakerWrapper::SpinnakerWrapper(const std::string& cameraParameterPath, const Point<int>& resolution,
const bool undistortImage, const int cameraIndex)
#ifdef WITH_FLIR_CAMERA
: upImpl{new ImplSpinnakerWrapper{}}
: upImpl{new ImplSpinnakerWrapper{undistortImage, cameraIndex}}
#endif
{
#ifdef WITH_FLIR_CAMERA
@@ -566,7 +655,7 @@ namespace op
// Retrieve list of cameras from the upImpl->mSystemPtr
upImpl->mCameraList = upImpl->mSystemPtr->GetCameras();
unsigned int numCameras = upImpl->mCameraList.GetSize();
const unsigned int numCameras = upImpl->mCameraList.GetSize();
log("Number of cameras detected: " + std::to_string(numCameras), Priority::High);
@@ -579,8 +668,8 @@ namespace op
// Release upImpl->mSystemPtr
upImpl->mSystemPtr->ReleaseInstance();
log("Not enough cameras!\nPress Enter to exit...", Priority::High);
getchar();
// log("Not enough cameras!\nPress Enter to exit...", Priority::High);
// getchar();
error("No cameras detected.", __LINE__, __FUNCTION__, __FILE__);
}
@@ -671,8 +760,7 @@ namespace op
//
// Serial numbers are the only persistent objects we gather in this
// example, which is why a std::vector is created.
std::vector<Spinnaker::GenICam::gcstring> strSerialNumbers(upImpl->mCameraList.GetSize());
for (auto i = 0u; i < strSerialNumbers.size(); i++)
for (auto i = 0; i < upImpl->mCameraList.GetSize(); i++)
{
// Select camera
auto cameraPtr = upImpl->mCameraList.GetByIndex(i);
@@ -692,7 +780,7 @@ namespace op
error("Unable to set acquisition mode to continuous (entry 'continuous' retrieval "
+ std::to_string(i) + "). Aborting...", __LINE__, __FUNCTION__, __FILE__);
int64_t acquisitionModeContinuous = ptrAcquisitionModeContinuous->GetValue();
const int64_t acquisitionModeContinuous = ptrAcquisitionModeContinuous->GetValue();
ptrAcquisitionMode->SetIntValue(acquisitionModeContinuous);
@@ -740,29 +828,31 @@ namespace op
cameraPtr->BeginAcquisition();
log("Camera " + std::to_string(i) + " started acquiring images...", Priority::High);
// Retrieve device serial number for filename
strSerialNumbers[i] = "";
Spinnaker::GenApi::CStringPtr ptrStringSerial = cameraPtr->GetTLDeviceNodeMap().GetNode(
"DeviceSerialNumber"
);
if (Spinnaker::GenApi::IsAvailable(ptrStringSerial)
&& Spinnaker::GenApi::IsReadable(ptrStringSerial))
{
strSerialNumbers[i] = ptrStringSerial->GetValue();
log("Camera " + std::to_string(i) + " serial number set to "
+ strSerialNumbers[i].c_str() + "...", Priority::High);
}
log(" ", Priority::High);
}
// Retrieve device serial number for filename
log("\nReading (and sorting by) serial numbers...", Priority::High);
const bool sorted = true;
upImpl->mSerialNumbers = getSerialNumbers(upImpl->mCameraList, sorted);
const auto& serialNumbers = upImpl->mSerialNumbers;
for (auto i = 0u; i < serialNumbers.size(); i++)
log("Camera " + std::to_string(i) + " serial number set to "
+ serialNumbers[i] + "...", Priority::High);
// Read camera parameters from SN
std::vector<std::string> serialNumbers(strSerialNumbers.size());
for (auto i = 0u ; i < serialNumbers.size() ; i++)
serialNumbers[i] = strSerialNumbers[i];
upImpl->mCameraParameterReader.readParameters(cameraParameterPath, serialNumbers);
if (upImpl->mUndistortImage)
{
// If all images required
if (upImpl->mCameraIndex < 0)
upImpl->mCameraParameterReader.readParameters(cameraParameterPath, serialNumbers);
// If only one required
else
{
upImpl->mCameraParameterReader.readParameters(
cameraParameterPath,
std::vector<std::string>(serialNumbers.size(), serialNumbers.at(upImpl->mCameraIndex)));
}
}
// Start buffering thread
upImpl->mThreadOpened = true;
@@ -790,6 +880,8 @@ namespace op
#else
UNUSED(cameraParameterPath);
UNUSED(resolution);
UNUSED(undistortImage);
UNUSED(cameraIndex);
error(WITH_FLIR_CAMERA_ERROR, __LINE__, __FUNCTION__, __FILE__);
#endif
}
@@ -806,23 +898,6 @@ namespace op
}
}
void SpinnakerWrapper::setCameraIndex(const int cameraIndex)
{
try
{
#ifdef WITH_FLIR_CAMERA
upImpl->mCameraIndex = cameraIndex;
#else
UNUSED(cameraIndex);
error(WITH_FLIR_CAMERA_ERROR, __LINE__, __FUNCTION__, __FILE__);
#endif
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
std::vector<cv::Mat> SpinnakerWrapper::getRawFrames()
{
try
@@ -831,7 +906,8 @@ namespace op
try
{
// Security checks
if ((unsigned long long) upImpl->mCameraList.GetSize()
if (upImpl->mUndistortImage &&
(unsigned long long) upImpl->mCameraList.GetSize()
!= upImpl->mCameraParameterReader.getNumberCameras())
error("The number of cameras must be the same as the INTRINSICS vector size.",
__LINE__, __FUNCTION__, __FILE__);
+4 -4
View File
@@ -142,7 +142,8 @@ namespace op
const std::string& ipCameraPath, const int webcamIndex,
const bool flirCamera, const std::string& cameraResolution,
const double webcamFps, const std::string& cameraParameterPath,
const unsigned int imageDirectoryStereo, const int flirCameraIndex)
const bool undistortImage, const unsigned int imageDirectoryStereo,
const int flirCameraIndex)
{
try
{
@@ -161,9 +162,8 @@ namespace op
{
// cameraFrameSize
const auto cameraFrameSize = flagsToPoint(cameraResolution, "-1x-1");
auto flirReader = std::make_shared<FlirReader>(cameraParameterPath, cameraFrameSize);
flirReader->setCameraIndex(flirCameraIndex);
return flirReader;
return std::make_shared<FlirReader>(cameraParameterPath, cameraFrameSize, undistortImage,
flirCameraIndex);
}
// Webcam
if (type == ProducerType::Webcam)