ApplicationsHow-to

Thermal CSV visualization: display raw pixel arrays

Build thermal CSV visualization with verified row order, fixed grayscale or false-color limits, and a saved copy of the original numeric values.

LumaSpec Vision9 min read Share on LinkedIn

On this page 9 sections
  1. 01Establish the file layout and value meaning
  2. 02Import a rectangular matrix without rescaling it
  3. 03Reconstruct a flattened array in the correct order
  4. 04Verify orientation with an asymmetric scene
  5. 05Display grayscale and false color with explicit limits
  6. 06Work through the display mapping and clipping
  7. 07Save measurements separately from the preview
  8. 08Check the acquisition path before choosing hardware
  9. 09Questions

A CSV file can contain a complete thermal image without containing any colors. The challenge is to reconstruct the correct pixel arrangement, display useful contrast, and keep the measurements separate from their presentation. This procedure is for engineers who already have numeric pixel data and need a repeatable preview. You will check the array dimensions, verify orientation, apply fixed display limits, and save the original values alongside a clearly labeled visualization.

Establish the file layout and value meaning

  1. Record the expected image width, height, pixel ordering, and meaning of each value before importing the file.

For an example image that is 80 pixels wide and 60 pixels high, a conventional image matrix contains 60 rows and 80 columns. Its total pixel count is:

Pixel count = width × height Pixel count = 80 × 60 = 4,800

A CSV export might instead contain a single column of 4,800 values, a single row, or coordinate columns followed by measurements. These layouts require different reconstruction steps. Inspect several lines of the actual text file, not a screenshot of its contents.

Record these details:

  • Whether the file contains a header or additional metadata rows.
  • Whether commas separate fields, and whether decimal points use a period.
  • Whether the first pixel represents the upper-left corner.
  • Whether flattened data advances across columns or down rows.
  • Whether values represent raw counts, radiance, or documented temperature units.
  • Whether any numeric codes indicate invalid pixels.

Text encoding affects how the file is read, not what its pixel values mean. A value near 30,000 does not establish a temperature scale. The thermal-count calibration guide explains what additional information temperature conversion requires.

Import a rectangular matrix without rescaling it

  1. Read the numeric values, verify the shape, and reject unexpected missing or nonnumeric entries.

The following matrix-oriented code assumes a headerless, comma-delimited file containing one complete image. The image must already be arranged as rows and columns:

W = 80;
H = 60;

A = readmatrix("frame.csv", "Delimiter", ",", ...
               "NumHeaderLines", 0);

assert(isequal(size(A), [H W]), ...
       "Unexpected image dimensions");
assert(isreal(A) && all(isfinite(A(:))), ...
       "Missing, nonnumeric, or nonfinite pixel values");

raw = A;

If the file has a documented header, set the header-line count accordingly. Do not skip rows merely to make the dimensions pass. First establish what those rows contain and whether the import settings match the export format.

Check a few imported values against the text file, including the first and last entries. Also inspect the minimum and maximum:

fprintf("Minimum: %.12g\n", min(raw(:)));
fprintf("Maximum: %.12g\n", max(raw(:)));

Importing integer counts into a double-precision matrix does not itself normalize them. Every unsigned 16-bit integer is exactly representable in that numeric type.

Do not immediately cast the matrix to an unsigned integer type. First verify that the documented data format requires integers between 0 and 65,535. A conversion can conceal negative values, round fractions, or saturate out-of-range entries. Missing values also need an explicit validity policy rather than replacement with zero.

For the acquisition-side distinction between numeric data and rendered images, use the high-bit-depth thermal export guide.

Reconstruct a flattened array in the correct order

  1. Reshape vector data only after confirming its documented traversal order.

Skip this step if the preceding import already produced the correct rectangular matrix. A reshape operation changes the arrangement of values; it does not discover their intended pixel positions.

For a separate file containing a single row or column, begin with:

W = 80;
H = 60;

B = readmatrix("pixels.csv", "Delimiter", ",", ...
               "NumHeaderLines", 0);

assert(isvector(B), "Expected a single pixel vector");
v = B(:);
assert(numel(v) == W*H, "Unexpected pixel count");
assert(isreal(v) && all(isfinite(v)), ...
       "Invalid pixel values");

If the exporter writes all columns of the first image row before starting the next row, reconstruct it with:

