1. building project on c6416 dskut27/c6416dsk.pdfc6416 report – uday kiran thummalapalli 1....

40
C6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK Connect the DSK kit to the PC and open the Code Composer Studio. All the project files are located under directory “C:\ti\my projects\”. 1) Click Project >> New… to open a build a new project. Enter the project name as contrast (user specific) as shown in Fig 1(b). Figure 1.(a) (b) Creating a project 2) Add the required files such as library files, source files, linker files (.cmd), assembly files (.asm). Click on Project >> Add Files to Project … Locate your files as shown in Fig 2. 1

Upload: others

Post on 03-Aug-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli

1. BUILDING PROJECT ON C6416 DSK

Connect the DSK kit to the PC and open the Code Composer Studio. All the project files are located under directory “C:\ti\my projects\”.

1) Click Project >> New… to open a build a new project.

Enter the project name as contrast (user specific) as shown in Fig 1(b).

Figure 1.(a) (b) Creating a project

2) Add the required files such as library files, source files, linker files (.cmd), assembly files (.asm). Click on Project >> Add Files to Project … Locate your files as shown in Fig 2.

1  

Page 2: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

The required libraries are csl6416.lib (C:\ti\C6000\cgtools\lib), dsk6416bsl.lib (C:\ti\C6000\bios\lib), dsp64x.lib (C:\ti\C6400\dsplib\lib), img64x.lib (C:\ti\C6400\imglib\lib), rts6400.lib (C:\ti\C6000\rts\lib). A linker is always required to allocate the memory and define memory address locations.

Figure 2.(a) (b) Adding files to project

3) Click on Project >> Scan All File Dependencies. This step will locate all the required header files.

2  

Figure 3.

Page 3: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

4) Configure the Build Options

Figure 4.

5) Follow the below figure for the configurations. As the chip we are using is C6416, select the target version as C64xx. Under the preprocessor section, add the include paths for the imglib, dsplib, libraries as the required header files have to be located. Define the symbols here as CHIP_6416.

3  

Page 4: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

Figure 5.(a) (b) (c) (d) (e) Steps showing the configurations for a C6416 DSP

6) Build the project. An .out file is created in Debug folder if the compilation is successful with no errors.

4  

Page 5: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

Figure 6.

7) Locate and Load the .out file.

Figure 7.(a) (b) Loading the .out files

5  

Page 6: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

8) Run the program by pushing the button as shown in the Fig 8 or use the hot key F5.

Figure 8. Executing the program

6  

Page 7: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli  

2. READING AND VIEWING IMAGE FROM A LINEAR ARRAY (MATRIX)

Load the project named Blurred located in the my projects folder. Build the project with all the libraries, source files and linker files included.

Image.h file initializes the image into a linear array. The intensities can be generated by using MATLAB. The array in_img is the input image.

//Image.h #define X_SIZE 256 #define Y_SIZE 256 #define N_PIXELS X_SIZE*Y_SIZE //define pixels intensities in the input image unsigned char in_img[N_PIXELS] = {137,137,134,136,138,135,135,132, 133,139,130,132,132,127,130,129,131,132,139,139,143,147,151,151,149,149,144,134,119,118,90,80,64,62,61,69,71,73,73,74,78,74,76,79,76,75,78,76,78,78,74,74,79,83,83,88,83,90,93,91,96,94,91,102,98,101,97,97,107,102,100,97,97,96,103,99,99,97,104,104,98,101,102,103,101,101,100,101,103,103,101,100,102,105,101,101,105,103,105,105,105,103,104,103,107,104,102,101,100,101,101,99,99,106,105,100,100,100,97,101,104,102,103,106,100,102,96,105,111,103,99,98,101,99,102,98,98,101,96,105,98,99,98,…………………………………………………………………………………………………………………………………,133,139,130,132,132,127,130,129,131,132,139,139,143,147,151,151,149,149,144,134,119,118,90,80,64,62,61,69,71,73,73,74,78,74,76,79,76,75,78,76,78,78,74,74,79,83,83,88,83,90,93,91,96,94,91,102,98,101,97,97,107,102,100,97,97,96,103,99,99,97,104,104,98,101,102,103,101,101,100,101,103,103,101,100,102,105,101,101,105,103,105,105,105,103,104,103,107,104,102,101,100,101,101,99,99,106,105,100,100,100,97,101,104,102,103,106,100,102,96,105,111,103,99,98};

Blurred.c can take the input image and convolve a mask which can blur the image. H is the convolving mask with weighted blurring intensities of box size 3. A higher order mask can be used by redefining the mask H (NH) and also the arguments for ‘IMG_con_3x3’ function. #include <dsk6416.h> #include <stdio.h> /* printf() */ #include <string.h> /* memset() */ #include <img_corr_3x3.h> #include <csl_timer.h> #include "image.h" /* image\kernel dimensions, example pixel data */ #pragma DATA_ALIGN (in_img, 8); #pragma DATA_SECTION (in_img, "SDRAM");

7  

Page 8: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

