Display with color tables
In this sample you apply color tables to the grayscale images. You essentially use the following functions:
Explanation
There are several reasons why you would want to apply a color table to a monochrome image. These include, for example, a more pleasant appearance and a display of the value range that is clearer to the human eye. This is above all relevant for 16-bit images, as the value spectrum is significantly more recognizable if it is distributed over three color channels.
Depending on the use case, you would like to use various color tables. TwinCAT Vision provides some predefined color gradients via the enum ETcVnColorMap. You can also define your own color gradients and create color tables with them.
In this sample you apply various color tables to the following grayscale gradient (with a value range of 16 bits).
Of course, you can also use your own images. Note that you can only use 1-channel images, or you will have to perform an appropriate conversion beforehand using F_VN_ConvertColorSpace.
Program
Before a color table can be applied to an image, it must first be created. To this end, it must be known whether the color table is to be for 8-bit or 16-bit images, as depending on that it will require a different number of entries (see Color tables). Accordingly, you must set the parameter eColorMapSize
of the type ETcVnColorMapSize to 256
in the case of 8-bit and 65536
in the case of 16-bit to match the bit depth of the input image ipImageIn
. You achieve this by querying the element size of the pixel format by means of F_VN_GetImageInfo:
hr := F_VN_GetImageInfo(ipImageIn, stImageInfo, hr);
IF stImageInfo.stPixelFormat.nElementSize = 8 THEN
eColorMapSize := TCVN_CMS_256;
ELSIF stImageInfo.stPixelFormat.nElementSize = 16 THEN
eColorMapSize := TCVN_CMS_65536;
END_IF
A color table is generated on the basis of a color gradient. You can either manually define a color gradient or use one from a template. This sample deals with the distinction on the basis of the parameter bUseCustomColors
.
IF bUseCustomColors THEN
// create color map from custom-defined colors
<...>
ELSE
// create color map from preset
<...>
END_IF
You define a color gradient manually by creating a container with several entries of the type TcVnVector3_REAL. Each entry represents a color. The colors are interpreted as being evenly distributed over the definition area when creating the color table; all other values are linearly interpolated for each of the three channels. A color gradient from the array aColors
with the three colors red, green and blue is used here. You then create the color table with the function F_VN_GenerateCustomColorMap.
VAR
aColors: ARRAY [0..(N_COLORS-1)] OF TcVnVector3_REAL := [
[255, 0, 0],
[0, 255, 0],
[0, 0, 255]
];
END_VAR
hr := F_VN_CreateContainerFromArray(ADR(aColors), ipColors, ContainerType_Vector_TcVnVector3_REAL, N_COLORS, hr);
hr := F_VN_GenerateCustomColorMap(
ipColorMap := ipColorMap,
ipInitialColors := ipColors,
eColorMapSize := eColorMapSize,
hrPrev := hr
);
In order to use a predefined color gradient, use the function F_VN_GenerateColorMap and set the parameter eColorMap
to the desired color gradient from the enum ETcVnColorMap. In this case this is initially set to JET
.
VAR
eColorMap: ETcVnColorMap := TCVN_CM_JET;
END_VAR
hr := F_VN_GenerateColorMap(
ipColorMap := ipColorMap,
eColorMap := eColorMap,
eColorMapSize := eColorMapSize,
hrPrev := hr
);
The color table created is a container that stores a color to be issued for every possible value in the input image. Therefore you can also create a color table yourself by defining all 256 or 65536 entries and then directly creating a container out of them. In most cases, however, the use of the API functions is simpler.
Finally, apply the color table created to the input image to obtain the desired result. The result image is always a 3-channel 8-bit image.
hr := F_VN_ApplyColorMap(
ipSrcImage := ipImage,
ipDestImage := ipImage,
ipColorMap := ipColorMap,
hrPrev := hr
);
The application of a predefined JET color table to the input image shown above produces the following result: