venerdì 27 novembre 2020

martedì 24 novembre 2020

Luna e Marte

 23 Novembre 2020 Firenze 18:30 




Visualizzatore di nuvole di punti con GLFW e PCL

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

sabato 21 novembre 2020

Realsense SDK con D435 in Debian

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


Oltre alle due camere per la stereoscopia e' presente un illuminatore IR per migliorare il dato di profondita' ed una camera RGB

La distanza massima operativa e' di circa 4m. Come si nota dal video il dato e' molto rumoroso



Un aspetto che mi ha lasciato molto perplesso e' che non risultano essere conservati gli angoli. Per esempio nella realta' l'angolo e' di 90 gradi mentre dalla mesh risulta essere di 105 gradi. Credo che questo sia dovuto al fatto che le lenti sono quasi dei fish-eye



Per quanto rigurda le lunghezza la porta in realta' e' larga 125 cm mentre il sensore la misura circa 105 cm

Diciamo che i dati al centro dell'immagine sono coerenti ma sui bordi 

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


Iphone 12 Pro per la geologia

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



 
Mettendo a confronto Tango con Iphone si nota che entrambi hanno un raggio di scansione massimo tra i 3 ed i 4 metri ma sicuramente la IMU di Iphone e' migliore in quanto spostandosi non decorrela in modo significativo anche su lunghezze superiori ai 10 m

Scansione con Iphone

Scansione con Google Tango Tablet


La cosa che mi impressiona sempre e' come sia possibile ottenere delle misure di lunghezza senza la necessita' di ricalibrare i dati ma questo aspetto e' comune sia a Tango che ad IPhone

Misura di strato : a sinistra di misura reale, a destra misura dal mesh


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 

giovedì 19 novembre 2020

Compilare VTK su WIndows

 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 



e si digita

msbuild /p:Configuration=Debug ALL_BUILD.vcxproj

la compilazione richiede abbastanza tempo

PCL Library e Visual Studio 2019

 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


Per creare un progetto in QT con le PCL si devono aggiungere nella path OpenNI2 (stranamente l'installer non la ha aggiunta nella PATH)

Ho sostituito la versione di CMAKE da quella di default di QT con l'installer di CMake  (modificabile dai Kit di Qt) ed come compilatore ho selezionato MSVC2019



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


Codemotion Online Tech Conference - Italian Edition

  La classica esperienza in cui capisci che il mondo sta andando in direzione opposta al tuo