Skip to main content

Industrial CT with Volvicon: Cone Beam Reconstruction, Void Detection, and Automated Reporting

· 6 min read
Volvicon Team
Volvicon Development Team

Industrial CT inspection workflows typically involve three sequential stages: volume reconstruction from raw projections, defect characterisation within the reconstructed volume, and export of quantitative results for reporting or downstream processing. Each stage carries its own set of parameters and potential failure modes. This post walks through how to automate all three stages in Volvicon using the Python Scripting API, drawing on a worked example with cone beam CT data.

Overview

The complete workflow covered here proceeds as follows:

  1. Reconstruct a 3D volume from a sequence of cone beam projection images using the FDK (Feldkamp–Davis–Kress) algorithm.
  2. Apply post-reconstruction filtering and render properties to improve visual interpretability.
  3. Run void/inclusion analysis to detect and characterise internal defects.
  4. Export per-defect statistics and aggregate porosity metrics to disk.

The same workflow applies to any industrial CT dataset where projection geometry is known — castings, welds, additive manufactured parts, composites, and similar materials.

Cone Beam CT Reconstruction

The FDK algorithm requires accurate knowledge of the scanning geometry. Errors in source-to-detector distance, source-to-isocenter distance, or detector pixel size propagate directly into the reconstructed voxel dimensions and therefore into all downstream measurements. Before running reconstruction, verify these parameters against your scanner's calibration data.

The key geometry parameters are:

ParameterDescription
source_to_detector_distanceDistance from the X-ray focal spot to the detector plane (mm).
source_to_isocenter_distanceDistance from the X-ray focal spot to the rotation axis (mm).
detector_pixel_size_x / yPhysical pixel pitch on the detector (mm).
xray_scan_total_angleTotal angular arc covered by the scan (360° for full circular scan).
is_clockwiseRotation direction — must match the physical scanner.

If your detector is not perfectly aligned with the rotation axis, the offset parameters (projection_offset_x/y, source_offset_x/y, out_of_plane_angle, in_plane_angle) allow you to compensate for translational and rotational misalignment before reconstruction rather than in post-processing.

Short scans and displaced detectors

For scans covering less than 360° or using an off-centre detector configuration, enable enable_displaced_detector and set angular_gap_threshold to match your scan arc. This activates the displaced detector FDK weighting function, which reduces truncation artefacts at the projection boundary.

Reconstruction Filter

The Hann filter (hann_cut_frequency) controls the high-frequency roll-off applied during filtered back-projection. A value of 0.0 applies no additional filtering beyond the ramp filter. Increasing it toward 1.5 progressively smooths the reconstruction at the cost of spatial resolution. For defect detection, start at 0.0 and increase only if noise is visually dominant in the reconstructed volume.

Truncation correction (truncation_correction) is relevant when the object extends beyond the detector field of view. Setting a value greater than 0 applies a correction that partially compensates for the cupping artefact introduced by truncated projections, though it does not fully eliminate it.

Post-Reconstruction Processing

After reconstruction, a bilateral filter can be applied to reduce noise while preserving edge sharpness:

volume_operations.bilateral_filter([reconstructed_volume], 1, 8000, 2)

The parameters control the spatial filter width and intensity range window. For typical metal or polymer CT data, the defaults above provide a reasonable starting point. The bilateral filter is preferable to Gaussian smoothing here because it does not diffuse high-contrast material boundaries — a property that matters for accurate void boundary delineation in the next stage.

Void / Inclusion Analysis

With a reconstructed and filtered volume, the void/inclusion analysis detects regions of anomalous intensity relative to the surrounding bulk material.

Voids appear as locally lower-intensity regions (gas pockets, shrinkage cavities, cracks). Inclusions appear as locally higher-intensity regions (denser foreign materials). The mode is selected at analysis creation time and cannot be changed without creating a new analysis object.

Detection Method

Two detection modes are available:

  • Absolute: Applies a fixed intensity contrast threshold relative to the estimated background level.
  • Relative: Applies a percentage-based contrast threshold relative to the local intensity range.

For most industrial CT datasets, enabling auto_absolute_contrast is the appropriate starting point. This estimates the background (bulk material) intensity automatically, reducing the need for manual threshold tuning between datasets with different exposure or material properties. Manual override is available when the automatic estimate is unreliable — for example, in datasets with strong beam hardening artefacts.

Filtering Detected Regions

The filtering step determines which candidate regions are included in the final result. The most consequential parameters are:

ParameterGuidance
min_voxel_countSets the minimum detectable defect size. Use 27 voxels (a 3×3×3 cube) as a practical lower bound to discard single-voxel noise.
max_voxel_countPrevents very large segmentation errors (e.g., partially segmented background) from appearing as defects.
min_sphericity / max_sphericitySphericity near 1.0 indicates near-spherical gas pockets. Lowering the minimum captures elongated crack-like features.
max_countHard cap on the number of returned defects. Useful for performance when processing datasets with thousands of small pores.
note

Geometric filtering does not re-run the detection — it post-processes the candidate list. If you tighten filters and then loosen them again, no new candidates are generated; you must re-run the analysis to capture previously excluded regions.

Statistics

The analysis returns both per-defect label statistics and aggregate descriptive statistics. The per-defect table includes volume, centroid coordinates, compactness, sphericity, equivalent diameter, and volume fraction — sufficient for most engineering defect characterisation reports. The aggregate porosity value (void_inclusion_results.porosity) gives the total defect volume as a fraction of the analysed region.

print(f"Total defects: {void_inclusion_results.total_defects_found}")
print(f"Total defect volume (mm³): {void_inclusion_results.total_defect_volume}")
print(f"Porosity: {void_inclusion_results.porosity:.4%}")
Porosity interpretation

The porosity value computed here is relative to the full reconstructed volume bounding box, not the part volume. If the volume was reconstructed with significant air surrounding the part, the porosity fraction will be underestimated. Use a ROI mask or crop the volume to the part bounds before analysis to obtain a physically meaningful porosity metric.

Exporting Results

Results can be written to disk as plain-text statistical summaries:

analysis_operations.write_void_inclusion_results_to_disk(
void_inclusion_results,
os.path.join(output_dir, 'void_inclusion.txt')
)

Snapshots of the 3D scene, application window, and individual views can be saved programmatically:

app.save_snapshot_to_disk(api.SnapshotType.View3D, 'C:/Samples/View3D.png')

For structured reporting (PDF reports with 3D scenes, charts, and measurement tables), the interactive UI tools under the Analyze ribbon tab provide report generation features not available through the scripting interface.

Video Tutorial

The full workflow — reconstruction, void analysis, visualisation, and reporting — is demonstrated in the video below: