Skip to content

Commit d31e80a

Browse files
Added new documentation and improved Doxygen comments
1 parent 215e18e commit d31e80a

File tree

9 files changed

+235
-22
lines changed

9 files changed

+235
-22
lines changed

Inc/array.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ typedef struct {
2121
void **data;
2222
array_dtor_t dtor;
2323
} array_t;
24+
25+
/* STM32IPL
26+
* These array functions can be used at application side.
27+
*/
2428
void array_alloc(array_t **a, array_dtor_t dtor);
2529
void array_alloc_init(array_t **a, array_dtor_t dtor, int size);
2630
void array_clear(array_t *array);

Inc/collections.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ bool bitmap_bit_get(bitmap_t *ptr, size_t index);
3737
//////////
3838
// lifo //
3939
//////////
40+
/* STM32IPL
41+
* These lifo functions are for library internals only.
42+
* Do not use at application side!
43+
*/
4044

4145
typedef struct lifo
4246
{
@@ -61,6 +65,11 @@ void lifo_peek(lifo_t *ptr, void *data);
6165
// fifo //
6266
//////////
6367

68+
/* STM32IPL
69+
* These fifo functions are for library internals only.
70+
* Do not use at application side!
71+
*/
72+
6473
typedef struct fifo
6574
{
6675
size_t head_ptr, tail_ptr, len, size, data_len;
@@ -84,6 +93,10 @@ void fifo_peek(fifo_t *ptr, void *data);
8493
// list //
8594
//////////
8695

96+
/* STM32IPL
97+
* These list functions can be used at application side.
98+
*/
99+
87100
typedef struct list_lnk
88101
{
89102
struct list_lnk *next_ptr, *prev_ptr;
@@ -120,6 +133,10 @@ void list_set(list_t *ptr, void *data, size_t index);
120133
// iterator //
121134
//////////////
122135

136+
/* STM32IPL
137+
* These iterator functions can be used at application side.
138+
*/
139+
123140
list_lnk_t *iterator_start_from_head(list_t *ptr);
124141
list_lnk_t *iterator_start_from_tail(list_t *ptr);
125142
list_lnk_t *iterator_next(list_lnk_t *lnk);

Inc/stm32ipl_mem_alloc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
******************************************************************************
33
* @file stm32ipl_mem_alloc.h
44
* @author SRA AI Application Team
5-
* @brief STM32 Image Processing Library - memory allocation wrapper header file
5+
* @brief STM32 Image Processing Library - memory allocation header file
66
******************************************************************************
77
* @attention
88
*

Readme.md

Lines changed: 204 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
## Introduction
88

9-
This document is a quick guide that introduces ***STM32 Image Processing Library*** and provides advises about the preparation and the usage of the *STM32 Image Processing Library* in real applications.
9+
This document is a quick guide that introduces ***STM32 Image Processing Library*** and provides advise about the preparation and the usage of the *STM32 Image Processing Library* in real applications.
1010

1111
*STM32 Image Processing Library* (in short, ***STM32IPL***) is a C software library for ***STMicroelectronics STM32 MCUs*** that provides specific functionalities that help the development of visual analysis applications.
1212

@@ -21,7 +21,7 @@ Please, note that this document does not contain detailed specifications of the
2121

2222
## Main characteristics
2323

24-
*STM32IPL* is an open source software library, written in C, that offers image processing and computer vision functionalities for a faster development of visual analysis applications on ***STM32*** microcontrollers.
24+
*STM32IPL* is an open-source software library, written in C, that offers image processing and computer vision functionalities for a faster development of visual analysis applications on ***STM32*** microcontrollers.
2525

2626
The main key characteristics of *STM32IPL* are:
2727

@@ -63,9 +63,9 @@ The software architecture of a typical *STM32* application exploiting *STM32IPL*
6363

6464
*STM32IPL* is released as open source ***STM32Cube Middleware*** component; basically, all the *STM32IPL* functions are platform independent, with few exceptions:
6565

66-
- The I/O functions that perform reading/writing operation on files, in particular, the two read/write functions that handle the supported image file formats as *BMP* (*Windows Bitmap*), *PPM* (*Portable PixMap*), *PGM* (*Portable GreyMap*), and *JPEG*: these functions depend on the following third party open source libraries that are part of the set of *STM32Cube Middleware* components:
66+
- The I/O functions that perform reading/writing operation on files, in particular, the two read/write functions that handle the supported image file formats as *BMP* (*Windows Bitmap*), *PPM* (*Portable PixMap*), *PGM* (*Portable GreyMap*), and *JPEG*: these functions depend on the following third-party open source libraries that are part of the set of *STM32Cube Middleware* components:
6767

68-
- ***FatFs***, that offers read/write operations on a *FatFS* file system (which can be, for example, mounted on an SD card)
68+
- ***FatFs***, that offers read/write operations on a *FatFS* file system (which can be, for example, mounted on an microSD card)
6969

7070
- ***LibJPEG***, that offers *JPEG* encoding and decoding functionalities
7171

@@ -83,7 +83,7 @@ This section describes the basic steps needed to develop an *STM32* application
8383

8484
### Setting the project properties
8585

86-
First of all, it is necessary to add the *STM32_ImageProcessing_Library/Inc* folder to the list of the include directories of the application project.
86+
As first step, it is necessary to add the *STM32_ImageProcessing_Library/Inc* folder to the list of the include directories of the application project.
8787

8888
Then, it is necessary to add `STM32IPL` to the list of define symbols of the compiler pre-processor.
8989

@@ -226,18 +226,25 @@ So, in general, it is up to the developer to read the documentation to understan
226226

227227
As soon as the *STM32IPL* is not needed anymore, the user can call `STM32Ipl_DeInitLib()` to release the whole memory block reserved at the beginning, so that it can be made available for further usages.
228228

229-
## Example
229+
### Containers
230230

231-
This section shows a simple example that uses *STM32IPL* to:
231+
*STM32IPL* uses two types of containers to store complex data: **list** and **array**. These containers are used as arguments to some *STM32IPL* functions, sometimes as input and sometimes as output parameters. In the following *Examples* section some handy examples that explain how to use such containers are reported.
232+
233+
## Examples
234+
235+
This section shows simple practical examples explaining how to use *STM32IPL* to develop applications. Such examples assume that *STM32IPL* has been properly initialized as explained in the section *Initialization of the library* above.
236+
237+
The examples below typically read image from files, so it is assumed that the user has properly initialized and mounted the *FatFs* file system, for instance on a microSD card, as the pertinent source code is not included here.
238+
239+
### Resize
240+
241+
This example explains how to:
232242

233243
- read an image
234-
- resize it to a destination image
244+
- resize it to a smaller destination image
235245
- show both images to the screen
236246

237247
```c
238-
/*
239-
* This example shows how to resize a source image to a smaller destination image.
240-
*/
241248
void Resize(void)
242249
{
243250
image_t srcImg; // Source image.
@@ -252,7 +259,8 @@ void Resize(void)
252259

253260
// Allocate memory to the destination image.
254261
// The destination image must have the same format as the source image.
255-
if (stm32ipl_err_Ok == STM32Ipl_AllocData(&dstImg, dstWidth, dstHeight, image_bpp_t)srcImg.bpp)) {
262+
if (stm32ipl_err_Ok == STM32Ipl_AllocData(&dstImg, dstWidth, dstHeight,
263+
image_bpp_t)srcImg.bpp)) {
256264
// Resize the source image and store the results into the destination image.
257265
if (stm32ipl_err_Ok == STM32Ipl_Resize(&srcImg, &dstImg, NULL)) {
258266
// Display the destination image on the screen (right side).
@@ -269,3 +277,187 @@ void Resize(void)
269277
}
270278
```
271279
280+
### Face Detection
281+
282+
This example explains how to:
283+
284+
- read an image
285+
- detect the faces in the image
286+
- use an array container to get the results (detected faces)
287+
- draw the bounding boxes of the faces in the image
288+
- show the image with the bounding boxes of the detected faces on the screen
289+
290+
```c
291+
void FaceDetection(void)
292+
{
293+
image_t img;
294+
cascade_t cascade; // The cascade structure used by the object detector.
295+
uint16_t thickness = 2; // Set the thickness of the rectangle (pixels).
296+
bool fill = false; // Avoid to fill the rectangle.
297+
float scaleFactor = 1.25f; // Modify this value to detect objects at
298+
// different scale (must be > 1.0f).
299+
float threshold = 0.75f; // Modify this value to tune the detection rate against
300+
// the false positive rate (0.0f - 1.0f).
301+
302+
// Load face cascade.
303+
if (stm32ipl_err_Ok == STM32Ipl_LoadFaceCascade(&cascade)) {
304+
// Load an image from file system.
305+
if (stm32ipl_err_Ok == STM32Ipl_ReadImage(&img, "myImage.bmp")) {
306+
uint32_t faceCount;
307+
array_t *faces = 0;
308+
309+
// Detect faces. No ROI is passed, so the full image is analyzed.
310+
if (stm32ipl_err_Ok == STM32Ipl_DetectObject(&img, &faces, NULL, &cascade,
311+
scaleFactor, threshold)) {
312+
313+
// Get the number of detected faces.
314+
faceCount = array_length(faces);
315+
316+
// Get the bounding box for each detected face.
317+
for (int i = 0; i < faceCount; i++) {
318+
rectangle_t *r = array_at(faces, i);
319+
320+
// Draw the bounding box around each detected face.
321+
STM32Ipl_DrawRectangle(&img, r->x, r->y, r->w, r->h,
322+
STM32IPL_COLOR_GREEN, thickness, fill);
323+
}
324+
325+
// Release the array containing the faces.
326+
array_free(faces);
327+
faces = NULL;
328+
}
329+
330+
// Display the image with the bounding boxes of the detected face
331+
// on the top-left corner of the screen.
332+
STM32Ipl_DrawScreen_DMA2D(&img, 0, 0);
333+
334+
// Release the memory buffer containing the source data image.
335+
STM32Ipl_ReleaseData(&img);
336+
}
337+
}
338+
}
339+
```
340+
341+
### Binarization
342+
343+
This example explains how to:
344+
345+
- read an image
346+
- use a list container to set the proper thresholds needed for the binarization
347+
- execute the binarization
348+
- show the binary image on the screen
349+
350+
```c
351+
void Binarization(void)
352+
{
353+
image_t img;
354+
list_t thresholds; // List of LAB thresholds used to binarize the image.
355+
color_thresholds_list_lnk_data_t colorTh; // Structure used to set the thresholds.
356+
bool invert = false; // Take the values inside the threshold bounds.
357+
bool zero = false; // The thresholded pixels in the destination image
358+
// are set to 1, the others to 0.
359+
360+
// Set the thresholds on LAB channels.
361+
colorTh.LMin = 0;
362+
colorTh.LMax = 100;
363+
colorTh.AMin = 0;
364+
colorTh.AMax = 127;
365+
colorTh.BMin = 0;
366+
colorTh.BMax = 127;
367+
368+
// Init the list so that each element has the right size.
369+
list_init(&thresholds, sizeof(color_thresholds_list_lnk_data_t));
370+
371+
// Push the thresholds used to binarize the image into the list.
372+
list_push_back(&thresholds, &colorTh);
373+
374+
// Read the image from file system.
375+
if (stm32ipl_err_Ok == STM32Ipl_ReadImage(&img, "myImage.bmp")) {
376+
377+
// Display the image on the screen (left side).
378+
STM32Ipl_DrawScreen_DMA2D(&img, 0, 0);
379+
380+
// Execute the binarization. In this case, source and destination are the same,
381+
// so the source image is overwritten with the binarized image; no mask is used.
382+
if (stm32ipl_err_Ok == STM32Ipl_Binary(&img, &img, &thresholds,
383+
invert, zero, NULL)) {
384+
// Display the modified image on the screen (left side).
385+
STM32Ipl_DrawScreen_DMA2D(&img, 400, 0);
386+
}
387+
388+
// Release the image data buffer.
389+
STM32Ipl_ReleaseData(&img);
390+
}
391+
392+
// Finally, release the memory allocated to the list.
393+
list_free(&thresholds);
394+
}
395+
```
396+
### Find circles
397+
398+
This example explains how to:
399+
400+
- read an image
401+
- find circles in the image using the Hough transform
402+
- use a list container to get the circles found
403+
- draw the circles on the image
404+
- show the image with the circles on the screen
405+
406+
407+
```c
408+
void FindCircle(void)
409+
{
410+
image_t img;
411+
list_t circles; // List of circles found.
412+
uint16_t thickness = 2; // Set the thickness of the circles (pixels).
413+
bool fill = false; // Avoid to fill the circle.
414+
uint32_t xStride = 2; // Number of pixels to be skipped horizontally.
415+
uint32_t yStride = 2; // Number of pixels to be skipped vertically.
416+
uint32_t threshold = 2000; // Magnitude threshold; only circles with magnitude
417+
// greater than or equal to such threshold are returned.
418+
uint32_t xMargin = 10; // Circles having horizontal distance between their
419+
// centers less than this value are merged.
420+
uint32_t yMargin = 10; // Circles having vertical distance between their centers
421+
// less than this value are merged.
422+
uint32_t rMargin = 30; // Circles having difference between their radius less
423+
// than this value are merged.
424+
uint32_t rMin = 18; // Minimum circle radius detected; increase it to speed
425+
// up the execution.
426+
uint32_t rMax = 50; // Maximum circle radius detected; decrease it to speed
427+
// up the execution.
428+
uint32_t rStep = 2; // Radius step value.
429+
430+
// Read the image from file system.
431+
if (stm32ipl_err_Ok == STM32Ipl_ReadImage(&img, "myImage.bmp")) {
432+
433+
// Search for the circles in the full image (no ROI is used)
434+
if (stm32ipl_err_Ok == STM32Ipl_FindCircles(&img, &circles, NULL,
435+
xStride, yStride, threshold,
436+
xMargin, yMargin, rMargin,
437+
rMin, rMax, rStep)) {
438+
439+
// Cycle through the circles found.
440+
while (list_size(&circles)) {
441+
find_circles_list_lnk_data_t circle;
442+
443+
// Pop the first circle in the list.
444+
list_pop_front(&circles, &circle);
445+
446+
// Now the list has one element less.
447+
448+
// Draw the circle on the image
449+
STM32Ipl_DrawCircle(&img, circle.p.x, circle.p.y, circle.r,
450+
TM32IPL_COLOR_GREEN, thickness, fill);
451+
}
452+
453+
// Now the list is empty, so it is not necessary to free it.
454+
}
455+
456+
// Display the image on the screen.
457+
STM32Ipl_DrawScreen_DMA2D(&img, 0, 0);
458+
459+
// Release the image data buffer.
460+
STM32Ipl_ReleaseData(&img);
461+
}
462+
}
463+
```

STM32IPL.chm

4.39 KB
Binary file not shown.

Src/stm32ipl_find_pixels.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ stm32ipl_err_t STM32Ipl_GetPixel(const image_t *img, uint16_t x, uint16_t y, stm
7575
* @brief Finds minimum and maximum point locations in an image. For RGB images, the Y value is considered.
7676
* The supported formats are Binary, Grayscale, RGB565, RGB888.
7777
* @param img Image; if it is not valid, an error is returned.
78-
* @param outMin List of points that represents the coordinates of minimum values; if it is not
79-
* valid, an error is returned.
80-
* @param outMax List of points that represents the coordinates of maximum values; if it is not
81-
* valid, an error is returned.
78+
* @param outMin List of point_t elements that represents the coordinates of the minimum values;
79+
* if it is not valid, an error is returned.
80+
* @param outMax List of point_t elements that represents the coordinates of maximum values;
81+
* if it is not valid, an error is returned.
8282
* @param roi Optional region of interest of the source image where the functions operates;
8383
* when defined, it must be contained in the source image and have positive dimensions, otherwise
8484
* an error is returned; when not defined, the whole image is considered.
@@ -406,7 +406,7 @@ stm32ipl_err_t STM32Ipl_FindMinMaxLoc(const image_t *img, list_t *outMin, list_t
406406
* @brief Finds the locations of non zero pixels in an image.
407407
* The supported formats are Binary, Grayscale, RGB565, RGB888.
408408
* @param img Image; if it is not valid, an error is returned.
409-
* @param out List of points that represents the coordinates of the non zero pixels;
409+
* @param out List of point_t elements that represents the coordinates of the non zero pixels;
410410
* if it is not valid, an error is returned.
411411
* @param roi Optional region of interest of the source image where the functions operates;
412412
* when defined, it must be contained in the source image and have positive dimensions, otherwise

Src/stm32ipl_hough.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extern "C" {
2727
* @brief Finds all infinite lines in the image using the Hough transform. Returns a list of lines ().
2828
* The supported formats are Binary, Grayscale, RGB565, RGB888.
2929
* @param img Image; if it is not valid, an error is returned.
30-
* @param out List of lines found. The type of results is find_lines_list_lnk_data_t.
30+
* @param out List of find_lines_list_lnk_data_t objects representing the lines found.
3131
* @param roi Optional region of interest of the source image where the functions operates;
3232
* when defined, it must be contained in the source image and have positive dimensions, otherwise
3333
* an error is returned; when not defined, the whole image is considered.
@@ -65,7 +65,7 @@ stm32ipl_err_t STM32Ipl_FindLines(const image_t *img, list_t *out, const rectang
6565
* @param roi Optional region of interest of the source image where the functions operates;
6666
* when defined, it must be contained in the source image and have positive dimensions, otherwise
6767
* an error is returned; when not defined, the whole image is considered.
68-
* @param out List of circles found. The type of results is find_circles_list_lnk_data_t.
68+
* @param out List of find_circles_list_lnk_data_t objects representing the circles found.
6969
* @param xStride Number of x pixels to skip when doing the Hough transform. Only increase this if circles you are searching for are large and bulky.
7070
* @param yStride Number of y pixels to skip when doing the Hough transform. Only increase this if circles you are searching for are large and bulky.
7171
* @param threshold Only circles with a magnitude greater than or equal to threshold are returned.

Src/stm32ipl_mem_alloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ void* fb_alloc0(uint32_t size, int hints)
241241
}
242242

243243
/*
244-
* @brief Allocates a biggest memory buffer from the fb stack.
244+
* @brief Allocates the biggest memory buffer from the fb stack.
245245
* Such buffer must be released with fb_free().
246246
* @param size Used to return the size of the allocated memory buffer (bytes).
247247
* @param hints Argument not used.

Src/stm32ipl_object_det.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ stm32ipl_err_t STM32Ipl_LoadEyeCascade(cascade_t *cascade)
6060

6161
/**
6262
* @brief Detects objects, described by the given cascade. The detected object are stored in an array_t
63-
* structure containing the bounding boxes (rectangle_t) one for each object detected; the caller is
63+
* structure containing the bounding boxes (rectangle_t), one for each object detected; the caller is
6464
* responsible to release the array. The supported formats are Grayscale, RGB565, RGB888.
6565
* @param img Image; if it is not valid, an error is returned.
6666
* @param out Pointer to pointer to the array structure that will contain the detected objects.

0 commit comments

Comments
 (0)