raw = reshape(v, [W H]).';

The nonconjugating transpose converts the intermediate arrangement into the required height-by-width matrix.

If the exporter writes an entire image column before advancing to the next column, use this alternative instead:

raw = reshape(v, [H W]);

Choose one reconstruction, not both. Both alternatives can produce valid dimensions, so a dimension check alone cannot establish which image is correct.

A small example makes the distinction visible. For a sequence containing 1 through 6, a row-first image with width 3 and height 2 should read:

1  2  3
4  5  6

The wrong traversal order produces a different arrangement without losing any numbers. Do not flatten a coordinate table or a matrix containing timestamps; select and reconstruct its documented pixel fields first.

Verify orientation with an asymmetric scene

  1. Confirm row direction, column direction, and transpose behavior before interpreting image features.

Use a scene with a known asymmetry, such as a warmer object near the upper-left corner and a different feature near the lower edge. A centered round object is a poor orientation test because several incorrect transformations can look plausible.

During verification, display row and column coordinates. Confirm these points:

  • The expected upper-left feature appears at small row and column indices.
  • Moving a target horizontally changes its column position.
  • Moving it vertically changes its row position.
  • The displayed aspect ratio preserves square pixels.

A transpose exchanges row and column coordinates. A horizontal flip reverses columns; a vertical flip reverses rows. These operations are not interchangeable fixes.

Preserve the imported source file and document any necessary transformation. If only the presentation needs a flip, apply it to a separate display array rather than silently changing the archived measurements.

When matching thermal data to another image stream, orientation is only the beginning. The thermal and RGB fusion guide explains why registration must remain separate from the original thermal measurements.

Display grayscale and false color with explicit limits

  1. Select a lower and upper display limit, then apply a palette without modifying the measurement matrix.

Start with grayscale because it makes geometry, striping, and discontinuities easy to inspect. The following limits are illustrative application values, not camera specifications or temperature thresholds:

lo = 29500;
hi = 31500;
assert(isfinite(lo) && isfinite(hi) && hi > lo, ...
       "Display limits must be finite and increasing");

figure;
imagesc(raw, [lo hi]);
axis image;
axis ij;
colormap(gray(256));
xlabel("Column");
ylabel("Row");
cb = colorbar;
cb.Label.String = "Raw count";
title("Grayscale with fixed display limits");

Here, axis image preserves equal scaling along the image axes. axis ij places increasing row indices downward, matching the usual top-left image convention.

To inspect the same values with false color, change only the palette and title:

colormap(hot(256));
title("False color; raw counts");

The palette changes appearance, not the entries in raw. Keep the colorbar label as raw counts unless the source documentation establishes another unit.

Automatic limits can help reveal an unfamiliar scene, but they can mislead when comparing successive frames. If each frame maps its own minimum and maximum to the palette endpoints, a stable object can change color when another object enters the scene.

For repeatable comparisons, use identical limits and palettes across the relevant frames. Select limits from the intended measurement range or a documented baseline, rather than independently from each image. The color-to-temperature mapping guide explains why a rendered color alone cannot establish temperature.

Work through the display mapping and clipping

  1. Calculate how representative values map into the display range, then count clipped pixels.

For a linear display, the normalized palette position is:

u = (x - L) / (U - L) u_display = min(1, max(0, u)) x = original pixel value L = lower display limit U = upper display limit

With a lower limit of 29,500 and an upper limit of 31,500, the display span is:

Display span = 31,500 - 29,500 = 2,000 counts For x = 30,500: u = (30,500 - 29,500) / 2,000 = 0.5

That value appears halfway through the selected palette. The discrete palette determines the final displayed shade.

Original value Normalized position Display treatment
29,000 -0.25 Lower endpoint color
29,500 0 Lower endpoint color
30,500 0.5 Middle of the palette
31,500 1 Upper endpoint color
32,000 1.25 Upper endpoint color

Values outside the limits remain present in the numeric matrix, even though their displayed colors no longer distinguish them. Check that loss of visible detail explicitly:

nLow = nnz(raw < lo);
nHigh = nnz(raw > hi);
pctClipped = 100*(nLow + nHigh)/numel(raw);
fprintf("Outside display limits: %.2f percent\n", pctClipped);

If 24 of 4,800 pixels exceed the limits, the clipped fraction is 24 / 4800 × 100 = 0.5%. Whether that is acceptable depends on where those pixels occur. A small clipped region can still contain the feature you need to inspect.