#pragma DATA_ALIGN (out_img, 8); #pragma DATA_SECTION (out_img, "SDRAM"); unsigned char out_img[N_PIXELS]; /* filtered image */ /* filter dimensions and coefficients */ #define NH 3 /* kernel is of size NHxNH (needs to be 3 for this program) */ #define BOUNDARY (NH/2) /* 1st and last BOUNDARY rows/cols in output set to 0 */ #pragma DATA_ALIGN (H, 8) char H[NH*NH] = { 1, 2, 1, /* 1/16 2/16 1/16 */ 2, 4, 2, /* 2/16 4/16 2/16 */ 1, 2, 1, /* 1/16 2/16 1/16 */ }; #define SHIFT 4 /* right-shift by 4 (div by 16) */ #define N_COLS_FILTERED Y_SIZE-2*BOUNDARY /* * Faster than memset(), count must be a multiple of * 8 and greater than or equal to 32 */ void memclear( void * ptr, int count ) { long *lptr = ptr; _nassert((int)lptr%8==0); #pragma MUST_ITERATE (32); for (count>>=3; count>0; count--) *lptr++ = 0; } void filter_image() { unsigned char *p = out_img+BOUNDARY*Y_SIZE; int ii, irow; /* set 1st BOUNDARY rows to zero */ memclear(out_img, BOUNDARY*Y_SIZE); /* filter the interior region of the image matrix */ for (irow=BOUNDARY; irow<X_SIZE-BOUNDARY; ++irow) { /* 1st BOUNDARY cols are zero */ for (ii=0; ii<BOUNDARY; ++ii) *p++ = 0; /* * IMG_conv_3x3 requires 3rd arg to be a multiple of 8, * that's why we pass in Y_SIZE instead of N_COLS_FILTERED * (last few filtered pixels are ignored)

8  

Page 9: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

*/ IMG_conv_3x3(&in_img[(irow-BOUNDARY)*Y_SIZE], p, Y_SIZE, H, SHIFT); /* last BOUNDARY cols are zero */ p += N_COLS_FILTERED; for (ii=0; ii<BOUNDARY; ++ii) *p++ = 0; } /* last BOUNDARY rows are zero */ memclear(out_img+(X_SIZE-BOUNDARY)*Y_SIZE, BOUNDARY*Y_SIZE); } int main(void) { TIMER_Handle hTimer; unsigned int start, stop, overhead, total = 0, t; /* timing */ const int N = 10; /* how many times to profile */ int ii = 0; DSK6416_init(); /* initialize the DSK board support library */ /* configure timer */ hTimer = TIMER_open(TIMER_DEVANY,0); TIMER_configArgs(hTimer, 0x000002C0, 0xFFFFFFFF, 0x00000000); /* compute overhead of calling the timer. */ start = TIMER_getCount(hTimer); /* called twice to avoid L1D miss. */ start = TIMER_getCount(hTimer); stop = TIMER_getCount(hTimer); overhead = stop - start; for (; ii<N; ++ii) { start = TIMER_getCount(hTimer); /* begin "profile area" */ filter_image(); stop = TIMER_getCount(hTimer); /* end "profile area" */ t = (stop-start-overhead) * 8; total += t; printf("# cycles to filter image: %d\n", t); } printf("avg time is %.2f cycles.\n", (float)total/(float)N); }

9  

Page 10: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

VIEWING THE IMAGE USING CCS

CCS offers simple ways of viewing the data as a graph, histogram, or even as an image. Below steps illustrate a walkthrough for displaying an image.

1) Click View >> Graph >> Image …

2) Select the RGB color space to select the R,G,B plane. A gray scale image can be viewed if all the planes, i.e., R,G,B planes have same arrays. Enter the address location of the image located or a HEX address where the image data have to be read.

10  

Page 11: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

3) Select the Lines per Display as #rows in the image and Pixels per Line as #columns in the image. Please Select Image Origin as Top Left, else you have an inverted image.

11  

Page 12: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

4) Now you can see the image displayed in a new window as shown below. A pointer (crosswire) is provided to view the pixel intensities and the locations.

12  

Page 13: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli

3. MAKING A CONFIGURATION (.cdb) FILE

Writing a linker (.cmd) file is made much easier using the DSP/BIOS configuration

tool of the CCS Studio. Tutorial below here shows a brief description of configuring a

simple memory mapping, RTDX enabling with buffer sizes.

1. Click File >> New >> DSP/BIOS Configuration…

2. Select C64xx.cdb respectively for the C6416 DSP.

3. Expand the System >> Memory trees to view the memory mapping of the chip.

You can insert a new memory segment by right-clicking on the Memory Section

Manager and select Insert MEM…

13

Page 14: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

4. Rename the new memory segment as SDRAM (for eg.). Explore the properties of

the memory by right-clicking on the memory section.

14

Page 15: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

This opens up a new dialog box where you can edit the starting address and length of the

memory location on the physical address map. Sample entries are shown in the figure

below. You can customize the mapping as per your choice.

5. Similarly, under the tree of Input/Output, right click on the section RTDX – Real-

Time Data Exchange Settings. You can add an entry for RTDX by selecting the

Properties option.

15

Page 16: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

On the safe size, enter the buffer size double than required i.e., if the data is 64K (256 x

256 = 65536) have a buffer size of 128K (65536 x 2 = 131072).

6. As you have added the required data segments, you can now save the cdb file and

add that to the project. Save the .cdb file by navigating through File >> Save As…

Include the file in the project (Project >> Add Files to Project …)

16

Page 17: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli

4. IMAGE CONTRAST STRETCHING

Contrast stretching (also called Normalization) attempts to improve an image by

stretching the range of intensity values it contains to make full use of possible values. The

first step is to determine the limits over which image intensity values will be extended.

These lower and upper limits will be called a and b, respectively (for standard 8-bit

grayscale pictures, these limits are usually 0 and 255). Next, the histogram of the original

image is examined to determine the value limits (lower = c, upper = d) in the unmodified

picture. If the original range covers the full possible set of values, straightforward

contrast stretching will achieve nothing, but even then sometimes most of the image data

is contained within a restricted range; this restricted range can be stretched linearly, with

original values which lie outside the range being set to the appropriate limit of the

extended output range. Then for each pixel, the original value r is mapped to output value

s using the function:

The code below shows the logic for image contrast stretching:

#include <limits.h>

MATH_H 1

MGLIB */

IZE*Y_SIZE

l not fit in

#include <stdio.h> D_#define _TI_ENHANCE

#include <math.h> ogram.h> /* I#include <img_hist

image dimensions */ /*

#define X_SIZE 128 #define Y_SIZE 128 #define N_PIXELS X_S signed char in_img[N_PIXELS]; un

Input & output buffer both wil/*

internal chip RAM, this pragma places the output buffer in off-chip RAM */

AM"); #pragma DATA_SECTION (out_img, "SBSR

17

Page 18: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

unsigned char out_img[N_PIXELS]; /* image histogram goes here, the pragma

scratch buffer needed by IMGLIB */

id compute_range(unsigned char *pin, int N, centile2,

unsigned short cumsum = 0, /* running tally of the cumulative sum

T1 = round((float)N * percentile1), /* threshold

;

image histogram */

24);

location for 1st (lower bound) percentile in histogram */

location for 2nd (upper bound) percentile in histogram */

id contrast_stretch(unsigned char *pin,

aligns the buffer on a 4-byte boundary which is required by IMGLIB */ #pragma DATA_ALIGN (hist, 4) unsigned short hist[256]; /*unsigned short t_hist[1024]; vo float percentile1, float per unsigned char *pbin1, unsigned char *pbin2) { */ for 1st bin */ T2 = round((float)N * percentile2); /* threshold for 2nd bin */ int ii, jj /* calc /* buffers must be initialized to zero */ memset(t_hist, 0, sizeof(unsigned short)*10 memset(hist, 0, sizeof(unsigned short)*256); IMG_histogram(pin, N, 1, t_hist, hist); /* find for (ii=0; ii<256; ++ii) { cumsum += hist[ii]; if (cumsum >= T1) { *pbin1 = ii; break; } } /* find for (jj=ii+1; jj<256; ++jj) { cumsum += hist[jj]; if (cumsum >= T2) { *pbin2 = jj; break; } } } vo unsigned char *pout, int N) { unsigned char a, b; /* lower & upper bounds for scaling function */ float scale, pixel; int ii;

18

Page 19: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

/* estimate dynamic range of the input */ compute_range(pin, N, .05, 0.95, &a, &b); /* apply linear scaling function to input pixels, taking care to handle overflow & underflow */ scale = 255.0/(float)(b-a);

19

ii] - a) * scale );

t main(void)

g, out_img, N_PIXELS);

Load the image via File >> Data >> Load… and input the file Xrays.dat for the

file size 16384. (128 X 128 = 16384). Next, run the program and observe the output.

View the images arrays using the View >> Graph >> Image… utility from the CCS.

Below images shows the result of the operation.

