System designTroubleshooting

Template matching incompatible image type: fix bit depth mismatch

Why template matching throws an incompatible image type error, the bit depth mismatches behind it, and how to convert both images and re-learn the template.

LumaSpec Vision10 min read Share on LinkedIn

On this page 11 sections
  1. 01What the error is telling you
  2. 02Cause 1: the template and image have different bit depths
  3. 03Cause 2: one image is colour, the other grayscale
  4. 04Cause 3: the image buffers were created with different types
  5. 05The fix: convert both images, then re-learn the template
  6. 06Worked example: a 12-bit frame in, an 8-bit match out
  7. 07Where the conversion belongs
  8. 08Checks before you call it fixed
  9. 09When the error comes back at runtime
  10. 10Prevention checklist
  11. 11Questions

You taught a template, the loop grabs a frame every few seconds to hold a feature on position, and the pattern-match call stops with the message "incompatible image type" — often carrying a hex code such as 0xbff60453. The message is literal: the template you taught and the image you are searching store their pixels differently, so the engine refuses the comparison before any scoring happens. This guide takes the failure in order of probability — bit depth, colour versus grayscale, and the type an image buffer was allocated with — gives a test for each, then works the conversion arithmetic on a real 12-bit frame so you can re-learn the template and restart the loop.

What the error is telling you

A pattern-matching engine compares pixels, and it accepts the comparison only when both images store those pixels the same way: the same bits per pixel and the same number of bands. Teach the template from an 8-bit grayscale source, then search a 16-bit frame, and the call stops. The full compatibility picture is short:

Template / search image 8-bit gray 16-bit gray RGB, 3 bands
8-bit gray matches type error type error
16-bit gray type error matches type error
RGB, 3 bands type error type error matches

It is a type check, not a quality judgement — the template can be excellent and the error still fires. That is also why the error so often survives an attempted fix. A stored template keeps the pixel type it had at the moment you learned it. Cast the live frame while the stored template keeps its old type, or cast the template after it was learned, and the pair is still mismatched. The order that works is convert first, then learn, then match.

Cause 1: the template and image have different bit depths

This is the most common origin. The template came from one source — an 8-bit snapshot, a saved file, a screenshot — while the runtime frames arrive from a camera running a 10-bit or 12-bit pixel format. On the PC those formats are unpacked into 16-bit planes, so the search buffer is 16-bit even though the sensor digitises 12 bits. The reverse also happens: the camera was switched to an 8-bit format after the template was taught on 16-bit frames.

Test it at the match call, not at the camera. Every vision library exposes the property — bits per pixel, depth or image type — on both the template and the search image. Print both values once inside the loop and the mismatch names itself. For background on why 10-bit sensor data so often reaches your code as 8-bit anyway, read why 10-bit sensors ship 8-bit images.

Cause 2: one image is colour, the other grayscale

A three-band RGB frame and a single-band grayscale template are different image types, exactly as 16-bit and 8-bit are. It happens when the template was taken from a colour rendering or a documentation picture while the line camera is mono, or when a colour camera streams decoded RGB against a template taught from a mono reference. Convert both sides to grayscale: colour adds nothing to a geometric match, and grayscale cuts the bytes per frame to a third.

Packed camera formats hide the same problem. A Bayer-packed or YUV stream becomes RGB or mono only after your decode step, and the type of the decoded buffer is what the match sees. If frames reach your code as raw bytes, decode them before processing and the type question settles upstream. A related trap — containers disagreeing with their pixel format — is covered in fixing a Mat type and pixel format mismatch.

Cause 3: the image buffers were created with different types

Every image in the pipeline lives in a buffer whose create call takes the pixel type as an argument. Two slip-ups keep the error alive after a conversion: the buffer receiving the camera frame is created 16-bit while the template buffer is created 8-bit, or the cast writes its output into a buffer allocated for the source type instead of the target. The conversion then quietly produces the wrong type and the match call reports the difference.

The working sequence, in pseudocode with illustrative names:

