System designTroubleshooting

IMAQdx extract color planes: why the image type must be RGB U32

Why IMAQdx ExtractColorPlanes reports not an image on a USB camera grab, the RGB U32 color buffer that fixes it, and how to get R, G and B planes into arrays.

LumaSpec Vision10 min read Share on LinkedIn

On this page 11 sections
  1. 01What the two symptoms tell you
  2. 02The contract every image buffer carries
  3. 03Cause 1: IMAQ Create never ran
  4. 04Cause 2: the buffer exists but is grayscale
  5. 05Cause 3: the camera is not delivering color
  6. 06The one-pixel strip is a rectangle, not a camera fault
  7. 07Worked example: what the arrays should look like at 640 × 480
  8. 08Wire the brightness and RGB sliders
  9. 09When the webcam is the limit
  10. 10Prevention checklist
  11. 11Questions

You wired IMAQdx Grab straight into ExtractColorPlanes and LabVIEW rejected the wire: not an image. Swap in ColorImageToArray and you get a strip one pixel high instead of a frame. Neither fault lives in the webcam. Both come from one contract between the LabVIEW image buffer you created and the pixel format the camera actually delivers. This page is for anyone capturing USB camera frames in LabVIEW who now wants per-channel control: brightness and RGB gain sliders on the front panel. You will trace the error code to its documented cause, set the camera's Pixel Format attribute so the grab delivers color, get height × width arrays out of the color conversion, and wire slider math that holds at 30 fps. The acquisition half — drivers, sessions, resolution limits — is covered in the USB camera in LabVIEW walkthrough; this page picks up at the first processing VI.

What the two symptoms tell you

Two failures, two different breaks in the same contract.

The not-an-image error on the ExtractColorPlanes wire has a documented, most-likely cause: the IMAQ Create call that allocates the buffer never ran, or did not run correctly. The vision driver's knowledge base lists exactly that as the first thing to check for error 1074396120. The second possibility sits one layer deeper: the buffer exists but was created as an 8-bit grayscale image, and ExtractColorPlanes only accepts a color image of type RGB U32.

The one-pixel strip out of ColorImageToArray is a different break. The VI works on a color image or on a sub-rectangle of one, and the rectangle input is what picks the part. A rectangle one pixel high returns exactly one row — a strip running through the image.

Symptom What broke First test
Not an image at ExtractColorPlanes Buffer never created, or created grayscale Trace the wire back to IMAQ Create and its type
One-pixel-high strip from ColorImageToArray Rectangle selects one row, or buffer is not color Read the array size output; expect height × width
Grab errors before processing Buffer type does not match the delivered pixel format Compare the buffer type with the Pixel Format attribute

The contract every image buffer carries

A LabVIEW vision image is not data on a wire; it is a reference to a buffer whose type is fixed at creation. IMAQ Create allocates the buffer and stamps it: grayscale 8-bit, or RGB U32, which packs one pixel into one 32-bit word. Every VI downstream reads that stamp, and the color VIs refuse anything that is not RGB U32.

The camera side carries its own half. IMAQdx documents its Pixel Format property as reading and writing the pixel format of the source sensor, so what the grab writes into your buffer is decided by that attribute. The contract closes only when both halves agree: a buffer created as RGB U32, fed by a camera delivering a color format the driver maps into it.

Cause 1: IMAQ Create never ran

This is the documented first check and the most common. If the image input of ExtractColorPlanes is wired from a control that IMAQ Create never initialized, or the Create call sits in a case structure that has not executed yet, the reference is empty and the VI reports not an image, error 1074396120.

Test. Trace the wire into ExtractColorPlanes back to its source. It must be the output of an IMAQ Create that has run before the grab loop starts, and the same buffer must be what IMAQdx Grab writes into each iteration.

Fix. Place IMAQ Create before the loop, name the buffer, and pass that one buffer into both IMAQdx Grab and ExtractColorPlanes. After the loop stops, release it.

Cause 2: the buffer exists but is grayscale

Create ran and the grab fills the image, yet ExtractColorPlanes still refuses it. Now the type stamp is the problem. An 8-bit grayscale buffer is a perfectly valid image — grab and display both work — but it is not a color image, so the color extraction VI rejects it. This is the failure you hit when the grab output itself gets refused by ExtractColorPlanes: that wire was grayscale all along.

Test. Wire the same buffer into IMAQ ImageToArray, the grayscale conversion. If it returns an array without complaint, the buffer is 8-bit grayscale and every color VI will keep refusing it. The same grayscale-versus-color mismatch breaks other chains too: see the green-channel extraction error from a stored grayscale image and the template matching bit-depth mismatch.

Fix. Recreate the buffer as RGB U32 in IMAQ Create. The image library's cast VI can convert an existing buffer between types, but re-creating at the source is one call and leaves no stale type downstream.

Cause 3: the camera is not delivering color

An RGB U32 buffer and a still-failing grab points at the camera half. Open the camera's attribute list in IMAQdx and read Pixel Format. If the active format is mono, or a format the driver does not map into packed color, the grab cannot fill a color buffer correctly.

Test and fix. Set Pixel Format to a packed RGB format in the attribute list and grab again — the property exists precisely to get and set the sensor's pixel format. Cameras that only deliver YUV are the documented exception: reading the data with IMAQdxGetImageData returns the packed byte array, and splitting it into color planes is your code's job. Bayer delivery has its own decode step before any color work — debug packed Bayer acquisition before image processing covers that order, and verifying the pixel format before processing prevents the whole class of fault. When a color frame comes out doubled instead, the pixel format behind it is again the suspect, as in the doubled color frame write-up.

The one-pixel strip is a rectangle, not a camera fault

ColorImageToArray works on a color image or on a sub-rectangle of one. The rectangle mode is the strip. If the rectangle input carries a region one pixel high — a single row across the width — the output is exactly that: a strip running through the image, which is what the webcam program produced.

Test. Read the array size output. A full-frame extraction of a 640 × 480 buffer returns 480 rows by 640 columns. One row means the rectangle input, or an unwired default that resolves to a single row, selected it.

Fix. Wire the rectangle to cover the whole frame, or leave the extraction defaults alone and confirm the dimensions. If the buffer is grayscale rather than color, no rectangle will help — work Cause 2 first. A strip one pixel high is geometry, not bandwidth, not a driver bug, and not the webcam.

Worked example: what the arrays should look like at 640 × 480

pixels per frame = width × height bytes per frame = width × height × 4 (RGB U32: 1 pixel per 32-bit word) ColorImageToArray out = height × width (unsigned 32-bit elements) bytes per color plane = width × height × 1 (ExtractColorPlanes output, 8-bit)

For a 640 × 480 webcam frame:

  • Pixels: 640 × 480 = 307,200.
  • Grab buffer: 307,200 × 4 bytes = 1,228,800 bytes per frame, about 1.2 MB.
  • ColorImageToArray: 480 × 640 = 307,200 elements at 4 bytes each = 1,228,800 bytes, matching the buffer exactly. One row means the rectangle broke it; an error means the buffer type did.
  • ExtractColorPlanes: three planes of 307,200 bytes each, 921,600 bytes total — the same pixels without the packing.

Check those numbers after the first grab and they become a permanent regression test: dimensions 480 × 640, elements 307,200, planes 3.

Wire the brightness and RGB sliders

Once ExtractColorPlanes runs, slider control is plain arithmetic on 8-bit planes.

  1. ExtractColorPlanes on the RGB U32 grab buffer gives separate red, green and blue planes.
  2. Convert each plane with IMAQ ImageToArray: three height × width arrays of 8-bit values.
  3. Apply the slider. Brightness adds an offset to every pixel; RGB gain multiplies each plane by its own factor.
  4. Clamp every result to 0–255 before writing back. Integer arithmetic past the top of the 8-bit range wraps around to dark, not white.
  5. Rebuild the display frame with IMAQ ArrayToColorImage and show that image.

Cost check: three full-frame array copies per frame. At 640 × 480 that is 921,600 bytes of plane data per frame, 921,600 × 30 = 27,648,000 bytes/s, about 28 MB/s at 30 fps — ordinary for a PC. At higher resolutions, extract and process a sub-rectangle first; the same RGB U32 buffer supports region work, as in this page on extracting image regions using RGB U32 images.

When the webcam is the limit

