16-bit Images in NI Vision

Updated Nov 3, 2017

Issue Details

I need to analyze a 16-bit image using NI-Vision. My data was stored using unsigned values (U16), but the Image datatype is defined with signed values (I16).


Many applications and camera drivers create 16-bit image data using unsigned values. This means that the darkest pixels have a value of 0 and the brightest have a value of b1111111111111111 (xFFFF or d65535). However, the Image datatype used in LabVIEW by NI Vision and NI-IMAQ reads data values using a signed interpretation. As Fig 1 shows, this leads to misinterpreted images when an array of data is changed to this datatype.

Figure 1: Unsigned and Signed Interpretation of Data

This interpretation difference can be overcome by subtracting a constant value of x8000 (d32768) from the raw values . However, neither the U16 nor I16 ranges allow this subtraction. (If xFFFF is subtracted from the original values, an underflow will occur.) There are two standard solutions to this problem:

Intuitive Solution:
Figure 2 shows that a 32-bit signed integer, which has a range that can accommodate every possible value in the operation, can be used as an intermediate state. The U16 image data is cast to I32, then the constant is subtracted, then the new data (which is in the allowed range of an I16) is cast to I16.
Figure 2: Using I32 Representation as an Intermediary

The LabVIEW code shown in Figure 3 accomplishes this adjustment and uses the resulting array for conversion to the Image datatype. (Note: the IMAQ ArrayToImage VI is part of the Vision Development Module and is not included with the NI-IMAQ driver.)  This solution is ideal for learning environments and example programs.

Figure 3: Importing a U16 image to the Image datatype in LabVIEW

Architectural Solution: 
The LabVIEW code shown in Figure 4 takes advantage of computer architecture and uses a common XOR gate with typecasting to accomplish the same task as the code shown in Figure 3.  In a practical application, this code will execute faster and more efficiently than that above.

Figure 4: Converting U16 to I16 with Type Cast Function and XOR