Cameras & sensorsExplainer

Mono12p vs Mono12Packed: pick the PFNC name your camera reports

Mono12p and Mono12Packed are distinct 12-bit packed formats. Set the name your camera reports, and budget 1.5 bytes per pixel — 25% less than Mono16.

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01Two names, one packing idea, two bit orders
  2. 02Why the wrong name fails in one of two ways
  3. 03The decision rule: read the list, then set it
  4. 04What packing costs and what it saves
  5. 05Worked example: 12 MP at 30 fps over a 400 MB/s USB3 budget
  6. 06When your library cannot unpack the format
  7. 07Mono cameras are where these names live
  8. 08Checks before you commit to packed 12-bit
  9. 09Pick the camera, then read its list
  10. 10Questions

Set the wrong packed format name and a healthy camera stops delivering images: the PixelFormat write bounces with an invalid enumeration value, or every fetched buffer arrives with an empty payload component and your reshape line fails one step later. Both Mono12p and Mono12Packed are legitimate 12-bit packed formats; the failure is a naming mismatch, not broken hardware. This guide covers where the two names come from, how their bit layouts differ, what 12-bit packed data costs and saves in bytes per pixel, and the decision rule that avoids the trap: set exactly the symbolic your camera's PixelFormat enumeration reports. It is for anyone wiring a GenICam consumer library to a mono camera over GigE or USB3.

Two names, one packing idea, two bit orders

Mono12p and Mono12Packed both describe monochrome pixels carrying 12 real bits: 4,096 gray levels, values 0 to 4,095. To avoid wasting a full 16-bit container on each sample, both formats pack two pixels into three bytes — 24 bits per pair, 1.5 bytes per pixel.

They are not synonyms. Mono12Packed is the packed 12-bit format defined for GigE Vision. Mono12p is the name the pixel format naming standard (PFNC) added later, at the birth of USB3 Vision, and it is the name USB3 Vision (U3V) cameras report. Both are valid entries in their standards; neither is an alias for the other. The decisive difference sits inside the three bytes: the two formats assign the 24 bits of a pixel pair in a different order, so a buffer decoded with the sibling's recipe returns the right number of pixels with the wrong gray values.

A third name completes the family: Mono12, the unpacked layout that carries each 12-bit sample in a 16-bit container at 2.0 bytes per pixel. It spends 25% more bandwidth than packed but decodes as a plain 16-bit array in any consumer.

Why the wrong name fails in one of two ways

PixelFormat is a GenICam enumeration, and its list holds exactly the symbolics the camera firmware exposes — nothing more. Two failure modes follow.

The fast failure: you write a name that is not in the list. A camera that reports Mono12p rejects Mono12Packed with an invalid enumeration value, and the same happens in reverse. Nothing moved; the write simply bounces. Setting an enumeration by integer value trades that readable error for a silent wrong entry, so stay with the symbolic names.

The slow failure: the write succeeds because the name matches what the camera reports, but the receiving library has no unpacker registered for that packed layout. Frames arrive and the fetch completes, yet the first payload component comes back as None, so the next line — reading .data off that component — throws. Mono8 never trips this: a 1-byte-per-pixel monochrome layout is the one decoder every consumer implements.

Both failures point to the same fix, in the next section.

The decision rule: read the list, then set it

The fix is one query away. Before setting anything, read the symbolic list of PixelFormat from the camera's node map; it names every format this exact unit accepts.

  1. If the list contains Mono12p, set Mono12p. If it contains Mono12Packed, set Mono12Packed. Never type the sibling name because another camera or protocol used it.
  2. If both names appear, keep the one your capture chain demonstrably unpacks, and prove it with a single frame before building the pipeline around it.
  3. Treat the interface as a hint, not a rule. The standards tie Mono12Packed to GigE Vision and Mono12p to USB3 Vision, but the enumeration on the unit you ship is the arbiter.
  4. Prove the result: fetch one buffer, check the first payload component is not None, and confirm the histogram reaches 4,095 rather than 255.

PixelFormat, Width and Height are GenICam standard feature names; the handle access differs per SDK:

node_map = cam.remote_device.node_map    # your SDK's handle to the GenICam node map
print(node_map.PixelFormat.symbolics)    # the list that decides, e.g. ['Mono8', 'Mono12p']
node_map.PixelFormat.value = 'Mono12p'   # must be one of the listed symbolics

Reading registers this way at runtime is the same move for exposure, packet size or format — see GigE camera register access at runtime.

What packing costs and what it saves

Pixel format Bits stored Bytes per pixel Gray levels
Mono8 8 1.0 256
Mono12p / Mono12Packed 12 1.5 4,096
Mono12 (unpacked) 12 2.0 4,096
Mono16 16 2.0 65,536