for (ii=0; ii<N_PIXELS; ++ii) { pixel = round( (float)(pin[ /* clamp to 8 bit range */ pout[ii] = (pixel<0.f) ? 0 : ((pixel>255.0) ? 255 : pixel); } } in{ //evm_init(); /* initialize the board */ DSK6416_init(); contrast_stretch(in_im printf("contrast stretch completed"); }

Page 20: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli

5. LAPLACE TRANSFORMATION USING IMGLIB LIBRARY

The Laplacian is a 2-D isotropic measure of the 2nd spatial derivative of an

image. The Laplacian of an image highlights regions of rapid intensity change and is

therefore often used for edge detection also referred as zero crossing edge detectors. The

Laplacian is often applied to an image that has first been smoothed with something

approximating a Gaussian smoothing filter in order to reduce its sensitivity to noise, and

hence the two variants will be described together here. The operator normally takes a

single gray level image as input and produces another gray level image as output. A

digital Laplacian mask is convoluted on the image using the convolution function from

the IMGLIB.

,

The file in the Laplace folder, calculates the Laplacian image depending on values of the

box filter H. Below shows Laplace.c

#include <dsk6416.h> printf() */

mage\kernel dimensions, example pixel data */

RAM"); d image */

eeds to be 3 for this

put

#include <stdio.h> /* #include <string.h> /* memset() */ #include <img_corr_3x3.h> #include <csl_timer.h> nclude "image.h" /* i#i

#pragma DATA_ALIGN (in_img, 8); DRAM"); #pragma DATA_SECTION (in_img, "S

ragma DATA_ALIGN (out_img, 8); #p

#pragma DATA_SECTION (out_img, "SDunsigned char out_img[N_PIXELS]; /* filtere filter dimensions and coefficients */ /*

#define NH 3 /* kernel is of size NHxNH (nprogram) */ #define BOUNDARY (NH/2) /* 1st and last BOUNDARY rows/cols in outset to 0 */ #pragma DATA_ALIGN (H, 8)

20

Page 21: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

char H[NH*NH] = { 0, 1, 0, /* 0 1 0 */ 1, -4, 1, /* 1 -4 1 */

ine SHIFT 0 /* right-shift by 0 (div by 1) */

ong *lptr = ptr;

nt--)

nsigned char *p = out_img+BOUNDARY*Y_SIZE;

set 1st BOUNDARY rows to zero */

filter the interior region of the image matrix */

* 1st BOUNDARY cols are zero */ = 0;

G_conv_3x3 requires 3rd arg to be a multiple of 8,

D

v_3x3(&in_img[(irow-BOUNDARY)*Y_SIZE],

);

last BOUNDARY cols are zero */

= 0;

last BOUNDARY rows are zero */

t main(void)

0, 1, 0, /* 0 1 0 */ }; #def #define N_COLS_FILTERED Y_SIZE-2*BOUNDARY /* * Faster than memset(), count must be a multiple of * 8 and greater than or equal to 32 */ void memclear( void * ptr, int count ) { l _nassert((int)lptr%8==0); #pragma MUST_ITERATE (32); for (count>>=3; count>0; cou *lptr++ = 0; } void filter_image() { u int ii, irow; /* memclear(out_img, BOUNDARY*Y_SIZE); /* for (irow=BOUNDARY; irow<X_SIZE-BOUNDARY; ++irow) { / for (ii=0; ii<BOUNDARY; ++ii) *p++ /* * IM * that's why we pass in Y_SIZE instead of N_COLS_FILTERE * (last few filtered pixels are ignored) */ IMG_con p,

E, Y_SIZ H, SHIFT /* p += N_COLS_FILTERED;

++ii) *p++ for (ii=0; ii<BOUNDARY; } /* memclear(out_img+(X_SIZE-BOUNDARY)*Y_SIZE, BOUNDARY*Y_SIZE); } in

21

Page 22: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

{

22

op, overhead, total = 0, t; /* timing */

6_init(); /* initialize the DSK board support library */

configure timer */ ER_DEVANY,0);

/* compute overhead of calling the timer. */

= TIMER_getCount(hTimer);

nt(hTimer); /* begin "profile area" */

intf("avg time is %.2f cycles.\n", (float)total/(float)N);

View the images arrays using the View >> Graph >> Image… utility from CCS. Below

images shows in_img and out_img.

TIMER_Handle hTimer; unsigned int start, st const int N = 10; /* how many times to profile */ int ii = 0; DSK641 /* hTimer = TIMER_open(TIM TIMER_configArgs(hTimer, 0x000002C0, 0xFFFFFFFF, 0x00000000); start = TIMER_getCount(hTimer); /* called twice to avoid L1D miss. */ start stop = TIMER_getCount(hTimer); overhead = stop - start; for (; ii<N; ++ii) { start = TIMER_getCou filter_image(); stop = TIMER_getCount(hTimer); /* end "profile area" */ t = (stop-start-overhead) * 8; total += t; printf("# cycles to filter image: %d\n", t); } pr}

Page 23: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli

6. MEDIAN FILTERING USING A 3 X 3 KERNEL

Image noise is the random variation of brightness or color information in images

produced by the sensor and circuitry of a scanner or digital camera. Image noise can also

originate in film grain and in the unavoidable shot noise of an ideal photon detector. It is

generally regarded as an undesirable by-product of image capture. Salt and pepper noise

is a form of noise typically seen on images. It represents itself as randomly occurring

white and black pixels. An effective noise reduction method for this type of noise

involves the usage of a median filter. It has been reported that modified median filters are

capable of removing speckle noise from the ultrasound images to an extent.

Considering a 3 X 3 kernel in the image matrix, median is the middle value when

all the numbers in the kernel are arranged in ascending order (i.e., 5th pixel, in case of a 3

X 3 kernel). During this process, the random white pixel (salt) or the black pixel (pepper)

are removed as they go the extremities in the ascending or the descending order.

The file median_filter3X3.c performs the above mentioned operation.

#define CHIP_6416 #include <dsk6416.h> #include <stdio.h> /* printf() */ #include <string.h> /* memset() */ #include <img_median_3x3.h> #include <csl_timer.h> #include <csl_dat.h> /* DMA */ //#include "image.h" /* image\kernel dimensions, example pixel data */ #include "tanks2.h" #pragma DATA_ALIGN (in_img, 8); #pragma DATA_SECTION (in_img, "SDRAM"); #pragma DATA_ALIGN (out_img, 8); #pragma DATA_SECTION (out_img, "SDRAM"); unsigned char out_img[N_PIXELS]; /* filtered image */ /* filter dimensions and coefficients */ #define NH 3 /* kernel is of size NHxNH (needs to be 3 for this program) */ #define BOUNDARY 1 /* * For block processing, segment image into individual chunks * that are then paged in and out of internal memory.

23

Page 24: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

*/ #define NUM_SCAN_LINES 16 /* # rows constituting a block, must divide evenly into X_SIZE */ #define NUM_BLOCKS (X_SIZE/NUM_SCAN_LINES) /* # blocks in partitioned image */ #define BLOCK_X_SIZE (NUM_SCAN_LINES+2*BOUNDARY) /* how many rows each block is */ /* * These are scratch buffers, strategically placed in on-chip RAM: * * input_buf = input pixels, passed to IMG_median_3x3 * output_buf = filtered pixels */ #pragma DATA_ALIGN (input_buf, 8); unsigned char input_buf[BLOCK_X_SIZE*Y_SIZE]; #pragma DATA_ALIGN (output_buf, 8); unsigned char output_buf[NUM_SCAN_LINES*Y_SIZE]; /* * Faster than memset(), count must be a multiple of * 8 and greater than or equal to 32 */ void memclear( void * ptr, int count ) { long * lptr = ptr; _nassert((int)lptr%8==0); #pragma MUST_ITERATE (32); for (count>>=3; count>0; count--) *lptr++ = 0; } /* Filter one block of an image, returns row index for next block */ int filter_block(int irow, int nrows, const unsigned char *restrict pin, unsigned char *restrict pout) { int jj = irow; for (; jj<irow+nrows; ++jj) { IMG_median_3x3(pin, Y_SIZE, pout); pin += Y_SIZE; /* incr scan-line in preparation for next iteration */ pout += Y_SIZE; } return jj-1; } /* March down the image block-by-block, filtering along the way */ void filter_image() { Uint32 id_EDMAin = DAT_XFRID_WAITNONE, id_EDMAout = DAT_XFRID_WAITNONE; int irow = BOUNDARY; unsigned char *pout_img = out_img, *pin_img = &in_img[(NUM_SCAN_LINES+BOUNDARY)*Y_SIZE], /*

24

Page 25: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

* We reuse the bottom-most portion of input_buf * by shifting it to the top, prior to the beginning * of the subsequent block filtering. The 1st time * through the "interior of the image" loop, the * the pointer to bottom-most portion (pinput_buf_row2move_1) * is different from the subsequent iterations * (pinput_buf_row2move_n). */ *pinput_buf_row2move_1 = input_buf + (BLOCK_X_SIZE-3*BOUNDARY)*Y_SIZE, *pinput_buf_row2move_n = input_buf + NUM_SCAN_LINES*Y_SIZE, *pinput_buf_row2move = pinput_buf_row2move_1, *pinput_buf_row2copy_into = input_buf+2*BOUNDARY*Y_SIZE; /************************************************************** * Algorithm 'prologue': filter the 1st block **************************************************************/ id_EDMAin = DAT_copy(in_img, input_buf, (BLOCK_X_SIZE-BOUNDARY)*Y_SIZE); memclear(output_buf, BOUNDARY*Y_SIZE); /* 1st few rows are 0 */ DAT_wait(id_EDMAin); irow = filter_block(irow, NUM_SCAN_LINES, input_buf, output_buf + BOUNDARY*Y_SIZE); /************************************************************** * Filter the interior of the image **************************************************************/ for (; irow<X_SIZE-NUM_SCAN_LINES; ++irow) { /* page out the most recently processed block */ id_EDMAout = DAT_copy(output_buf, pout_img, NUM_SCAN_LINES*Y_SIZE); pout_img += NUM_SCAN_LINES*Y_SIZE; /* page in the next block of pixel data */ /* * 1st shift the scan-lines we can reuse from the bottom * to the top of the scractch buffer. */ memcpy(input_buf, pinput_buf_row2move, 2*BOUNDARY*Y_SIZE); pinput_buf_row2move = pinput_buf_row2move_n; /* DMA in next set of scan-lines */ id_EDMAin = DAT_copy(pin_img, pinput_buf_row2copy_into, NUM_SCAN_LINES*Y_SIZE); pin_img += NUM_SCAN_LINES*Y_SIZE; /* gotta wait now for both xfers to complete before proceeding */ DAT_wait(id_EDMAout); DAT_wait(id_EDMAin);

25

Page 26: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

irow = filter_block(irow, NUM_SCAN_LINES, input_buf, output_buf); } /************************************************************** * Algorithm 'epilogue': filter the last block **************************************************************/ /* page out the most recently processed block of image data */ id_EDMAout = DAT_copy(output_buf, pout_img, NUM_SCAN_LINES*Y_SIZE); pout_img += (NUM_SCAN_LINES)*Y_SIZE; /* page in the last block of data */ memcpy(input_buf, pinput_buf_row2move, 2*BOUNDARY*Y_SIZE); /* shift scan-lines */ id_EDMAin = DAT_copy(pin_img, pinput_buf_row2copy_into, (NUM_SCAN_LINES-BOUNDARY)*Y_SIZE); /* gotta wait now for both xfers to complete before proceeding */ DAT_wait(id_EDMAout); DAT_wait(id_EDMAin); filter_block(irow, NUM_SCAN_LINES-BOUNDARY, input_buf, output_buf); /* last few rows are zero */ memclear(output_buf + (NUM_SCAN_LINES-BOUNDARY)*Y_SIZE, BOUNDARY*Y_SIZE); /* we're done, page out this final block of pixel data */ id_EDMAout = DAT_copy(output_buf, pout_img, NUM_SCAN_LINES*Y_SIZE); DAT_wait(id_EDMAout); } int main(void) { TIMER_Handle hTimer; unsigned int start, stop, overhead, total = 0, t; /* timing */ const int N = 10; /* how many times to profile */ int ii = 0; DSK6416_init(); /* initialize the DSK board support library */ /* configure timer */ hTimer = TIMER_open(TIMER_DEVANY,0); TIMER_configArgs(hTimer, 0x000002C0, 0xFFFFFFFF, 0x00000000); /* initialize EDMA (1st arg ignored w/ EDMA) */ DAT_open(DAT_CHAANY, DAT_PRI_HIGH, 0); /* compute overhead of calling the timer. */ start = TIMER_getCount(hTimer); /* called twice to avoid L1D miss. */ start = TIMER_getCount(hTimer); stop = TIMER_getCount(hTimer); overhead = stop - start; for (; ii<N; ++ii) { start = clock(); /* begin "profile area" */ filter_image();

26

Page 27: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

stop = clock(); /* end "profile area" */ t = (stop-start-overhead) * 8; total += t; printf("# cycles to filter image: %d\n", t); } printf("avg time is %.2f cycles.\n", (float)total/(float)N); }