frame    = grab()                   # 12-bit camera, 16-bit planes on the PC
tpl_img  = to_gray8(frame)          # cast into a buffer created as 8-bit
search   = to_gray8(grab())         # same conversion on every frame
template = learn(tpl_img)           # stored template is now 8-bit
score    = match(search, template)  # both sides 8-bit, call succeeds

The fix: convert both images, then re-learn the template

  1. Commit to one runtime format: 8-bit grayscale. Gray pattern matching is built around 256 levels, and nearly every industrial feature keeps tens of them after conversion. Match in 16-bit only when the feature spans fewer than about ten levels in 8-bit — low-contrast seams between similar metals are the usual case.
  2. Convert the template source image and a live frame with the same conversion, each writing into a buffer created for 8-bit grayscale.
  3. Learn the template from the converted image. This step is what clears the stored type conflict permanently.
  4. Probe both image types at the match call once, then run. If the error persists, the conversion's output buffer is the culprit — recreate it for the target type.

If you would rather change the camera than convert in software, set the camera's pixel format to an 8-bit mode and re-check exposure afterwards, because exposure behaviour shifts with format changes on many sensors.

Worked example: a 12-bit frame in, an 8-bit match out

Take a camera streaming a 12-bit pixel format. Unpacked on the PC, the values sit in 16-bit planes spanning 0 to 4095. The conversion to 8-bit divides by 2^(12−8) = 16, a right shift by four bits:

v8 = floor(v12 / 2^(12-8)) = v12 >> 4

A bright pixel on the braid at 2600 becomes 2600 / 16 = 162.5 → 162. Background at 1900 becomes 118. The feature keeps 44 gray levels of contrast — far more than the handful a stable match score needs. The full range also lands correctly: 4095 / 16 = 255.9 → 255, so nothing clips.

Frame size matters to the pipeline, not to the error. The LS-CMR-0166 is a 12 MP USB3 area scan camera with a 4000 × 3000 resolution. At that size a 16-bit mono frame is 4000 × 3000 × 2 = 24,000,000 bytes ≈ 22.9 MiB, and the 8-bit version is 12,000,000 bytes ≈ 11.4 MiB. One conversion per frame on a five-second cycle costs milliseconds.

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

The same numbers tell you whether the template is a sensible size. With a 40 mm field of view across 4000 pixels, one pixel covers 40 / 4000 = 0.01 mm = 10 µm, so a 4 mm feature at the braiding point spans 400 pixels. That is a workable template: aim for at least a few tens of pixels on each side so the score stays stable. Work the pixel count for your own field of view or start it here:

Camera resolution for the smallest feature
Units
Pixels needed
–
Sensor size
– MP
Smallest sensor that fits
–
Pixel on the part
– mm
Pixels across the feature, that sensor
–

Pixels needed = field / feature × pixels per feature on each axis (field incl. margin). The lens must resolve the pixels too: Nyquist = 1000 / (2 × pixel µm) lp/mm.

Find cameras with enough pixels Open the full calculator

Where the conversion belongs

Convert once, immediately after unpacking, in one place. Every downstream consumer — display, match, measurement — then sees the same 8-bit grayscale type, and a format change upstream cannot reintroduce the mismatch. On a PC-based line that place sits on your vision controller, between the camera interface and the application. A VC3000-class controller such as the MV-VC3301H-128G66, with an Intel Core i3 processor and 8 GB of memory, absorbs the conversion well inside the inspection budget.

Vision controllersHikrobot MV-VC3301H-128G66 I3-8100, 8GB+128G SSD, No PoE, PCIe expansion supported, Incl. VM6200Pro licenseMV-VC3301H-128G66
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$2,419.00View partBuild a system with it

On-device matching removes one side of the problem entirely: a smart camera teaches and matches in the same environment, so template and frames share one format by construction. A 6 MP mono model such as the MV-SC5060XM-08M-WBN still needs its pixel format fixed in configuration — reset the device and a stored template can face a different type again.

Smart cameras & vision sensorsHikrobot MV-SC5060XM-08M-WBN SC5000X series Smart Camera, 6 MP, Mono, 8 mm focal length, M12-mountMV-SC5060XM-08M-WBN
Interface
GigE
Resolution
6-10 MP
Sensor format
1/2.4"
Shutter
Rolling
$1,629.00View part

Checks before you call it fixed

  • Teach a region with real structure. Edges running in both directions give the engine gradient to lock onto; a flat patch scores badly even with correct types. A taught region that is too small raises its own error — see fixing a template image too small.
  • Keep the search window as small as the motion allows. A braiding point that wanders ±30 mm needs a far smaller window than the full frame, and the match runs faster for it — the same lever behind raising a slow pattern-match update rate.
  • Teach and run at the same optics. Gray matching tolerates only a few percent of scale change; when the part outgrows the field of view, match a stable sub-feature instead, as in template matching a part larger than the field of view.
  • Log both image types at the match call during commissioning. One line in the log turns any future recurrence into a ten-second diagnosis.

When the error comes back at runtime

The error can return months after clean commissioning, and three changes lie behind nearly every case. A replaced or power-cycled camera came up in a different pixel format than the one commissioned. A stored template was reloaded from a file saved at another bit depth. Or the decode path changed — a software update that hands your code packed data where it used to receive unpacked planes.

Two habits close all three paths. Write the pixel format into the camera's start-up configuration so every boot lands in the same mode. And read the header bit depth before loading image files, so an old file cannot sneak an old type into a running line.

Prevention checklist

  • Camera pixel format written into start-up configuration, not left at the last-used value.
  • One conversion to 8-bit grayscale, immediately after unpacking, in one place in the pipeline.
  • Templates learned only from converted frames, and re-learned after any camera swap or format change.
  • Conversion output buffers created for the target type.
  • Stored templates saved after conversion, their bit depth checked on load.
  • Teach and run at the same working distance, lens and lighting.

If the camera side is also in play — a format you cannot lock, or a 12-bit stream you want to keep — start a replacement at the camera step of the configurator or ask us through the contact page. Free expert support comes with every order, and in-stock items ship within one business day.

Questions

Why does casting the search image not clear the error?

Because the stored template keeps the pixel type it had when you taught it, so the cast fixes only one side of the pair. The engine still compares an 8-bit template against a 16-bit buffer. Convert a live frame, learn a new template from a converted frame, and probe both types at the match call. If the error survives that, the cast is writing into a buffer allocated with the wrong type — recreate that buffer for the target type.

Should the match run in 8-bit or keep the 16-bit data?

Run it in 8-bit grayscale. Gray pattern matching is built around 256 levels, and after the divide-by-16 from 12-bit data nearly every industrial feature keeps tens of them — plenty for a stable score. Stay in 16-bit only when the feature spans fewer than about ten levels once converted, which happens on low-contrast seams between similar metals, and then use a matching function that accepts 16-bit input on both sides.

How do I check an image's bit depth while the loop runs?

Read the type property the library exposes on the buffer — bits per pixel, depth or image type — and print it for the template and the search image at the match call. Do it there, not at acquisition, because unpacking and any cast in between can change the type. Cross-check once by saving both to PNG and reading the file header before loading it back.

Can a colour image cause the same error?

Yes. Three-band RGB against single-band grayscale is a type mismatch exactly like 16-bit against 8-bit, and it fails the same way regardless of which side is the template. Convert both images to grayscale before learning and matching. Colour contributes nothing to a geometric match, and grayscale also cuts the bytes the controller moves per frame by two thirds.

What does the hex code 0xbff60453 mean?

It is the numeric form of the incompatible image type error in one widely used vision library: the template and the search image have different pixel types. The code adds no detail — it names no side and no bit depth — so treat the text as the whole diagnosis and probe both image types yourself. Its value is as a search term that leads straight to this failure mode.

How do I stop the error returning after a camera swap?

Write the pixel format into the camera's start-up configuration so a replaced or power-cycled camera boots in the same mode, convert every frame to 8-bit grayscale immediately after unpacking, and re-learn the template from a converted frame. When a stored template is reloaded, read its bit depth from the file header first. Those three habits close every recurrence path this error has.