USB 2.0 moves 480 Mbps on the wire — 60 MB/s theoretical — and sustained streams land near 40 MB/s once protocol overhead is paid. The worked example needs 1,228,800 bytes × 30 fps = 36.9 MB/s, inside the ceiling with little margin. Doubling each dimension quadruples the load: 1280 × 960 = 1,228,800 pixels, × 4 bytes = 4,915,200 bytes per frame, × 30 = 147 MB/s, which no USB 2.0 link carries uncompressed. The camera falls back to a compressed delivery or a lower frame rate, and your slider math inherits the artifacts.

A machine-vision color camera removes that squeeze and follows the same contract — create RGB U32, set Pixel Format, grab:

Area scan camerasHikrobot MV-CU020-90GC 2.5 MP Area Scan Camera, GigE, GMAX4002, ColorMV-CU020-90GC
Sensor format
1/1.7"
Lens mount
C-mount
Interface
GigE
Resolution
Up to 3 MP
$309.00View partBuild a system with it
Area scan camerasHikrobot MV-CS200-10GC 20 MP Area Scan Camera, GigE, IMX183, Color, BasicMV-CS200-10GC
Sensor format
1"
Lens mount
C-mount
Interface
GigE
Resolution
16-25 MP
$739.00View partBuild a system with it

Both drop into the same IMAQdx workflow as the webcam. The smart camera category goes one step further and runs the inspection on the device itself; the area scan camera category covers the rest of the range.

Prevention checklist

  • Create the buffer with the color type before the loop opens. The type is fixed at creation; a grayscale buffer cannot be argued into ExtractColorPlanes later.
  • Read the camera's Pixel Format attribute before wiring any color VI. The grab writes what the sensor delivers, not what the buffer expected.
  • Check array dimensions after the first grab. Height × width means rectangle and type both agreed; a single row points at the rectangle, an error at the type.
  • Keep one buffer per purpose. Grab into the RGB U32 buffer and display from a separate one; recycling the display buffer for grabs re-introduces the mismatch.
  • Clamp slider writes to 0–255. Unclamped arithmetic wraps at the 8-bit ceiling and turns bright pixels black.

Run that list once per project and both opening symptoms stay dead. If you are starting a build rather than rescuing one, the camera finder and the camera configuration step get you to a camera whose format list you control.

Questions

Does grabbing USB camera frames in IMAQdx need a paid vision library?

The IMAQdx driver alone captures and displays frames from USB and GigE Vision cameras — enough for a live front-panel view, no vision license needed. ExtractColorPlanes, ColorImageToArray, ImageToArray and ArrayToColorImage belong to the Vision Development Module, so per-channel slider work needs that module installed and licensed.

Can IMAQdx turn a YUV camera stream into RGB for me?

If the camera's format list includes a packed RGB format, set Pixel Format to it and the grab fills an RGB U32 buffer directly. If the camera only delivers YUV, check the attribute list first before assuming either path — the unpacking then happens in your own code.

What frame rate can a USB 2.0 webcam sustain with RGB U32 delivery?

Take the worked example: 1,228,800 bytes per frame at 640 × 480. USB 2.0 carries 480 Mbps on the wire, about 60 MB/s theoretical, with sustained streams near 40 MB/s. Thirty fps lands at 36.9 MB/s, within about ten percent of the practical ceiling. When sliders add per-frame copies, 15 fps or a 320 × 240 region keeps the front panel responsive.

Should I unpack the RGB U32 words myself instead of using ExtractColorPlanes?

You can — each unsigned 32-bit element from ColorImageToArray packs one pixel's color values into a single word. The catch is byte order: whether the unused byte sits first or last is the disagreement that keeps resurfacing in RGB U32 discussions. ExtractColorPlanes unpacks all planes in one call, with no byte-order assumptions in your slider code.

What changes when I swap the webcam for a GigE Vision camera?

The buffer contract is identical: create RGB U32, set the camera's Pixel Format attribute to a color format, grab. Bandwidth moves to the network instead: a 1 GbE link carries 125 MB/s theoretical, roughly 110 MB/s sustained, so uncompressed color streams scale further. YUV-delivering GigE models behave like the YUV USB case — IMAQdxGetImageData returns packed bytes you unpack yourself.