Generate the image header file using generate_header_file.m file. View the image

arrays using View >> Graph >> Image… utility from CCS. Below images shows median

filtered images for different outputs.

27

Page 28: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli

7. SOBEL EDGE DETECTION USING RTDX

PROTOCOL AND VISUAL STUDIO COM OBJECT

These are the essential steps in designing a RTDX communication setup:

1. Design a module which handles the image processing on the DSP chip.

2. Program a target program which runs on the C6416 chip. This program includes

all the required data, flags, parameters reception from the host. Later, these

parameters are used as arguments for the designed modules. Create a COFF file

(.out) and load on the chip.

3. Design a host program using Visual Studio (or MATLAB) to transmit images,

options for the target console on the chip. Make a GUI with the required

parameters to e passed to the kit using the MFC configuration tool.

TARGET MODULE:

- Files to be included: (Files located on Sobel_RTDX\Target)

Sobel_edge_detect.cdb

Sobel_edge_detect.c

Img64x.lib

sobel_edge_detectcfg.cmd

- Include the imglib include folder path in the Preprocessor option of the compiler.

28

Page 29: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

- Build the project.

- Enable the RTDX Module.

- Load the COFF (.out) file and Run it.

29

Page 30: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

Code below shows sobel_edge_detect.c

#include <rtdx.h> /* target API */ #include <stdio.h> #include <IMG_sobel.h> #include <IMG_thr_le2min.h> #include "target.h" /* defines TARGET_INITIALIZE() */ #include "image.h" /* dimensions */ RTDX_CreateInputChannel(ichan); /* input image & T come down this pipe */ RTDX_CreateOutputChannel(ochan); /* processed image back through this pipe */ #pragma DATA_SECTION(img_buf1, "SDRAM"); #pragma DATA_ALIGN (img_buf1, 8); unsigned char img_buf1[N_PIXELS]; #pragma DATA_SECTION(img_buf2, "SDRAM"); #pragma DATA_ALIGN (img_buf2, 8); unsigned char img_buf2[N_PIXELS]; void memclear( void * ptr, int count ) { long *lptr = ptr; _nassert((int)lptr%8==0); #pragma MUST_ITERATE (32); for (count>>=3; count>0; count--) *lptr++ = 0; } unsigned char *sobel_edge_detect() { /* * input & output buffers for IMG_thr_le2min may NOT * alias (see IMG_thr_le2min docs), thus operation * cannot be done "in-place". */ int NH=3; /* kernel is of size NHxNH (needs to be 3 for this program) */ int BOUNDARY = (NH/2); /* 1st and last BOUNDARY rows/cols in output set to 0 */ char H[9] = { -1, -2, -1, /* -1 -2 -1 */ 0, 0, 0, /* 0 0 0 */ 1, 2, 1, /* 1 2 1 */ }; int N_COLS_FILTERED = Y_SIZE-2*BOUNDARY, SHIFT = 0; unsigned char *p = img_buf2+BOUNDARY*Y_SIZE; int ii, irow; /* set 1st BOUNDARY rows to zero */

30

Page 31: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

memclear(img_buf2, BOUNDARY*Y_SIZE); /* filter the interior region of the image matrix */ for (irow=BOUNDARY; irow<X_SIZE-BOUNDARY; ++irow) { /* 1st BOUNDARY cols are zero */ for (ii=0; ii<BOUNDARY; ++ii) *p++ = 0; /* * IMG_conv_3x3 requires 3rd arg to be a multiple of 8, * that's why we pass in Y_SIZE instead of N_COLS_FILTERED * (last few filtered pixels are ignored) */ IMG_conv_3x3(&img_buf1[(irow-BOUNDARY)*Y_SIZE], p, Y_SIZE, H, SHIFT); /* last BOUNDARY cols are zero */ p += N_COLS_FILTERED; for (ii=0; ii<BOUNDARY; ++ii) *p++ = 0; } /* last BOUNDARY rows are zero */ memclear(img_buf2+(X_SIZE-BOUNDARY)*Y_SIZE, BOUNDARY*Y_SIZE); return img_buf2; } void main() { int status, run_edge_detector, ii; unsigned char *pimg = NULL; TARGET_INITIALIZE(); RTDX_enableOutput(&ochan); /* enable output channel */ RTDX_enableInput(&ichan); /* enable input channel */ printf("Input & Output channels enabled ...\n"); while (1) { /* wait for the host to send us a threshold */ if (sizeof(run_edge_detector) != (status = RTDX_read(&ichan, &run_edge_detector, sizeof(run_edge_detector)))) printf("ERROR: RTDX_read of edge detection flag failed!\n"); else printf("Edge detection = %s\n", (run_edge_detector)?"yes":"no"); /* now we're expecting X_SIZE x Y_SIZE worth of image data */ if (N_PIXELS != (status = RTDX_read(&ichan, img_buf1, N_PIXELS))) { printf("ERROR: RTDX_read of image failed (%d)!\n", status); exit(-1); } printf("Received %dx%d image\n", X_SIZE, Y_SIZE); /* process the image */ pimg = sobel_edge_detect();

31

Page 32: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

/* send it back to host */ printf("Sending processed image data back to host ...\n"); for (ii=0; ii<X_SIZE; ++ii) { /* write one row's worth of data */ if (!RTDX_write(&ochan, pimg+ii*Y_SIZE, Y_SIZE)) { printf("ERROR: RTDX_write of row %d failed!\n", ii); exit(-1); } } /* end (for each row) */ printf("Image segmentation completed.\n"); } }

HOST MODULE:

Intel Integrated Performance Primitives (IPP) and Graphics Device Interface (GDI+)

libraries are required to run the following program. The installation files (.exe) are

located in the Sobel_RTDX\Resources folder.

A sample project for the Host application is already constructed for the RTDX transfer.

Please refer to the folder Sobel_RTDX\Host for the Visual Studio project file,

SegmentationHost.vcproj. Add the IPP library include directory to compiler path, IPP

linker library folder path for linker path and additional static library files to the project.

32

Page 33: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

Add the Include path for the IPP library ‘include’ files are located.

Add the Include path for the Additional libraries required from the IPP Stublib folder.

33

Page 34: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

Add the required static libraries: gdiplus.lib, ipps.lib, ippi.lib

The line in stdafx.h

#import "C:\ti\cc\bin\rtdxint.dll"

imports the RTDX COM object required for the data transfer. The class Image8bpp

handles the image object read by the GUI and has different functions (Ref. Image8bpp

class members).

This code snippet below can communicate with target module:

From Callbcak function of the Segment button:

void CSegmentationDlg::OnSegmentButton() { if (m_apOrigBitmap.get()) { // 1st tell the target to edge detect or just segment theApp.rtdx()->sendInteger( this->m_edgeDetectCheck.GetCheck()?1:0 ); // next send the image to be processed theApp.rtdx()->sendImage(m_apOrigBitmap.get()); // lastly, read the segmented image m_apProcessedBitmap = auto_ptr<Image8bpp>( theApp.rtdx()->readImage() ); m_apProcessedBitmap->binarize();

34

Page 35: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

this->OnPaint(); } }

Methods of the RTDX class has the capable to transfer the data to and from the DSP chip.

Run the project and check the folder Sobel_RTDX\Host\Debug\ for the executable file

(SegmentationHost.exe). This application can transer images. Figure below shows the

GUI of the application.

Load the image and hit the Segment button, while the COFF file (.out) file is running on

the CCS with RTDX enabled.

35

Page 36: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

C6416 Report – Uday Kiran Thummalapalli

8. REGION GROWING USING RTDX PROTOCOL

This project is capable of making an RTDX transfer with the target chip, process the

image and resend to the host. Region growing is a method to view objects in an image whose

intensities are below a threshold. The remaining pixels are blacked out or whiten out depending

on the criterion. The main goal of segmentation is to partition an image into regions. We have to

