Laboratorio 01

Setup dell’Ambiente — CMake, Eigen e OpenCV

Docente

Obiettivo di Oggi

Prima di scrivere una sola riga del nostro framework, dobbiamo costruire il cantiere. In questo laboratorio configuriamo i tre strumenti che useremo per tutto il corso:

  • CMake: il sistema di build che trasforma i nostri file .cpp in un eseguibile, in modo automatico e indipendente dal sistema operativo.
  • Eigen: la libreria C++ per l’algebra lineare — matrici, vettori, operazioni ottimizzate.
  • OpenCV: la libreria per la visione artificiale — caricheremo e visualizzeremo le immagini MNIST.

Al termine del laboratorio avrete un progetto che compila e stampa il risultato di un prodotto matrice-vettore.

L’Ambiente di Lavoro: Il Compilatore

Per compilare C++17 vi serve un compilatore moderno. Scegliete il vostro sistema:

Linux — tutto già disponibile:

sudo apt install build-essential cmake   # Ubuntu/Debian
sudo dnf install gcc-c++ cmake           # Fedora

macOS — usate Homebrew:

brew install gcc cmake

Il clang++ di Apple funziona, ma gcc via Homebrew è più coerente con Linux.

Windows — il consiglio è WSL 2 (Windows Subsystem for Linux): un terminale Linux reale dentro Windows, senza macchine virtuali:

wsl --install   # installa Ubuntu di default; riavviate poi

Poi seguite le istruzioni Linux. Verificate con g++ --version e cmake --version.

L’Ambiente di Lavoro: L’Editor

Il consiglio è Visual Studio Code — gratuito, multipiattaforma, estensibile.

Estensioni da installare subito dal pannello Extensions:

  • C/C++ (Microsoft) — syntax highlighting, IntelliSense, debugger integrato
  • CMake Tools (Microsoft) — compila con un click dalla barra di stato
  • clangd (opzionale) — autocompletamento più preciso e veloce

Con CMake Tools potete dimenticare i comandi da terminale: il pulsante Build in basso a sinistra compila il progetto. Usate comunque il terminale nelle prime settimane per capire cosa succede sotto.

Installare Eigen

Eigen è header-only: non occorre compilarla. Scegliete il metodo più comodo:

Via package manager (consigliato):

sudo apt install libeigen3-dev    # Linux Ubuntu/Debian
brew install eigen                # macOS

Manualmente (funziona su tutti i sistemi):

  1. Scaricate Eigen da eigen.tuxfamily.org
  2. Copiate la cartella Eigen/ dentro libs/eigen/ nel vostro progetto

Nel CMakeLists.txt punterete agli header con:

# Se installata via package manager:
find_package(Eigen3 REQUIRED)

# Se installata manualmente:
include_directories(libs/eigen)

Installare OpenCV

OpenCV è una libreria compilata: va installata e poi collegata al progetto.

Linux:

sudo apt install libopencv-dev

macOS:

brew install opencv

Windows/WSL: stessa procedura Linux dentro il terminale WSL.

Nel CMakeLists.txt aggiungete:

find_package(OpenCV REQUIRED)
target_link_libraries(mio_prog ${OpenCV_LIBS})

Verificate che OpenCV sia trovata con:

pkg-config --modversion opencv4

Il CMakeLists.txt del Corso

Ecco il file di partenza che useremo e aggiorneremo nel corso delle settimane:

cmake_minimum_required(VERSION 3.15)
project(BasicNeural)

set(CMAKE_CXX_STANDARD 17)

# Eigen
find_package(Eigen3 QUIET)
if(NOT Eigen3_FOUND)
    include_directories(libs/eigen)   # fallback manuale
endif()

# OpenCV
find_package(OpenCV REQUIRED)

add_executable(mio_prog main.cpp)
target_link_libraries(mio_prog ${OpenCV_LIBS})

I tre comandi per compilare e avviare:

cmake -B build
cmake --build build
./build/mio_prog

I Tipi Fondamentali di Eigen

Useremo questi tipi per tutto il corso:

Tipo Cosa rappresenta Esempio
Eigen::MatrixXd Matrice di double, dimensioni dinamiche Pesi di un layer
Eigen::VectorXd Vettore colonna di double Bias, output di un layer
Eigen::ArrayXd Array 1D per operazioni elemento per elemento Funzioni di attivazione

Xd sta per X-dimensionale double. Ci sono varianti float (Xf) e a dimensioni fisse (Matrix3d, ecc.) che non useremo.

Operazioni Fondamentali di Eigen

#include <Eigen/Dense>

Eigen::MatrixXd W = Eigen::MatrixXd::Random(3, 4); // 3x4, valori in [-1,1]
Eigen::VectorXd x = Eigen::VectorXd::Random(4);    // 4x1

// Prodotto matrice-vettore → risultato 3x1
Eigen::VectorXd z = W * x;

// Trasposta
Eigen::MatrixXd Wt = W.transpose();  // diventa 4x3

// Inizializzazioni utili
Eigen::MatrixXd Z = Eigen::MatrixXd::Zero(3, 4);
Eigen::MatrixXd I = Eigen::MatrixXd::Identity(4, 4);

// Operazioni ELEMENTO PER ELEMENTO con .array()
// (indispensabile per le funzioni di attivazione!)
Eigen::ArrayXd relu = z.array().max(0.0);   // ReLU: max(0, zi)
Eigen::ArrayXd sig  = 1.0 / (1.0 + (-z.array()).exp()); // Sigmoid

Attenzione: * tra due MatrixXd è sempre prodotto matriciale. Per il prodotto elemento per elemento usate .array().

Task: Hello Eigen + OpenCV

Verificate che tutto funzioni scrivendo un main.cpp che:

  1. Crea una matrice W (\(3 \times 4\), valori casuali) e un vettore x (\(4 \times 1\)).
  2. Calcola \(z = W \cdot x\) e lo stampa — le dimensioni devono essere \(3 \times 1\).
  3. Calcola z_relu = z.array().max(0.0) e lo stampa: è il vostro primo forward pass!
  4. Crea un’immagine vuota OpenCV \(28 \times 28\) (scala di grigi) e la visualizza:
#include <opencv2/opencv.hpp>
cv::Mat img(28, 28, CV_8UC1, cv::Scalar(128)); // grigio medio
cv::imshow("Test MNIST size", img);
cv::waitKey(0);

Se Eigen stampa e OpenCV apre la finestra, l’ambiente è pronto per tutto il corso.

La soluzione di riferimento verrà discussa all’inizio della prossima lezione.