1. CBlob Low-Level Blobification Package
1.1. CBlob contents
1.1.1. Structs
1.1.1.1. struct point
struct point{
int x;
int y;
};
Pretty much only used with the blob struct
1.1.1.2. struct bitmap
struct bitmap{
int width;
int height;
uint16_t* data;
};
Pretty self-explanitory. The data is a 16-bit int because the blobdata struct uses the bitmap to represent which pixel belongs to which blob (so there can be more than 256 blobs).
1.1.1.3. struct blob
struct blob{
int mass;
struct point ul;
struct point lr;
double cm_x;
double cm_y;
};
blob.ul and blob.lr are the upper-right and lower-left corners of the blob, respectively. cm_x and cm_y are the x and y coordinates of the "center of mass" of the blob.
1.1.1.4. struct blobdata
struct blobdata{
int width;
int height;
int nblobs;
struct bitmap* blobmap;
int* equivList;
struct blob** bloblist;
};
The meat of the package. nblobs is the total number of blobs, and therefore the length of the bloblist array. equivList is used internally in the blob processing [should we take it out of the struct, and just make it a local var in Blobdata_init?]. blobmap has contains the number of the blob at each pixel in its image data, and bloblist is a an array of pointers to blobs, the indexes of which correspond to the data in blobmap.
1.1.1.5. playerblob_t
typedef struct player_blobfinder_data_varsize{
uint16_t width, height;
int n_channels;
player_blobfinder_header_elt_t* header;
player_blobfinder_blob_elt_t* blobs;
} playerblob_t;
This is a struct that is basically equivalent to the player_blobfinder_data_t from Player/Stage. However, unlike the Player/Stage version, its size is determined at runtime, and can contain an unlimited (well, limited to sizeof(int)) number of blobs.
1.1.2. Functions
1.1.2.1. Blob_*
void Blob_init(struct blob* theBlob, struct point* pixel); void Blob_init_xy(struct blob* theBlob, int x, int y); void Blob_addpixel(struct blob* theBlob, struct point* pixel); void Blob_addpixel_xy(struct blob* theBlob, int x, int y); void Blob_joinblob(struct blob* theBlob, struct blob* other);
These are all called by Blobdata_init, and you shouldn't need to use them.
1.1.2.2. Bitmap_*
void Bitmap_init(struct bitmap* map, int w, int h); void Bitmap_set(struct bitmap* map, int x, int y, uint16_t in); uint16_t Bitmap_get(struct bitmap* map, int x, int y); void Bitmap_del(struct bitmap* map); int Bitmap_write_to_pgm(struct bitmap* map, char* filename, int levels);
Should be-self explanitory. To create a blank bitmap, you must allocate the memory for the bitmap struct, then call Bitmap_init on it. When you are done, call Bitmap_del on it, and then free the memory:
struct bitmap* bmp; bmp = (struct bitmap*) malloc(sizeof(struct bitmap)); Bitmap_init(bmp, width, height); // use bmp Bitmap_del(bmp); free(bmp);
or from python:
1 2 3 4 5 6 7 8 | import pyrobot.vision.cblob.blob as blob bmp = blob.bitmap() blob.Bitmap_init(blob, width, height) # use the blob blob.Bitmap_del(bmp) #bmp itself gets cleaned up automatically |
1.1.2.3. Blobdata_*
void Blobdata_init(struct blobdata* data, struct bitmap* theBitmap); void Blobdata_del(struct blobdata* data)
Use the same protocol as for bitmap. Blobdata_init is the function that actually does the processing to convert a bitmap into a list of blobs.
1.1.2.4. Transducer functions
struct bitmap* bitmap_from_cap(struct image_cap* image, int width, int height,
double (*filter)(double, double, double),
double threshold);
struct bitmap* bitmap_from_ppm(char* filename,
double (*filter)(double, double, double),
double threshold);
struct bitmap* bitmap_from_pgm(char* filename,
double (*filter)(double, double, double),
double threshold);
struct bitmap* bitmap_from_8bitGrayArray(uint8_t* array, int width, int height,
double (*filter)(double, double, double),
double threshold);
struct bitmap* bitmap_from_8bitRGBArray(uint8_t* array, int width, int height,
double (*filter)(double, double, double),
double threshold);
struct bitmap* bitmap_from_32bitPackedRGBArray(uint32_t* array, int width, int height,
double (*filter)(double, double, double),
double threshold);
These functions transform images into bitmap structs. The (*filter) argument is a callback that takes a function pointer to a filter function. These filter functions are described below. They output a float value in the range [0.0, 1.0]. If the value they return is greater than threshold at a pixel, the pixel is set to 1 in the bitmap, otherwise it's set to 0. Remember that you still have to call Bitmap_del on the bitmap returned by these functions and free the pointer, although you do not have to malloc or Bitmap_init the bitmap before you call a transducer.
bitmap_from_cap takes an image_cap struct from the pyro.camera.v4l package, and returns a bitmap of the current image. The others should be self-explanitory
1.1.2.5. filter functions
double filter_red (double r, double g, double b); double filter_green (double r, double g, double b); double filter_blue (double r, double g, double b); double filter_hue (double r, double g, double b); double filter_saturation (double r, double g, double b); double filter_brightness (double r, double g, double b);
These functions are for use with the tranducer functions, described above. They take an rgb value as three doubles in the range [0.0, 1.0], and return a number in the same range. Because of how SWIG works, if you want to use these functions from python, you much use their name in all caps. For example:
import pyrobot.vision.cblob.blob as blob
bmp = blob.bitmap_from_ppm("cap.ppm", blob.FILTER_BRIGHTNESS, 0.5)
If you are planning on adding a new filter, you must modify the SWIG interface file blob.i. The file looks like this:
%module blob
%include blob.h
%{
#include "blob.h"
typedef double (*FILTER_FUNC)(double, double, double);
const FILTER_FUNC FILTER_RED = filter_red;
const FILTER_FUNC FILTER_BLUE = filter_blue;
const FILTER_FUNC FILTER_GREEN = filter_green;
const FILTER_FUNC FILTER_HUE = filter_hue;
const FILTER_FUNC FILTER_SATURATION = filter_saturation;
const FILTER_FUNC FILTER_BRIGHTNESS = filter_brightness;
%}
typedef double (*FILTER_FUNC)(double, double, double);
const FILTER_FUNC FILTER_RED = filter_red;
const FILTER_FUNC FILTER_BLUE = filter_blue;
const FILTER_FUNC FILTER_GREEN = filter_green;
const FILTER_FUNC FILTER_HUE = filter_hue;
const FILTER_FUNC FILTER_SATURATION = filter_saturation;
const FILTER_FUNC FILTER_BRIGHTNESS = filter_brightness;
To add a new funciton, add two new const FILTER_FUNC lines, one inside the %{}% brackets, and one outside them.
1.1.2.6. Player/Stage export functions
player_blobfinder_data_t* make_player_blob(struct blobdata** blobs, uint32_t* channels, int n_channels); playerblob_t* make_player_blob_varsize(struct blobdata** blobs, uint32_t* channels, int n_channels); void playerblob_del(playerblob_t* blobs);These functions convert a list of blobdata structs, built on different channels, to a struct that Player/Stage could use.