achieve the goal by looking for the boundaries between regions based on discontinuities in gray

levels or color properties. The GUI here has a splitter control which can read a threshold value.

Below here are the codes for the target and the host. The user interface and the GUI elements can

be added/ removed/ modified from the ‘RegiongrowHost.rc’.

TARGET:

- Files to be include (Files located on Regiongrow_RTDX_Net/Target)

Regiongrow.cdb Regiongrow.c Img64x.lib Regiongrow.cmd 

Code below shows Regiongrow.c

#include <rtdx.h> /* target API */ #include <stdio.h> #include <IMG_sobel.h> #include <IMG_thr_le2min.h> #include "target.h" /* defines TARGET_INITIALIZE() */ #include "image.h" /* dimensions */ RTDX_CreateInputChannel(ichan); /* input image & T come down this pipe */ RTDX_CreateOutputChannel(ochan); /* processed image back through this pipe */ #pragma DATA_SECTION(img_buf1, "SDRAM"); #pragma DATA_ALIGN (img_buf1, 8); unsigned char img_buf1[N_PIXELS]; #pragma DATA_SECTION(img_buf2, "SDRAM"); #pragma DATA_ALIGN (img_buf2, 8);

36  

Page 37: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

unsigned char img_buf2[N_PIXELS]; void memclear( void * ptr, int count ) { long *lptr = ptr; _nassert((int)lptr%8==0); #pragma MUST_ITERATE (32); for (count>>=3; count>0; count--) *lptr++ = 0; } region_fill(unsigned char fill_percent) { /* * input & output buffers for IMG_thr_le2min may NOT * alias (see IMG_thr_le2min docs), thus operation * cannot be done "in-place". */ IMG_thr_le2min(img_buf1, img_buf2, Y_SIZE, X_SIZE, fill_percent); } void main() { int status, fill_percent, run_edge_detector, ii; //unsigned char *pimg = img_buf2; TARGET_INITIALIZE(); RTDX_enableOutput(&ochan); /* enable output channel */ RTDX_enableInput(&ichan); /* enable input channel */ printf("Input & Output channels enabled ...\n"); while (1) { /* wait for the host to send us a threshold */ if (sizeof(fill_percent) != (status = RTDX_read(&ichan, &fill_percent, sizeof(fill_percent)))) printf("ERROR: RTDX_read of Fill Percent failed!\n"); else printf("Filling Scale = %d\n", fill_percent); /* wait for the host to send us a threshold */ /*if (sizeof(run_edge_detector) != (status = RTDX_read(&ichan, &run_edge_detector, sizeof(run_edge_detector)))) printf("ERROR: RTDX_read of edge detection flag failed!\n"); else printf("Reversing Fill = %s\n", (run_edge_detector)?"yes":"no");*/ /* now we're expecting X_SIZE x Y_SIZE worth of image data */

37  

Page 38: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

if (N_PIXELS != (status = RTDX_read(&ichan, img_buf1, N_PIXELS))) { printf("ERROR: RTDX_read of image failed (%d)!\n", status); exit(-1); } printf("Received %dx%d image\n", X_SIZE, Y_SIZE); /* process the image */ region_fill((unsigned char)fill_percent); /* send it back to host */ printf("Sending processed image data back to host ...\n"); for (ii=0; ii<X_SIZE; ++ii) { /* write one row's worth of data */ if (!RTDX_write(&ochan, img_buf2+ii*Y_SIZE, Y_SIZE)) { printf("ERROR: RTDX_write of row %d failed!\n", ii); exit(-1); } } /* end (for each row) */ printf("Region Filling completed.\n"); } }

HOST MODULE:

Compose the ‘vcproject’ for RegiongrowHost and compile for the code for no errors.

Code snippet from ‘RegiongrowDlg.c’, written here below, shows the code for which sends the

information through RTDX and receives the image.

void CSegmentationDlg::OnSegmentButton() { if (m_apOrigBitmap.get()) { // Set the min and max for the scale to region fill m_fillpercent.SetRange(0,256); // 1st tell the target the percentage to fill theApp.rtdx()->sendInteger( this->m_fillpercent.GetPos()); // 2nd tell the target the way it has to fill, from black/ white?? //theApp.rtdx()->sendInteger( this->m_edgeDetectCheck.GetCheck()?1:0 ); // next send the image to be processed theApp.rtdx()->sendImage(m_apOrigBitmap.get()); // lastly, read the segmented image

38  

Page 39: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

m_apProcessedBitmap = auto_ptr<Image8bpp>( theApp.rtdx()->readImage() ); m_apProcessedBitmap->binarize(); this->OnPaint(); } }

The call back function of the button ‘Fill’ reads the value of the splitter element reads the image and sends to the DSP. Upon, reception from the RTDX, it reads back the image and repaints the figure window. Images below show the result for different values of the threshold.

39  

Page 40: 1. BUILDING PROJECT ON C6416 DSKut27/C6416DSK.pdfC6416 Report – Uday Kiran Thummalapalli 1. BUILDING PROJECT ON C6416 DSK . Connect the DSK kit to the PC and open the Code Composer

40