Packed 12-bit carries the full 4,096-level depth at 75% of the unpacked rate: 1.5 bytes per pixel against 2.0, a 25% saving that converts directly into frame rate or ROI headroom on a fixed link. That saving is the reason to pack; 12-bit depth itself is the reason to leave Mono8 behind. Sixteen times the gray steps let one exposure hold both the dark side of a bore and its bright machined rim, and thresholds survive a gain change without re-tuning. The depth choice has its own trade-offs — the bit-depth guide walks them — and a related trap is a sensor that digitizes 10 or 12 bits while the pixel format ships 8, which the ADC-versus-pixel-format guide untangles.

One working consequence: a packed buffer is not byte-addressable per pixel, because no pixel owns a byte boundary. Consume the decoded array your library hands back, not the raw bytes.

Worked example: 12 MP at 30 fps over a 400 MB/s USB3 budget

The case: the LS-CMR-0166, a 12 MP USB3 area scan camera on a 1/1.7" IMX226 rolling-shutter sensor, rated 30 fps at its full 4000 × 3000 resolution.

Area scan cameras12 MP USB3 area scan camera, IMX226, 1/1.7" rolling shutter, 30 fps, 4000 × 3000 resolution (LS-CMR-0166)LS-CMR-0166
Sensor format
1/1.7"
Interface
USB3
Resolution
12 MP
Shutter
Rolling
$560.00View partBuild a system with it

Inputs, and where each comes from:

  • Geometry and frame rate: 12,000,000 pixels per frame (4000 × 3000) and 30 fps, from the camera's catalog rating.
  • Bytes per pixel, from the pixel format standard: 1.0 B for Mono8, 1.5 B for Mono12p, 2.0 B for Mono12 in 16-bit containers.
  • Link budget: USB 3.0 moves 5 Gbit/s of line rate; 8b/10b coding leaves 500 MB/s of raw payload, and protocol headers keep real USB3 Vision streams near 400 MB/s. Plan on 400 MB/s — the USB3 bandwidth budget guide runs this arithmetic per camera.

Rule in words: frame size = pixels × bytes per pixel; stream rate = frame size × frame rate; top frame rate = budget ÷ frame size.

frame_bytes = width_px × height_px × bytes_per_pixel stream_MBps = frame_bytes × fps / 1000000 fps_max = 1000000 × budget_MBps / frame_bytes

Arithmetic:

  • Pixels: 4000 × 3000 = 12,000,000 px.
  • Mono12 unpacked: 12,000,000 px × 2.0 B/px = 24 MB per frame; 24 MB × 30 fps = 720 MB/s.
  • Mono12p: 12,000,000 px × 1.5 B/px = 18 MB per frame; 18 MB × 30 fps = 540 MB/s.
  • Mono8: 12,000,000 px × 1.0 B/px = 12 MB per frame; 12 MB × 30 fps = 360 MB/s.
  • Top frame rate at 400 MB/s: Mono12 unpacked 400 ÷ 24 = 16.7 fps; Mono12p 400 ÷ 18 = 22.2 fps; Mono8 400 ÷ 12 = 33.3 fps.

Result: packing saves 6 MB per frame — 180 MB/s at 30 fps, exactly 25% of the unpacked stream.

Decision: at the full 12 Mpx, neither 12-bit variant clears 30 fps on the 400 MB/s budget; unpacked stops near 16.7 fps and packed near 22.2 fps, so packing buys about 5.5 fps. Only Mono8 carries the full frame at 30 fps with margin left (360 MB/s against 400). To hold 30 fps in 12-bit, cut the window instead: 400 ÷ 30 ÷ 1.5 ≈ 8.9 Mpx with Mono12p, or 400 ÷ 30 ÷ 2.0 ≈ 6.7 Mpx with Mono12. MB here means 10⁶ bytes.

When your library cannot unpack the format

Work the fallbacks in this order:

  1. Move to a current release of your capture library first. Packed decoding is a recent addition to GenICam consumers, and several projects pinned older versions that predate it; one long-running support case was settled only when the consumer matched the exact symbolic the camera reported. Test the library you deploy, on the PC you deploy to, before blaming the camera.
  2. Fall back to unpacked 12-bit: set Mono12 and the pipeline receives a plain 16-bit array every consumer handles, at the cost of the 25% bandwidth saving.
  3. Fall back to Mono8 when 256 gray levels answer the question. It is the cheapest stream on any link and decodes everywhere.
  4. Decode the packed bytes yourself only as a last resort. Two pixels share three bytes, so the raw buffer cannot be reshaped to (height, width) — the byte count is 1.5 times the pixel count — and the nibbles must be recombined in the order the format defines. Color pipelines meet the same split in packed Bayer names; the packed-Bayer conversion guide shows the 16-bit path.

