La classica esperienza in cui capisci che il mondo sta andando in direzione opposta al tuo
Per imparare un po' di librerie mi sono fatto il mio visualizzatore di nuvole di punti
Volevo includere ImGui o NanoGui per settare i valori delle variabili ma non riesco a trovare il modo di compilarli
https://github.com/c1p81/cloudpoint_glfw
La visualizzazione si modifica con i tasti freccia/pg up-down ed il mouse
Dopo un po' di esperienza con i sensori a luce strutturata ho provata il sensore Intel RealSense D435 (attenzione manca la i finale....a differenza al D435i qui non e' presenta la IMU integrata) che funziona come sensore di profondita' usando la stereoscopia di due camere
Il sensore e' nato per applicazioni di robotica ed e' molto veloce nell'acquisizione/elaborazione (circa 30 fps) ma il risultato come dato di profondita' e' molto differente da quello che si ottiene da un sensore a luce strutturata
l'SDK e' nato per Windows e Ubuntu ma si puo' installare su Debian utilizzando Snap
snap install librealsense
Oltre alle librerie si installa anche realsense-viewer da cui e' possibile anche effettuare l'upgrade del firmware della camera
Gli esempi si trovano a https://dev.intelrealsense.com/docs/code-samples
Per compilare gli esempi ho dovuto installare anche la libreria StbEasyFont (e' presente nella directory third parts ma io la ho installata con apt per semplicita')
=================================================
cmake_minimum_required(VERSION 3.5)
project(realsense LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(realsense2 REQUIRED )
add_executable(realsense main.cpp)
target_link_libraries(realsense realsense2)
=================================================
=================================================
#include <iostream>
#include <librealsense2/rs.hpp>
using namespace std;
int main()
{
rs2::pipeline p;
p.start();
rs2::frameset frames = p.wait_for_frames();
rs2::depth_frame depth = frames.get_depth_frame();
float width = depth.get_width();
float height = depth.get_height();
float dist_to_center = depth.get_distance(width / 2, height / 2);
std::cout << "The camera is facing an object " <<
dist_to_center << " meters away" << endl << endl;
return 0;
}
=================================================
Multicam
Nell'esempio Multicam oltre alla libreria Realsense viene usata anche OpenGL con glfw
================================================
cmake_minimum_required(VERSION 3.5)
project(multicam LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# finds OpenGL, GLU and X11
find_package(OpenGL REQUIRED)
if(NOT OPENGL_FOUND)
message("ERROR: OpenGL not found")
endif(NOT OPENGL_FOUND)
set(GL_LIBRARY GL GLU X11)
find_package(realsense2 REQUIRED )
add_executable(multicam main.cpp)
target_link_libraries(multicam realsense2 glfw ${GL_LIBRARY} m)
================================================
Avevo provato tempo fa ad usare il tablet Google Tango per scansionare un affioramento roccioso
Adesso che anche Iphone 12 pro (e Ipad Pro 2020) ha un lidar volevo vedere la possibilita' di usare il telefono di Apple per applicazione geologiche
Scansione con Iphone
Scansione con Google Tango Tablet
Non esiste una applicazione ufficiale per esportare i cloudpoint o la mesh da IPhone ma sono disponibili 3DScanner App, PolyCam e Heges
I dati comunque sono leggibili ed elaboraibili da CloudCompare
Una volta spacchettato il file tar.gz per esempio c:\vtk\src. Si crea una directory build e con CMake-GUI si indica la sorgente in src e ovviamente la build con build usando come target il compilatore di Visual Studio 2019 (viene richiesta la scelta dopo aver premuto Configure)
Al termine si clicca Generate e si aprono gli strumenti di Visual Studio/Developer Command Prompt, si entra nella directory dove e' stato creato il file progetto
Per installare ed usare PCL su Windows la cosa piu' comoda e' utilizzare il pacchetto PCL-1.11.1-AllInOne-msvc2019-win64
Una volta installato il file exe per esempio in C:\Program Files\PCL 1.11.1
il file CMAKE e' il seguente
===============================================
cmake_minimum_required(VERSION 3.5)
project(t3 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(PCL 1.3 REQUIRED COMPONENTS common io features)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(t3 main.cpp)
target_link_libraries(t3 ${PCL_LIBRARIES})
===============================================
mentre un programma di esempio e'
===============================================
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
using namespace std;
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ> ("c://gabriele.pcd", *cloud) == -1) //* load the file
{
PCL_ERROR ("Couldn't read file test_pcd.pcd \n");
return (-1);
}
//std::cout << "Loaded " << cloud->width * cloud->height << " data points from test_pcd.pcd with the following fields: " << std::endl;
/*for (size_t i = 0; i < cloud->points.size (); ++i)
std::cout << " " << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << std::endl;
*/
// Create the normal estimation class, and pass the input dataset to it
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud (cloud);
// Create an empty kdtree representation, and pass it to the normal estimation object.
// Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
ne.setSearchMethod (tree);
// Output datasets
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
// Use all neighbors in a sphere of radius 3cm
ne.setRadiusSearch (0.03);
// Compute the features
ne.compute (*cloud_normals);
//std::cout << endl << cloud_normals->size() << endl;
// cloud_normals->size () should have the same size as the input cloud->size ()*
int i = 0;
for (pcl::Normal n : *cloud_normals) {
//std::cerr << i << " n = " << n.normal_x << ", " << n.normal_y << ", " << n.normal_z << "\n";
std::cout << n.normal_x << "," << n.normal_y << "," << n.normal_z << "\n";
i++;
}
return 0;
}
Visto che puro ML non funziona per le serie tempo di cui mi sto occupando ed le regressioni basate su formule analitiche mostrano dei limiti...