A Python script reads a handful of images, stacks them for a side-by-side check, and the first cv2.imshow call dies with Unrecognized or unsupported array type in function 'cvGetMat'. The camera, the driver and the file path are almost never at fault: the array you handed to the window code has the wrong number of dimensions, or the installed OpenCV package cannot open windows at all. This page is for engineers debugging a Python vision station on a bench PC. You get the shape imshow actually accepts, a one-line test that names the culprit, the concatenate fix with the arithmetic checked, and a grab-loop pattern that keeps frames from GigE area scan cameras out of the trap.
Why does cv2.imshow say unrecognized or unsupported array type in cvGetMat?
The array you passed is not one image: np.array(list_of_frames) turned your list into a 4-D array of shape (2, 120, 180, 3), and cvGetMat can only convert arrays with two or three dimensions into a cv::Mat.
The error code, (-206:Bad flag (parameter or structure field)), comes from cvGetMat, the internal step that wraps a NumPy array into a cv::Mat before the window code runs. A cv::Mat holds rows, columns and optional channels; there is no slot for a batch axis. Append every cv2.imread result to a list and call np.array(frames), and NumPy adds a leading axis: two frames of 120 × 180 × 3 become one array of (2, 120, 180, 3). imshow has no batch mode to draw it.
The same refusal fires for an object array. If cv2.imread returns None on a bad path, the list still holds one element, so the check if frames: passes — a non-empty list is truthy — and np.array(frames) returns dtype object with shape (1,). Test the frame, not the list: if img is not None:.
What shape and dtype does imshow accept?
Two shapes work: a 2-D array of shape (H, W) shown as 8-bit mono, or a 3-D array of shape (H, W, C) with 1, 3 or 4 channels — the Windows window code asserts bpp == 8, 24 or 32 and nothing else.
The second traceback in this failure says the same from the inside: (-215:Assertion failed) bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32) in function 'FillBitmapInfo'. The bitmap the Windows backend paints must be 8, 24 or 32 bits per pixel. In uint8 that maps to one mono plane, one BGR image or one BGRA image, and nothing between — a (H, W, 2) array has no mapping and dies here.
Sixteen-bit and float arrays get scaled for display automatically, but converting yourself with cv2.convertScaleAbs keeps the on-screen gray levels identical to what your algorithm reads. When a color frame misbehaves after a conversion like that, the Mat type versus pixel format guide walks the full dtype table.
How do you confirm the array shape is the problem?
Print three attributes before any OpenCV call: img.ndim must be 2 or 3, img.dtype must be uint8, and a shape tuple with four entries such as (2, 120, 180, 3) names the stacked-list bug on sight.
- Run
print(img.ndim, img.dtype, img.shape)on the line before the call. ndim 2 or 3 with dtype uint8: the array is innocent, look at the window instead. - ndim == 4: a list got stacked. Jump to the concatenate fix below.
- dtype object or an empty shape: a None got into the list. Print the exact path string and switch the check to
if img is not None:. - Array clean but the window still paints nothing: the event loop is the suspect, and the blank image window troubleshooting guide covers waitKey, event pumping and window threads.
img = frames[0] # first element of your list: np.ndarray or None
print(type(img)) # <class 'numpy.ndarray'>
print(img.dtype) # uint8
print(img.shape) # (120, 180, 3) good
# (2, 120, 180, 3) stacked list — fix below
How do you stack several images into one imshow window?
Join the list along the width axis with np.concatenate(frames, axis=1): two 120 × 180 × 3 frames become one 120 × 360 × 3 image of 129,600 bytes, and imshow draws it as a side-by-side strip.
axis=1 joins columns, axis=0 stacks rows and axis=2 merges channels — the last produces meaningless colors, never use it for layout. Concatenate needs equal sizes on the remaining axes, so two (120, 180, 3) frames strip cleanly. But (120, 180, 3) next to (1080, 1920, 3) raises a ValueError inside NumPy before OpenCV sees anything.
import numpy as np
import cv2
frames = [] # list of np.ndarray, uint8
frames.append(cv2.imread("left.png")) # -> (120, 180, 3)
frames.append(cv2.imread("right.png")) # -> (120, 180, 3)
stacked = np.array(frames) # wrong: (2, 120, 180, 3), cvGetMat refuses it
strip = np.concatenate(frames, axis=1) # right
print(stacked.shape) # (2, 120, 180, 3)
print(strip.shape) # (120, 360, 3)
print(strip.size) # 129600 — that is 120 * 360 * 3 bytes
cv2.imshow("strip", strip)
cv2.waitKey(0)
cv2.destroyAllWindows()
The arithmetic belongs on the bench card: 180 + 180 = 360 columns, and 120 × 360 × 3 = 129,600 bytes, about 0.13 MB per copy. np.hstack(frames) is the identical call for images, and np.vstack(frames) returns (240, 180, 3). When you want one window per region instead — four cameras, four tiles — the ROI split and display guide shows that pattern.
Why does imshow report the function is not implemented?
This error never looks at your array: the installed OpenCV package has no GUI backend, so cv2.imshow raises before any shape is checked, and the fix is the package, not the pixels.
The message says it outright — the window code was left out, and it names the missing Windows, GTK+ or Cocoa support. Two wheels ship on PyPI: opencv-python and opencv-contrib-python include the window code; opencv-python-headless leaves it out by design for servers and containers. A headless wheel on a machine that should show windows produces exactly this failure.
Fix it inside the environment your script actually runs. pip show opencv-python and pip show opencv-python-headless list which one is present; remove the headless wheel and install a GUI-enabled build into that same environment, then start a fresh interpreter so the new library loads. On Ubuntu or Debian source builds the message's own advice holds: install libgtk2.0-dev and pkg-config, then re-run the cmake configure step.
One machine can carry both kinds, one per environment: a desktop environment for debug windows, a cell environment that never opens one. The live preview in GUI applications guide covers the window loop that follows the fix.
How do you display live camera frames without cvGetMat errors?
Convert at the grab and assert before display: cast every frame to a uint8 array as the SDK hands it over and require img.ndim in (2, 3), so a bad shape stops your loop at the grab, not inside a window call.
Camera SDKs deliver a buffer that converts straight to (H, W) for mono or (H, W, 3) for color, so the pattern is three lines:
img = np.asarray(grab()) # grab() is your SDK's acquire call
assert img.ndim in (2, 3), img.shape
preview = cv2.resize(img, None, fx=0.25, fy=0.25)
cv2.imshow("cam0", preview)
cv2.waitKey(1)
For bench debugging, the MV-CU020-90GC pairs a 1/1.7-inch global shutter color sensor with a GigE link, and its frames drop straight into that loop.
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
- Interface
- GigE
- Resolution
- Up to 3 MP
High-resolution sensors make that resize line earn its keep. The LS-CMR-0166 delivers 4000 × 3000 frames. An 8-bit BGR copy of one holds 4000 × 3000 × 3 = 36,000,000 bytes; the preview copy at fx = fy = 0.25 lands at 1000 × 750 × 3 = 2,250,000 bytes. Show the small one, inspect the full one.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
Grab loops that allocate a fresh array per frame grow without bound; the buffer reuse guide keeps memory flat across a shift.
On the cell, drop the windows altogether: run the headless build, write frames to disk on failure, and let a vision controller drive cameras and lights directly. The MV-VC2140-128G40-1T has 8 GB of memory and four built-in light channels for exactly that role, while your desktop PC keeps the debug windows. The camera finder filters by resolution, interface and shutter when you are picking the bench camera first.
- LAN ports
- 3-4 LAN ports
- USB 3 ports
- 2 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
Which fix matches which error message?
Match the message to the move: the table covers the four ways an imshow call fails in a vision script and the one-line fix for each.
| Message | What it means | Fix |
|---|---|---|
(-206:Bad flag) Unrecognized or unsupported array type in cvGetMat |
Four dimensions, or dtype object from a None in the list | Pass one frame, or np.concatenate(frames, axis=1) for a strip |
(-215:Assertion failed) bpp == 8, 24 or 32 in FillBitmapInfo |
The array reached the window but is not 8, 24 or 32 bpp | Convert to uint8 with 1, 3 or 4 channels |
(-2) The function is not implemented in cvShowImage |
The package has no GUI backend | Install a GUI-enabled opencv-python build into that environment |
| Window frame opens, no pixels, no error | The event loop never pumped | Call cv2.waitKey after imshow, then retest |
One decision per row: a 4-D stack becomes a strip with axis=1, a bpp assertion becomes a uint8 conversion, a not-implemented call becomes a package change in that environment, and a silent empty window becomes a waitKey. None of the four sends you shopping for a new camera.
What do you check before the next imshow call?
Five checks cover every imshow failure in this guide, each takes seconds at the prompt, and each maps back to a fix in the table above, so run them top to bottom before rebuilding anything.
- img.ndim is 2 or 3 — cvGetMat wraps only two- and three-dimensional arrays into an image.
- img.dtype is uint8 with 1, 3 or 4 channels — the window paints 8, 24 or 32 bpp and stops on anything else.
- img is not None — a list holding one None is still truthy, so test the frame itself.
- One cv2.waitKey call follows every imshow — the window paints when the event loop runs.
- The environment that shows windows holds a GUI-enabled build — headless wheels belong where no window ever opens.
Once frames render, choose the hardware side in the system configurator, or keep going on the systems topic page.
Questions
Does cvGetMat also reject DNN blobs and other 4-D arrays?
Yes. A network input blob has shape (N, C, H, W) in float32 — four dimensions and the wrong layout for a picture — so cvGetMat refuses it exactly like your image stack. Convert before showing: cv2.dnn.imagesFromBlob returns (H, W, C) arrays from a blob, or squeeze the batch axis and scale the floats to uint8 yourself.
Why did my window open with a border and a close button but no image?
The window was created, then the blit failed or the event loop never ran, so the frame stays unpainted. Read the terminal: a (-215) assertion means the array failed the 8, 24 or 32 bpp check; no error at all points to a missing or swallowed waitKey. Fix the array first, then the event loop.
Is np.hstack the same as np.concatenate(frames, axis=1)?
Yes, for image stacks. np.hstack concatenates along axis 1, so two (120, 180, 3) frames give (120, 360, 3) either way; np.vstack joins along axis 0 and returns (240, 180, 3). The difference only appears outside images: for 1-D arrays hstack joins along axis 0, which never comes up with (H, W, C) frames.
How large is a stacked display image in memory?
For uint8, bytes equal rows × columns × channels. Two 4000 × 3000 BGR frames side by side need 4000 × 6000 × 3 = 72,000,000 bytes, about 72 MB, for one copy of the strip. A display copy resized at fx = fy = 0.5 needs 1500 × 2000 × 3 = 9,000,000 bytes, about 9 MB — measure on the full-resolution original.
Can cv2.imshow run inside a notebook cell?
Only as a native OS window, and the kernel blocks on cv2.waitKey until you dismiss it, stalling the notebook session. For inline viewing, write the array out with cv2.imwrite and open the file, or pass the (H, W, 3) array to a plotting library that renders inline. Keep native windows for script runs on the bench PC.