If you need the 4,096 levels and your consumer cannot unpack, pay for Mono12 and bank the certainty; the gray levels are worth more than the megabits.

Mono cameras are where these names live

Monochrome format names belong to mono sensors; color sensors carry the Bayer-named equivalents of the same layouts. In the range below, the mono area scan cameras span the interfaces these names come from:

Area scan camerasHikrobot MV-CS200-10UM 20 MP Area Scan Camera, USB3.0, IMX183, 2nd Gen., MonoMV-CS200-10UM
Sensor format
1"
Lens mount
C-mount
$759.00View part
Area scan camerasHikrobot MV-CT0MG0060/R/NN/NN 6 MP Area Scan Camera, 3rd Gen., GigE, Mono, BASEMV-CT0MG0060/R/NN/NN
Sensor format
1/1.8"
Lens mount
C-mount
$909.00View part
Area scan cameras12 MP GigE area scan camera, IMX226, 1/1.7" rolling shutter, 9 fps (LS-CMR-0053)LS-CMR-0053
Sensor format
1/1.7"
Lens mount
C-mount
$560.00View part

The two LS-CMR models on the same IMX226 sensor show why the link, not the sensor, sets the pace: the LS-CMR-0053 moves its 12 MP frames over GigE at 9 fps, while the LS-CMR-0166 runs the same sensor over USB3 at 30 fps. The arithmetic behind that pairing: at 12 MB per Mono8 frame, GigE's roughly 118 MB/s of usable payload tops out near 9.8 fps, and USB3's 400 MB/s planning budget clears 30. Same sensor, three times the pace — a link-budget result.

Checks before you commit to packed 12-bit

Run the list on the exact unit and library version you will ship:

  • Read the PixelFormat symbolic list on that unit; the list differs between models and firmware generations.
  • Fetch one frame and check the gray range: values up to 4,095 mean the packed decoder ran; a 0–255 range or a None component means it did not.
  • Re-run the link budget at your chosen format. The 1.5-versus-2.0-bytes difference moved the top frame rate from 16.7 to 22.2 fps in the worked example, and it moves your ROI limit by the same factor.
  • Test end to end on the deployment PC. Decoder support lives in the consumer library version, not the camera, and a bench PC on a newer build proves nothing about the machine on the line.

Pick the camera, then read its list

Choose the sensor and interface for your bandwidth first — the camera finder filters resolution, interface and shutter — then read the PixelFormat list of the shortlisted model before writing pipeline code. The camera configurator pairs the camera with lens, light and controller, and more format-level guides sit on the cameras topic page. If a shortlisted camera does not list the packed 12-bit format your pipeline wants, contact us with the application and target frame rate, and we will shortlist models whose lists carry it.

Questions

The camera accepted Mono12p but every fetch returns a None component — is the camera broken?

Almost certainly not. The set succeeded because the name is in the camera's list; the failure is downstream, where the receiving library has no unpacker for that packed layout, so it returns a buffer with no usable component. Set the camera to Mono8 or Mono12 and fetch again: if those decode normally, the camera, lens path and link are healthy and only the packed decoder is missing. Then update the capture library or fall back to an unpacked format.

How much bandwidth does Mono12p save over Mono16?

A packed 12-bit stream costs 1.5 bytes per pixel against 2.0 for 12-bit data carried in 16-bit containers — a 25% cut. On a 12 MP frame that is 18 MB instead of 24 MB, so a 400 MB/s USB3 budget yields about 22 fps instead of 16.7 fps. Against Mono8 the packed format costs 50% more: 1.5 bytes against 1.

Are Mono12p and Mono12Packed the same bytes under different labels?

No. Both store two 12-bit pixels in the same three bytes, but the two formats assign those 24 bits to the pixel pair in a different order. A buffer decoded with the wrong recipe comes back the right size with the wrong gray values, which is far harder to notice than an exception. The names are separate entries in the pixel format standards, and each camera lists the one or ones it implements.

Do color cameras have packed 12-bit formats too?

Yes. The same GigE-versus-PFNC naming split repeats for packed color data: a USB3 Vision camera reports the PFNC packed Bayer name, while GigE Vision cameras use the legacy Packed spelling. The bit layouts differ just as the monochrome ones do, and the same decision rule applies — read the camera's PixelFormat enumeration and set exactly the symbolic it lists. Packed Bayer decoding has its own pitfalls, so test against a known gray target before trusting the values.