read-vk6

Crates.ioread-vk6
lib.rsread-vk6
version0.1.0
created_at2025-11-18 12:55:57.353125+00
updated_at2025-11-18 12:55:57.353125+00
descriptionFast and simple reader for VK6/VK7 files from Keyence confocal laser scanning microscopes
homepage
repositoryhttps://github.com/beneficial01/read-vk6
max_upload_size
id1938413
size347,549
Mahmoud (Beneficial01)

documentation

https://docs.rs/read-vk6

README

read-vk6

A fast and simple Rust library for reading VK6/VK7 files from Keyence confocal laser scanning microscopes (VK-X series), such as the VK-X1000 and VK-X3000.

This library extracts:

  • Height maps (surface topography in micrometers)
  • RGB optical images (when available)
  • Comprehensive metadata (75+ fields including timestamp, lens info, measurement settings, camera parameters, etc.)

Inspired by the excellent Surfalize Python library.

Features

  • ✨ Simple API: read a VK6 file in one function call
  • 🚀 Fast native Rust implementation
  • 📊 Returns data as ndarray arrays ready for scientific computing
  • 🎨 Optional RGB image extraction
  • 📝 Comprehensive metadata extraction (75+ measurement and camera settings fields)
  • 🔬 Preserves all measurement conditions from the original file

Installation

Add this to your Cargo.toml:

[dependencies]
read-vk6 = "0.1.0"

Usage

use read_vk6::{read_vk6, RawSurface};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Read VK6 file with RGB image
    let surface = read_vk6(Path::new("sample.vk6"), true)?;
    
    // Access height map (µm)
    println!("Height map shape: {:?}", surface.height.dim());
    println!("Step X: {} µm/pixel", surface.step_x);
    println!("Step Y: {} µm/pixel", surface.step_y);
    
    // Access metadata
    if let Some(title) = &surface.metadata.title {
        println!("Title: {}", title);
    }
    if let Some(timestamp) = &surface.metadata.timestamp {
        println!("Timestamp: {}", timestamp);
    }
    
    // Access RGB image if available
    if let Some(rgb) = &surface.rgb_image {
        println!("RGB image shape: {:?}", rgb.dim());
    }
    
    Ok(())
}

Read without RGB image

If you only need the height map and want to skip image processing:

let surface = read_vk6(Path::new("sample.vk6"), false)?;

Data Structure

The RawSurface struct contains:

pub struct RawSurface {
    pub height: Array2<f64>,          // Height map in micrometers (rows, cols)
    pub step_x: f64,                  // µm per pixel in X direction
    pub step_y: f64,                  // µm per pixel in Y direction
    pub metadata: Metadata,           // Comprehensive file metadata
    pub rgb_image: Option<Array3<u8>>, // RGB image (rows, cols, 3) if available
}

Metadata Fields

The Metadata struct contains 75+ fields extracted from the VK6 file, including:

Basic Information:

  • title, lens_name, timestamp, diff_from_utc

Optical Settings:

  • optical_zoom, objective_magnification, lens_id, num_aperture
  • nd_filter, light_filter_type, head_type

Measurement Settings:

  • run_mode, peak_mode, speed, distance, pitch
  • sharpening_level, plane_compensation

Camera & PMT Settings:

  • pmt_gain_mode, pmt_gain, pmt_gain_2, pmt_offset
  • camera_gain, shutter_speed_mode, shutter_speed
  • white_balance_mode, white_balance_red, white_balance_blue

Resolution & Units:

  • x_length_per_pixel, y_length_per_pixel, z_length_per_digit (in picometers)
  • xy_length_unit, z_length_unit, xy_decimal_place, z_decimal_place
  • height_effective_bit_depth, light_effective_bit_depth

Image Processing:

  • gamma, gamma_reverse, gamma_correction_offset
  • light_lut_mode and LUT parameters (light_lut_in0-4, light_lut_out0-4)
  • img_attributes, color_composite_mode, img_layer_number

And many more... See src/types.rs for the complete list.

Use the summary() method for a quick overview:

println!("{}", surface.metadata.summary());

Example: See examples/show_metadata.rs for a complete demonstration of all metadata fields:

cargo run --example show_metadata

Example: Export to NumPy and PNG

See tests/integration.rs for a complete example that:

  1. Reads a VK6 file
  2. Exports the height map as a NumPy .npy file
  3. Exports the RGB image as a PNG

Run the test:

# Place your VK6 file at tests/data/sample.vk6
cargo test --test integration -- --nocapture

This will create:

  • tests/out/height.npy - Height map array
  • tests/out/rgb.png - RGB optical image

Visualizing Results with Streamlit

A simple Streamlit app is included to visualize the extracted data:

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Place your VK6 file at tests/data/sample.vk6
cargo test --test integration -- --nocapture

# Run the viewer
uv run streamlit run streamlit_app.py

The app will display:

  • Height map with colorbar
  • RGB optical image

File Format Support

Currently supports:

  • ✅ VK6 files (tested)
  • 🔄 VK7 files (uses same internal format, should work)

The library reads the embedded Vk4File from the ZIP archive and parses:

  • Measurement conditions
  • Height layer (16-bit or 32-bit depth)
  • Color/Light layer (RGB image)
  • String data (title, lens)

Dependencies

  • ndarray - Multi-dimensional arrays
  • byteorder - Binary data parsing
  • zip - ZIP archive handling
  • chrono - Timestamp parsing
  • thiserror - Error handling

Contributing

Contributions welcome! This library was created to provide a Rust alternative for reading Keyence microscope files. If you encounter issues with specific VK6/VK7 files or have suggestions, please open an issue.

License

MIT License. See LICENSE-MIT for details.

Acknowledgments

  • Inspired by Surfalize by Frederic Schell
  • Format information based on reverse engineering of VK6 file structure

See Also

Commit count: 0

cargo fmt