EPFL
 Biomedical Imaging Group
EPFL   Review of C Language for Image Processing
English only    BIG > Intranet > C language > Review of C Language for Image Processing
 CONTENTS
Home Page
Events
Members
Publications
Tutorials and Reviews
Research
Demos
Download Algorithms
Teaching
Intranet
Review of C Language for Image Processing

Contents

  1. Types
  2. Pointers/Arrays
  3. Functions
  4. Preprocessor
  5. Compilation
  6. Dynamic library

Prerequisite: Basic knowledge of C

Reference: The C Language (ANSI C), Brian W. Kernighan & Denis M. Ritchie


1. Types

Variables = {Type, Identificator, Value}

Scalar types

  Typical implementation

It is not a rule

Suffixe Example
INTEGER      
char 8 bits [-127..128]   v='a';
unsigned char 8 bits [0..255]    
short (short int) 16 bits [-32768..32767]    
unsigned short 16 bits [0..65535]    
int 16 bits do not use default v=3;
unsigned int 16 bits do not use U v=3U;
long (long int) 32 bits L v=3L;
unsigned long 32 bits UL v=3UL;
REAL      
float 32 = {1+24+7} bits F V3.0F;
double 64 = {1+53+10} bits default v=3.0;
long double 80 = {1+64+15} bits    

See the file <limits.h> and <float.h> to know the limitations.

Conversion

  • Explicit: Casting example(double)var;
  • Implicit: Rules of C. Be careful ! Prefer always explicit conversion.

Structure

Data composed as a set of variables

struct TImage {
	float *Data;
	long Nx, Ny;	
};

How to access to a field? . or ->

	struct TImage s;	/* structure */
	struct TImage *ps;	/* pointer to structure */

		s.Nx = 10L;
		ps->nx = 10L;

Enum

Type given a list of constants

		enum TOpenDay {Monday, Tuesday, Wednesday, Thursday};
		enum TOpenDay Today;
		Today = Tuesday;
	


2. Pointers/Arrays

Declaration of a pointer
		short *ps;
		short *ps = (short *)NULL;

Unary operators

& provide the address of an object: p = &a;

* provide the content of an address: a = *p;

Access to pointed data

Using index notation

				long Summation(long *p, long n)
				{
				long i, sum=0L;
					for(i=0L; i<n; i++) {
						sum += p[i];
					}
					return(sum);
				}
Scanning from 0 to n-1

The addresses are numerical values: arithmetic operations are possible

				long Summation(long *p, long n)
				{
				long i, sum=0L;
	
					for(i=0L; i<n; i++) {
						sum += *p++;
					}
					return(sum);
				}
Where is p now ?

Question: What is the difference between *(p++); and (*p)++; ?

Dynamic allocation

malloc: reserved a block of memory

free: release the reserved block
				long *p;			

				p = (long *)malloc((size_t)(1000L*(long)sizeof(long)));
				if ( p == (long *)NULL)	{
					return (ERROR);
				}
				...
				free(p);
Don't forget

To allocate enough memory for your data.

To check if there's available memory.

To release the memory after usage.

Multidimensionnal arrays

The array data are organized follow as a raster:

How to access to a points (i,j,k) in volume of dimension [nx,ny,nz]

Value = Volume[i + nx*(j+ny*k)];


3. Functions

Modularity

Create a function when the inputs and outputs are well defined.

Passing parameters

  • By value: The function works with a copy of the parameters: the parameters aren't modified by the function.

double BSpline( double x, long Order)

  • By address: Give the pointer to the function: by this way the function can modify the parameters.

void Sobel( double *input, double *output)

Return

Return nothing:

			void Activate()
			{ 
				...
				return; 
				...
			}

Return result:

			long GetLength()
			{ 	
				...
				return(d);
				...
			}

Scope: extern vs static

Good practice to explicity qualify what it is the scope of a function.


4. Preprocessor

Directive #include

Causes a copy of a specific files in place of the directive

2 forms:

  • #include <stdio.h> < > for the C standard libraries
  • #include "myfile.h" " " for the user headers

Directive #define, #undef

Usage 1: Create symbolic constants or macro (prefer functions instead macros)

		#undef PI
		#define PI ((double)3.14159265358979323846264338327950288419716939937510)
		#ifdef, #ifndef

Usage 2: Allow conditional compilation

		#undef DEBUG
		#define DEBUG
		...
		#ifdef DEBUG	
		printf("%d", a);
		#endif


5. Compilation

Compilation phases

compilation

Settings of your compiler

  • Include files: Announce where are the include files
  • Optimization: Good compromize among Speed / Small Code / Easy to debug
  • Warning: Choose what are the level of warnings


6. Dynamic library

The compilation can produce an Application or Dynamic library

  Application Dynamic library
  Stand-alone Run inside an application
Loading At the launch When the calling application use the library
Entry point 1 entry: main() No main() function

The list of the callable functions are specified

Standard I/O Usage of the console I/O: printf(),… Don’t use the standard I/O. You don't know which application use your dynamic library
Windows Executable/Application Dynamic link library (.dll)
Macintosh Application Shared Library (.shlb)
Unix Executable Dynamic library (.so)

Execise 1: Design

Design a program for interactive exploration of 3D volumes of medical data. Identify user needs, propose a user interface. The design should include a short description of user interaction, short description of the internals, description of all functions and data structures.


Exercise 2: Using pointers

We would like to create a button from an image.

Source image

Result image

The size of the border is a parameter.

There are two basic operations:

  • Rescale the gray level of the input image from 0 to 255.
  • Add border around the image, dark gray in the south and east sides and light gray in the north and west sides. On the Macintosh, you find an empty framework file createbutton.c in the bilib:student that you can complete.

The interface to IDL is already done. So launch IDL, run init and the choose the dynamic library student.shlb. Then you can run for example:

IDL> show, createbuttonnowidget(lena(), border=10)


Exercise 3: Image processing example

We would like to write a function that does a smoothing filter using the moving average algoritm in a image (2D array) with mirror boundary conditions. The length of the moving window is a parameter. On the Macintosh, you find an empty framework file movingaverage.c in the bilib:student where that you can complete. The interface to IDL is already done. So launch IDL, run init and the choose the dynamic library student.shlb. Then you can run for example:

IDL> show, movingaveragenowidget(lena(), length=10)

Optional: extend this filter for a volume (3D array).