Window/Level on the TI C6x EVM
The previous Visual Studio window/level program was interesting in that it illustrated how slider bars allow the user to interactively control the input parameters for an image processing algorithm, and how algorithm output can be visualized in real-time. Suppose as part of an embedded application, you had to implement window/level, perhaps as a component of a larger imaging subsystem. How would you go about testing your C6x implementation? In this example, we will draw upon some of the tools we previously used to feed data into the TI IDE, but will augment it with the ability to dynamically change the window and level parameters from within CCStudio. The end result, while not approaching the level of user interaction provided by the Visual Studio C++ application, nevertheless serves to show how a fair amount of interactivity may be obtained using CCStudio General Extension Language (GEL) files. The alternative is to hard-code the window and level parameters in the source code, and rebuild the application each time one wants to test various window and level settings – hardly a solution conducive to rapid and effective testing.
In the Chap3\window_level\WindowLevelCCS directory a CCStudio project named window_level. p j t may be found. The linker settings, accessed through the linker command file window level. cmd, are identical to those of the contrast stretching CCStudio project of 3.2.2, and the build settings are also similar except that this project does not utilize any IMGLIB functions, and thus there is no need to link to imglib. lib nor include the IMGLIB include file directory. Listing 3-10 are the contents of the sole C module for this project, window_level. c.
Listing 3-10: window level, c.
This program performs its processing in-place, that is the pixel data is fed into the array img and then this same array is subsequently overwritten as the LUT processing takes place. The program’s high-level flow can be garnered from the main function, where we first initialize the EVM board, then construct a LUT according to the values contained in the global variables window and level, and finally process the image in apply_lut. In short, this C program is more or less a direct line-by-line port of Algorithm 3-3.
Fair enough, but then how is the image data read into the program and how can we dynamically alter the window and level parameters, a la the Visual Studio C++ application from 3.3.2? For this functionality, we turn to a very powerful add-on feature to CCStudio, the GEL file. GEL files are written in an interpretive language with a C-like syntax that can plug into CCStudio, and are quite useful for automating repetitive tasks – such as feeding data into the DSP and dynamically changing variables. Listing 3-11 is the contents of window_level. gel, which can be found in Chap3\window_level\WindowLevelCCS.
Listing 3-11: window_level. gel
This GEL file adds four plug-in features into CCStudio, which should be self-explanatory from the function names in Listing 3-11. Loadlmage reads in a CCS data file, specified by the third input argument, and sends it to the global variable specified by the fifth argument (in this case img). The test data contained in the CCStudio-formatted data file can be created with the save_ccs_data_file MATLAB function (see Listing 3-4) or through other means. Save Image performs the converse, taking data contained in img and sending it to a CCStudio data file, which in turn can be parsed using the read_ccs_data_file MATLAB function (see Listing 3-5). The remaining two functions, W and L, implement sliders allowing the user to change window and level, respectively.
To see the application in action, build and load the program window_level. out onto the DSP. Set a breakpoint in the main function, at the line where make_lut is called. Run the program, and when execution halts at the breakpoint, load window_level.gel from the File|Load GEL menu selection. After the GEL file has been loaded into CCStudio, a new menu appears under the main GEL menu, "Window/Level", whose name is specified by the first line of Listing 3-11. Underneath this new menu is a sub-menu with the four previously described selections. You can now show the window and level slider bars by using the GEL|Window\Level|W and GEL|Window\Level|L menu options.
Figure 3-18. Code Composer Studio running window_level. out, after having selected the GEL|Window\Level|W, GEL|Window\Level|L, and GEL|Window\Level|Load Image menu options. Pressing the "»" button on the tape-player control sends the data in tanks . dat into the global img array.
Selecting GEL|Window\Level|Load Image displays a CCStudio tape-player control, through which you feed the input data to the DSP. Note that you can change the location of the input data file to match whatever happens to be on your local disk by modifying the third argument to GEL_AddOutputFile in the Loadlmage GEL function, and subsequently reloading the GEL file. After selecting these three menu options, the CCStudio IDE will look similar to the screen-shot shown in Figure 3-18.
The forward arrow in the tape-player control fills img with the pixel values stored in the CCStudio data file, and the slider bars update the window and level global variables. After window and level have been set, step past apply_lut in the debugger, and then select Gel|Window\Level|Save Image. This menu selection brings up another tape player control, which is then used to send the contents of img to the file specified in the third argument to GEL_AddOutputFile.