Wavelet-Based Edge Detection (Image Processing) Part 2

Multiscale Edge Detection on the C6701 EVM and C6416 DSK

Our initial foray into embedded wavelet-based image processing is a set of programs written and tested on the C6701 EVM and C6416 DSK platforms. These programs are all fixed-point C implementations of the multiscale edge detection scheme shown in MATLAB form in Listing 6-6. The IMGLIB wavelet functions implement the classical 2D DWT as discussed in 6.1, and thus we implement the multiscale edge detector using hand-crafted C functions that implement the algorithme a trous described in the previous section. In the Chap6\wave_edge directory on the CD-ROM are three CCStudio project directories, which are described in more detail in this section: C6701EVM, C6701EVM_HPI, and C6416DSK.

We begin by presenting a wholly unoptimized and standalone fixed-point implementation of the multiscale edge detector built and tested on the C6701 EVM. This project will also run efficiently on a C62xx platform without any code changes because it uses only fixed-point arithmetic. After introducing the fixed-point C implementation of the core algorithm, an interactive system along the lines of the RTDX application of 5.2.5 is given, although this time we employ the services of the Host Port Interface (HPI) to shuttle data to and fro. Finally, the implementation of (1) and (2) is optimized for the C6416 DSK with a combination of both higher-level algorithmic modifications and lower-level optimizations using specialized C compiler intrinsics.


Standalone Multiscale Edge Detector (C6701EVM)

The project directory Chap6\wave_edge\C670lEVM is a very simple EVM project that relies on a technique used throughout this topic to prototype image processing algorithms – the actual input image is built into the program by inlining the pixel data of the "peppers" image (see Figure 611) in the header file image . h. The linker command file is not noteworthy except to say that the . cinit segment has been remapped to external memory due to the fact that the pixel data is compiled into the binary. The contents of the main source file that makes up this program, wave_edge. c, is shown in Listing 6-7.

Listing 6-7: wave edge . c

Listing 6-7: wave edge . c

 

 

 

 

Listing 6-7: wave edge . c

 

 

 

 

Listing 6-7: wave edge . c

 

 

 

 

Listing 6-7: wave edge . c

 

 

 

 

Listing 6-7: wave edge . c

One thing to keep in mind is that the implementation of Listing 6-7 is sub-optimal for a variety of reasons – it is meant to illustrate some of the details behind a fixed-point wavelet-based image processing system and for the sake of clarity and time many optimizations are omitted. Some of these optimizations are applied in the C6416 DSK project, and in particular the DMA paging optimization of 4.3 would go a long way towards improving performance. All of the image buffers are placed in external memory, and consequently we incur a large cost attributed to the EMIF as we access external memory during the processing loops.

One aspect of this program that differs from all of the other previous C image processing algorithms is that the wavelet arrays are not "flattened" and are explicitly defined as multi-dimensional arrays in wave_edge . h, as can be seen in Listing 6-8. This simplification is merely for the purpose of clarity – the optimized implementation described in 6.2.3.3 uses flattened one-dimensional image buffers which then enables us to use certain compiler intrinsics to our advantage.

Listing 6-8: wave_edge.h, which contains definitions for the approximation and detail coefficient matrices used in Listing 6-7.

Listing 6-8: wave_edge.h, which contains definitions for the approximation and detail coefficient matrices used in Listing 6-7.

 

 

 

Listing 6-8: wave_edge.h, which contains definitions for the approximation and detail coefficient matrices used in Listing 6-7.

The approximation and detail coefficient are defined as three-dimensional signed integer matrices, and the length of the third dimension of approx is one more than MAX_LEVELS because the first approximation image matrix is the input image pixels shifted to the left by 9 bits, for fixed-point considerations. As we have seen previously, when developing fixed-point algorithms the programmer must always remain cognizant of the balancing act between dynamic range and resolution. With wavelet algorithms, this problem becomes more acute because the range of possible values increases in proportion to wavelet scale, due to the presence of the high-pass filter. At the same time, we strive to retain adequate resolution and this is the reason for the use of 32-bit integers for storage of the approximation and detail coefficient matrices – a minimum of 22 bits is required to avoid overflow, because we multiply by 1/9 in Q15 format (3640) within segment_detail_image. With one bit reserved for sign, that leaves 9 "binal" (as opposed to decimal) points, which accords us sufficient resolution for this particular algorithm. The copy and scaling operation is performed in main, where the input data is copied from in_img to approx and then bit-shifted.

The first step is to perform the wavelet analysis, which is done in wave_decomp_a_trous. This function contains a loop which first low-pass filters the current approximation image, and then forms the detail image by subtracting two successive approximation images. Recall that the key reason for choosing the B3 spline filter as the wavelet is its suitability for fixed-point arithmetic – this fact is clearly illustrated in the convolution inner loop where all the divisions are replaced by corresponding right bit shifts. Upon reaching the end of the final iteration through the outer-most loop within wave_decomp_a_trous, the mean absolute value of the final detail image is computed and returned back to the caller. Moreover, we segment the absolute value of this final detail image, and thus we right-shift those coefficients back by 9 bits. The _abs compiler intrinsic is used in lieu of the C ternary operator to quickly calculate the absolute value of the deltas.

Upon completion of wave_decomp_a_trous, the wavelet decomposition has been carried out to the specified number of levels, and what is left is to binarize the final detail coefficient image via the dynamic threshold segmentation algorithm developed in Listing 6-6. This operation is carried out in segment_detail_image, and as in the MATLAB version of the algorithm, the wavelet modulus maxima is estimated by comparing each detail coefficient at location (irow, icol) with the average of its surrounding 3×3 neighborhood. This local average is in essence a 2D box filter and a fixed-point implementation of this process was discussed in full detail in 4.3.2. The segmented edge image, where 0 signifies a non-edge pixel and 255 an edge, is placed into out_img and the result can be visualized using CCStudio’s image graphing feature, as discussed in 4.3.1.

Next post:

Previous post: