LDS said:

HarryFilm said:

Here is some ACTUAL CODEC CODE I am using in this project.

That's just a long comment for a file header, and a prototype of a function using your logorrheic style. No actual code.

Then there's your usual technobabble - btw, it's "Cortex", not "Coretex"... and I don't remember an A4 one (Apple A4 is a different beast...)

---

A4 is a specific sub-model of the Cortex (misspelling fixed!) cores used by embedded device makers which is even MORE RISC-y (i.e. reduced instructions) for power-saving reasons. The compiler is supposed to do all the fancy logic to allow higher-level functions that more CISC-y (i.e. more complex) cpu instruction sets do at the hardware level. A4 is NOT an Apple moniker but rather something originally from either Texas Instruments or Qualcomm (not sure!) who licence the ARM architecture from ARM itself but I am seeing that A4 moniker in the actual ARM company's (i.e. the Advanced RISC Machines company now owned by Softbank) documentation I've got.

Canon uses this A4 core for simple power-saving reasons at 25 MHz up to 1.5 GHz

in its DIGIC series of camera image processing and control CPU's.

I ain't no mere beginner in this...Here is how to do SIMPLE AND EFFECTIVE EDGE DETECTION from MY OWN CODE i designed all by myself from scratch which WILL run on ARM, Intel/AMD, MIPS, IBM Power, SuperSPARC and various DSP processors

INCLUDING the Canon DIGIC series:

COPY this code to a Landscape-mode using 10 point narrow font in a word processing document to see the entire RATHER NICELY DOCUMENTED code segment.

THIS BELOW CODE SEGMENT IS FULLY GNU GPL 3.0 OPEN SOURCE LICENCE FOR YOU programmers: Have at it for modification but REMEMBER to keep your work and modifications to this code to the GNU GPL 3.0 licence terms!

Procedure Apply_Convolution_Filter_to_Pixel( Var Any_Bitmap, Temporary_Storage_Bitmap: Virtual_Bitmap; Starting_X_Coordinate, Starting_Y_Coordinate, Index_to_Start_of_Filter: Large_Integer; Var Convolution_Kernel: Array of Large_Integer; Procedure_to_Run_After_Each_Convolution_Kernel: After_Each_Convolution_Kernel_Procedure_Type );

Var

x, y, i,

Current_X_Coordinate,

Current_Y_Coordinate,

Current_Pixel_Brightness,

Original_Pixel_Brightness,

Final_Convolution_Result,

Final_Convolution_Grid_Result,

Convolution_Kernel_Width,

Convolution_Kernel_Height,

X_Centre_of_Kernel,

Y_Centre_Of_Kernel,

Edge_Sensitivity_Threshold,

Type_of_Output_Image_Desired : Large_Integer;

New_Pixel,

Sampled_Pixel,

Original_Pixel : RGB_Pixel_Type;

New_Pixel_Brightness : Floating_Point;

Convolution_Operation_is_Additive : Boolean_Type;

Begin

Try

// Find out if this is the first convolution kernel applied in a series of filters

if Index_to_Start_of_Filter = ZERO then

Convolution_Operation_is_Additive := FALSE // Assume that this is the first in a series of kernels being applied

else

Convolution_Operation_is_Additive := TRUE; // Assume that this is the second or later in a series of kernels being applied

Original_Pixel := Get_Pixel( Any_Bitmap, Starting_X_Coordinate, Starting_Y_Coordinate );

Original_Pixel_Brightness := Get_Greyscale_Value_of_RGB_Pixel( Original_Pixel );

Final_Convolution_Result := ZERO;

Final_Convolution_Grid_Result := ZERO;

Convolution_Kernel_Height := Convolution_Kernel[ Index_to_Start_of_Filter ];

Convolution_Kernel_Width := Convolution_Kernel[ Index_to_Start_of_Filter + 1 ];

// The location of where the X, Y coordinate of where the convolution kernel itself should be centred over a pixel

X_Centre_of_Kernel := Convolution_Kernel[ Index_to_Start_of_Filter + 2 ];

Y_Centre_Of_Kernel := Convolution_Kernel[ Index_to_Start_of_Filter + 3 ];

// Any pixels luminances under this threshold will be ignored

Edge_Sensitivity_Threshold := Round( ( Convolution_Kernel[ Index_to_Start_of_Filter + 4 ] * 0.01 ) * MAXIMUM_COLOUR_CHANNEL_VALUE );

// Details whether the image should output a black & white image, greyscale or original image with filter applied

Type_of_Output_Image_Desired := Convolution_Kernel[ Index_to_Start_of_Filter + 5 ];

{

This is the main convolution loop which multiples all the elements of the convolution kernel

and all the elements of the sampled image region. The coefficients in the Kernel will determine

whether the difference between the sampled pixel and surrounding pixels is amplified or mitigated.

}

i := Index_to_Start_of_Filter + 6;

for y := 1 to Convolution_Kernel_Height do

for x := 1 to Convolution_Kernel_Width do

Begin

Current_X_Coordinate := ( Starting_X_Coordinate + x ) - X_Centre_of_Kernel;

Current_Y_Coordinate := ( Starting_Y_Coordinate + y ) - Y_Centre_of_Kernel;

// The convolution kernel can be equal in width and height or asymmetrical thus make sure we overlay the kernel overtop the correct pixel

Sampled_Pixel := Get_Pixel( Any_Bitmap, Current_X_Coordinate, Current_Y_Coordinate );

Current_Pixel_Brightness := Get_Greyscale_Value_of_RGB_Pixel( Sampled_Pixel );

// multiple each Kernel element with each pixel of the sampled image region

Final_Convolution_Result := Final_Convolution_Result + ( Current_Pixel_Brightness * Convolution_Kernel[ i ] );

// add to the sum total of the all kernel multiplication operations

Final_Convolution_Grid_Result := Final_Convolution_Grid_Result + Convolution_Kernel[ i ];

Inc( i );

End;

// Get the final convolution filter result

if Final_Convolution_Grid_Result = ZERO then

Final_Convolution_Result := ( Final_Convolution_Result + 1 ) div ( Final_Convolution_Grid_Result + 1 )

else

Final_Convolution_Result := Final_Convolution_Result div Final_Convolution_Grid_Result;

// Set each colour channel to legal RGB values

Final_Convolution_Result := RGB_Clamp( Final_Convolution_Result, RGB_Colour_Space );

{

Determine how the kernel result should be interpreted and how Temporary_Storage_Bitmap

should have its pixels created or copied from the original bitmap.

If this is the first or only application of a convolution kernel, then any

convolution kernel result that is above the Edge_Sensitivity_Threshold is copied to the current X, Y coordinate

of Temporary_Storage_Bitmap. Those convolution kernel results that fall below Edge_Sensitivity_Threshold

cause the pixel located at current X,Y coordinate of Temporary_Storage_Bitmap

to be set to a default value of dark black or the pixel value from the original bitmap

may be copied to Temporary_Storage_Bitmap.

If this is the second or later in a series of convolutions being applied,

then all convolution operations are additive to Temporary_Storage_Bitmap.

This means that only pixels that are above the Edge_Sensitivity_Threshold

are added to Temporary_Storage_Bitmap. Pixels that fall below Edge_Sensitivity_Threshold

are ignored and no pixel is modified on Temporary_Storage_Bitmap.

}

Case Type_of_Output_Image_Desired of

OUTPUT_BLACK_AND_WHITE_IMAGE : Begin

{

Used for creating a reference bitmap image (i.e Temporary_Storage_Bitmap) which is used

in other subsequent image manipulation of the original image.

i.e. if pixel at reference image X,Y location is White then the original bitmap's pixel

at that location needs to be changed or looked for further processing otherwise

if Black then pixel at X,Y on the original can be ignored and no futher processing need be done.

}

If Final_Convolution_Result >= Edge_Sensitivity_Threshold then

New_Pixel := RGB_Colour_100_Percent_White

else // if necessary, set the pixel that is below the edge sensivity threshold to dark black

if Convolution_Operation_is_Additive = FALSE then

New_Pixel := RGB_Colour_ZERO_Percent_Black

else

Exit;

End;

OUTPUT_ORIGINAL_IMAGE_WITH_FILTER_APPLIED : Begin

{

Copies the original pixel data to Temporary_Storage_Bitmap and applies

the convolution filter to the copied pixel data.

When all processing is done to Temporary_Storage_Bitmap,

it can be copied back to the original bitmap.

i.e. original bitmap is overwritten by Temporary_Storage_Bitmap.

}

If Final_Convolution_Result >= Edge_Sensitivity_Threshold then

Begin

New_Pixel := Original_Pixel;

Set_Pixel_to_Absolute_Luminance_Level( New_Pixel, Final_Convolution_Result );

End

else // if necessary, set the pixel that is below the edge sensivity threshold to dark black

if Convolution_Operation_is_Additive = FALSE then

New_Pixel := Original_Pixel

else

Exit;

End;

OUTPUT_AS_GREY_SCALE_IMAGE : Begin

{

Temporary_Storage_Bitmap is changed such that each Final_Convolution_Result is output

as a greyscale level pixel.

Future image processing operations can interpretthe differing Greyscale levels

of Temporary_Storage_Bitmap as a degree of interest or degree of change that should

be applied to each pixel of the original bitmap.

i.e. Dark Black = no change to original pixels is required

50% grey = partially apply further image processing operations

Bright White = fully apply subsequent image processing operations

}

If Final_Convolution_Result >= Edge_Sensitivity_Threshold then

Set_Each_Channel_of_RGB_Pixel_to_Same_Value( New_Pixel, Final_Convolution_Result )

else // if necessary, set the pixel that is below the edge sensivity threshold to dark black

if Convolution_Operation_is_Additive = FALSE then

New_Pixel := RGB_Colour_ZERO_Percent_Black

else

Exit;

End;

else

Begin

// if unable to determine how to interpret a kernel result give a default answer

New_Pixel := RGB_Colour_ZERO_Percent_Black;

Set_Bitmap_Error( 'Unable to the perform the designated convolution because the Type_of_Output_Image_Desired'+ CRLF +

'parameter may be bad. It is currently set at: ' + NumberToString( Type_of_Output_Image_Desired ) + DOUBLE_SPACE +

'Output pixel has been changed to RGB_Colour_ZERO_Percent_Black.', 'Apply_Convolution_Filter_to_Pixel()' );

End;

End;

// Make sure the procedure actually exists before running the code that will examine

// and if necessary, modify each output pixel of a convolution kernel before it is copied to the Temporary_Storage_Bitmap

if @Procedure_to_Run_After_Each_Convolution_Kernel <> RUN_NO_OTHER_PROCEDURE then

Procedure_to_Run_After_Each_Convolution_Kernel( Any_Bitmap, Temporary_Storage_Bitmap, Starting_X_Coordinate, Starting_Y_Coordinate, Original_Pixel, New_Pixel );

// Save the convolution result to the reference image which can then be interpreted in subsequent image processing operations

Set_Pixel( Temporary_Storage_Bitmap, Starting_X_Coordinate, Starting_Y_Coordinate, New_Pixel );

Except // on any errors return a default result

New_Pixel := RGB_Colour_ZERO_Percent_Black;

Set_Bitmap_Error( 'Unable to the perform the designated convolution because of a number of reasons including'+ CRLF +

'parameters may be out-of-range, Convolution_Kernel is improperly declared or has values that are to big or too small,' + DOUBLE_SPACE +

'Output pixel has been changed to RGB_Colour_ZERO_Percent_Black.', 'Apply_Convolution_Filter_to_Pixel()' );

Set_Pixel( Temporary_Storage_Bitmap, Starting_X_Coordinate, Starting_Y_Coordinate, New_Pixel );

End;

End;

{

Convolution is both a mathematical concept and an important tool in data processing,

in particular in digital signal and image processing.

Convolution allows one to multiply the individual elements of two numerical arrays together

and return an averaged numerical representation of the contents of both numerical arrays.

These convolution functions can interpret or discern the edges of image elements or objects,

find specific levels of pixel brightness, obtain the degree of colour or luminance transition

between two adjacent pixels and other useful functions.

Is essence, convolution is the process of finding the difference between two numbers and then

either mitigating that difference or amplifying the difference.

Applying single or multiple convolution kernels to a pixel sample can achieve effects

such as image smoothing, sharpening, edge detection and embossing.

for example:

x1, x2, x3 y1, y2, y3

x4, x5, x6 X y4, y5, y6 = averaged result after multiplying all the elements together

x7, x8, x9 y7, y8, y9

A Convolution Filter Kernel is an odd-sized, even-sized, or asymmetrically-sized matrix of integers

usually 3x3 or 5x5, 7x7 or 9x9, 2x2 or 4x4 or 6x6 elements in size containing a patterned series of

positive or negative numbers. These numbers can be multipled with each

Red, Green and Blue colour channel of a pixel or just the single computed Greyscale value of each RGB pixel.

The convolution result can saved to the secondary reference bitmap called Temporary_Storage_Bitmap

as a Black and White bitmap, Greyscale bitmap, or original pixels with convolution applied.

This will give you the option of using the convolution kernel results as a reference that

details which pixels on the original bitmap to take a closer look at or process further.

This is chosen by passes to the parameter Type_of_Output_Image_Desired one of the following parameters:

OUTPUT_BLACK_AND_WHITE_IMAGE

OUTPUT_ORIGINAL_IMAGE_WITH_FILTER_APPLIED

OUTPUT_AS_GREY_SCALE_IMAGE

DO_NOT_CHANGE_IMAGE

The resulting bitmap can be used as is, with the convolution effect applied or the output bitmap

can be referenced by other subsequent image processing operations.

i.e. any pixels on the reference bitmap which is Dark Black indicates that the pixel on the Original bitmap

located at the sampled X,Y coordinate should be ignored, otherwise a Bright White pixel indicates the original pixel

should have subsequent image processing operations fully applied. In-between greyscale values indicate

the degree of which any subsequent special effect or image processing operation should be applied.

Note that the larger the convolution kernel is in terms of number-of-elemnts, the longer the operation will take.

1024 by 768 pixel, 24 bit image = 2,359,296 Bytes using a 3x3 convolution filter = 21,233,664 operations

the sames image using a 5x5 filter will require 58,982,400 operations, A 7x7 filter will require 115,605,504 operations

and a 9x9 filter will require 191,102,976 operations. We get a rather large increase in the amount of time that is required

for each convolution to be applied if a convolution filter is larger than 3x3.

The larger convolution filters are used where accuracy of result is more important than execution speed.

PLEASE NOTE that the convolution kernels used in this routine can be be odd sized, even sized or asymmetric

including kernel sizes such as 3x3 or 5x5, 7x7, 9x9 ..or.. 2x2, 4x4, 8x8, ...or... 4x1, 3x4 or 3x5 or 7x2.

This allows very advanced image processing operations on square-shaped groups of pixels, single horizontal lines of pixels,

single vertical lines of pixels and rectangular groups of pixels.

The parameter Any_Bitmap is the original bitmap upon which the convolution kernel will be applied

Temporary_Storage_Bitmap is a holding area (or reference bitmap) which will temporarily store the

convolution kernel results.

Starting_X_Coordinate and Starting_Y_Coordinate detail upon which pixel of the original bitmap

the convolution kernel will be applied. Screen coordinate 0,0 is the upper left corner of original bitmap.

Convolution_Kernel is an array of Large_Integers which contains the information about a single convolution kernel

or it can also contain multiple convolution kernels which can then be applied one after another.

The convolutions kernels do NOT have to be the same size which thus allows the possibility of

applying a 3x3 kernel, then a 7x2 kernel, a 4x4 kernel and then a 5x5 kernel in succession.

The Large_Integer Array which is passed to the Convolution_Kernel parameter must follow the following convention:

Index ZERO = width of the convolution kernel itself from 1..x

Index 1 = height of the convolution kernel itself from 1..y

Index 2 = the X coordinate of where the kernel will be centred over the sampled pixel from the original bitmap - this is 1..x based NOT ZERO based

Index 3 = the Y coordinate of where the kernel will be centred over the sampled pixel from the original bitmap - this is 1..y based NOT ZERO based

Index 4 = An edge sensitivity flag which details that any convolution results that are under this optimal threshold are ignored

and not saved to Temporary_Storage_Bitmap. The integer is changed to a percentage of the maximum allowable

value in the individual colour channel of an RGB_Pixel_Type.

thus integer value example could be 50 = 50% of 255 = 127, or 25 = 25% of 255 = 63 or 75 = 75% of 255 = 191

This makes sure that only relevant pixels are considered for processsing and not stray pixels or unimportant ones.

This can be changed on the fly if neccessary by assigning another Large_Integer value to this index location.

Index 5 = One of the 4 constants OUTPUT_BLACK_AND_WHITE_IMAGE, OUTPUT_ORIGINAL_IMAGE_WITH_FILTER_APPLIED,

OUTPUT_AS_GREY_SCALE_IMAGE, DO_NOT_CHANGE_IMAGE which tells the routine how to interpret the convolution kernel results.

This allows for further image processing where the pixels stored in Temporary_Storage_Bitmap can be referenced

and the level of greyscale can be interpreted to mean how much attention should be focused on the pixel located at the

same X,Y location of the original bitmap.

Index 6 = Start of the Convolution Kernel which MUST be of the width and height detailed in Index ZERO and Index 1

Any further Large_integers after the above is interpreted as another Convolution kernel following the same structure as above

Index_to_Start_of_Filter is the starting ZERO-based index to the start of each convolution kernel i.e. ZERO..n

Procedure_to_Run_After_Each_Convolution_Kernel is a pointer to a user-defined procedure which allows the user

to interpret and further process the convolution kernel result for each pixel in the original bitmap.

Usually used to clamp the kernel result values to within specific integer ranges or to change the output pixel values.

If you have not defined any procedure to run after each application of a convolution filter specify the

parameter Procedure_to_Run_After_Each_Convolution_Kernel to be the pre-defined constant RUN_NO_OTHER_PROCEDURE

The procedure must of type After_Each_Convolution_Kernel_Procedure_Type

which following the convention:

Procedure Name_of_Procedure( Var Any_Bitmap, Temporary_Storage_Bitmap: Virtual_Bitmap; Current_X_Coordinate, Current_Y_Coordinate: Large_Integer; Var Original_Pixel, Changed_Pixel: RGB_Pixel_Type );

Example:

Uses Routines;

Const

// Width, Height, X_Centre, Y_Centre, Image Output Type

Sobel_Edge_Detection_Convolution_Filter : Array[ 1..30 ] of Large_Integer = ( // Detects Vertical edges and sharp transients between luminance values

3, 3, 1, 1, 35, OUTPUT_BLACK_AND_WHITE_IMAGE,

-1, 0, 1,

-2, 0, 2,

-1, 0, 1,

// Detects Horizontal edges and sharp transients between luminance values

3, 3, 1, 1, 35, OUTPUT_BLACK_AND_WHITE_IMAGE,

1, 2, 1,

0, 0, 0,

-1, -2, -1 );

Var

x, y,

Index_to_Start_of_Kernel,

End_of_Convolution_Kernels : Large_Integer;

Original_Bitmap,

Temporary_Bitmap : Virtual_Bitmap;

Begin

Initialize_Bitmap( Original_Bitmap, 'Original Image.bmp' ); // Allocate memory for bitmap variable and then load image from disk file

Initialize_Bitmap( Temporary_Bitmap ); // Allocate only the simple basic memory for this bitmap variable

// Get the last index to the array of integers denoted by Convolutions_to_Apply

End_of_Convolution_Kernels := High( Sobel_Edge_Detection_Convolution_Filter );

// Apply a series of pre-defined convolution filters to each pixel in the original image

i := ZERO;

Repeat

// Run each convolution kernel over the entire bitmap and save the kernel results to Temporary_Bitmap

For y := ZERO to Original_Bitmap.Height - 1 do

For x := ZERO to Original_Bitmap.Width - 1 do

Apply_Convolution_Filter_to_Pixel( Original_Bitmap, Temporary_Bitmap, x, y, Index_to_Start_of_Kernel, Sobel_Edge_Detection_Convolution_Filter, RUN_NO_OTHER_PROCEDURE );

// Increment the counter I so that it points to the next set of integers that represent a convolution filter record

Inc( Index_to_Start_of_Kernel, ( Sobel_Edge_Detection_Convolution_Filter[ Index_to_Start_of_Kernel ] * Sobel_Edge_Detection_Convolution_Filter[ Index_to_Start_of_Kernel + 1 ] ) + 6 );

Until i >= End_of_Convolution_Kernels;

// Overwrite the original bitmap with the reference bitmap image

Original_Bitmap.Assign( Temporary_Bitmap );

Original_Bitmap.SaveToFile( 'Changed Image.bmp' );

Destroy_All_These_Bitmaps( [ Original_Bitmap, Temporary_Bitmap ] );

End.

}