A completely flat image has no internal contrast to reveal. Widening or narrowing the palette cannot recover variation absent from the measurements.

Save measurements separately from the preview

  1. Archive the numeric matrix, its interpretation, and the display settings as separate information.

Retain the original CSV unchanged. Save a working array together with enough metadata to reconstruct the displayed view:

meta.width = size(raw, 2);
meta.height = size(raw, 1);
meta.units = "raw counts";
meta.origin = "top-left, verified";
meta.displayLimits = [lo hi];
meta.palette = "hot";

save("thermal_frame.mat", "raw", "meta");
exportgraphics(gcf, "thermal_preview.png");

Set metadata fields to what you actually verified. Include the frame identifier, acquisition time, invalid-value policy, and orientation transformation when those are available.

The saved preview is for communication and inspection. It is not a replacement for the numeric array: a palette image can merge distinct measurements into the same displayed color.

If you also write a new CSV, configure its numeric precision for the source data type and verify a read-back comparison. Decimal-valued measurements may require more precision than integer counts. The camera bit-depth guide explains the distinction between measurement precision and display appearance.

Check the acquisition path before choosing hardware

  1. Confirm the export requirements before selecting a camera or changing an existing acquisition system.

You do not need different hardware simply because a CSV initially looks dark or scrambled. First eliminate import, ordering, and display-limit problems.

For a new acquisition path, browse infrared cameras and use the camera finder to narrow the interface options. Two catalog entries provide starting points for interface discussions, not confirmation of a particular numeric export format.

The LS-IRC-0044 has a GigE interface.

Infrared cameras640 x 512 thermal camera, 8-14 μm, 50 Hz, GigE, FOV 88.5° × 73.2°, 9-24 V DC (LS-IRC-0044)LS-IRC-0044
Lens mount
C-mount
Interface
GigE
Resolution
Up to 3 MP
Spectrum
LWIR
$5,885.00 · quotedView and quote

The LS-IRC-0016 has a USB3 interface.

Infrared camerasLWIR thermal camera module, USB3, 640×512 resolution (LS-IRC-0016)LS-IRC-0016
Interface
USB3
$3,999.00 · quotedView and quote

For either candidate, request confirmation of the available numeric stream, units, invalid-value codes, frame dimensions, and documented export method. Do not infer radiometric output or CSV support from an interface label.

Before accepting the workflow, complete this checklist:

  • Confirm the pixel count and matrix dimensions against the export documentation.
  • Compare corner values with the original text file.
  • Verify orientation using an asymmetric target.
  • Preserve source values without normalization or unverified casting.
  • Use consistent display limits for comparisons.
  • Label counts as counts, not degrees.
  • Check clipping around the feature of interest.
  • Reopen the saved numeric data and confirm the values are unchanged.

For an existing file, start with those checks before changing equipment. For acquisition planning, send the expected image dimensions and numeric-output requirements through application support, or start a camera configuration.

Questions

Do thermal CSV values near 30,000 represent temperature?

No. Large integer values may be raw sensor counts, scaled measurements, or another documented encoding. Establish the units from the export documentation before converting anything. A display palette can visualize the array immediately, but temperature measurement requires the appropriate calibration and acquisition information.

Why does my reconstructed image look striped or scrambled?

Check traversal order as well as dimensions. A flattened vector can be reshaped into the expected size while assigning values to the wrong pixels. Verify whether the export advances across rows or down columns, then confirm the result using a scene with an identifiable off-center feature.

Should I convert imported values to an unsigned integer type?

Do not cast merely to make the display work. A floating-point matrix can preserve unsigned 16-bit integer counts exactly. Convert only when the documented format requires it, after checking for fractional values, invalid entries, negative numbers, and values beyond the permitted range.

Can I compare false-color images from different frames?

Yes, but only when the underlying units are comparable and the display uses the same limits and palette. Independent automatic scaling can assign different colors to the same numeric value. Compare the original arrays for quantitative decisions, and use the rendered images as supporting views.

Is saving a preview image enough to preserve the data?

For measurement work, retain the numeric array and its metadata alongside any preview. A rendered image generally cannot preserve every original pixel value or its interpretation. Archive the source CSV, document orientation and units, and store the display limits so the preview can be reproduced.