image-processingcomputer-visionembeddedconnected-components

Blob detection on embedded platform, memory restricted


I have a STM32H7 MCU with 1MB of RAM and 1MB of ROM. I need to make a blob detection algorithm on a binary image array of max size 1280x1024.

I have searched about blob detection algorithms and found out that they are mainly divided into 2 categories, LINK:


void setLabels(){
  int m=2; 
  for(int y=0; y<height; y++){
     for(int x=0; x<width; x++){
        if(getPixel(x,y) == 1) compLabel(x,y,m++);
     }
  }
}

void compLabel(int i, int j,int m){
  if(getPixel(i,j)==1){
    setPixel(i,j,m); //assign label

    compLabel(i-1,j-1,m); 
    compLabel(i-1,j,m);
    compLabel(i-1,j+1,m); 
    compLabel(i,j-1,m);
    compLabel(i,j+1,m); 
    compLabel(i+1,j-1,m);
    compLabel(i+1,j,m); 
    compLabel(i+1,j+1,m);
  }
}

The down sides of the 1st algorithm is that it is using recursive calls for all the pixel around the original pixel. I am afraid that it will cause hard fault errors on STM32 because of the limited stack. The down sides of the 2nd algorithm is that it requires a lot of memory for the labeling image. For instance, for the max. resolution of 1280x1024 and for the max. number of labels 255 (0 for no label), image label size is 1.25MB. Way more than we have available.

I am looking for some advice on how to proceed. How to get center coordinates and area information of all blobs in the image without using to much memory? Any help is appreciated. I presume that the 2nd algorithm is out of the picture since there is no memory available.


Solution

  • You firstly have to go over you image with a scaling kernel to scale your image back to something that is able to be processed. 4:1 or 9:1 are good possibilities. Or you are going to have to get more RAM. Because this situation seems unworkable otherwise. Bit access is not really fast and is going to kill your efficiency and I don't even think that you need that big of an image. (at least that is my experience with vision systems)

    You can then store the pixels in straight unsigned char array which can be labeled with the first method you named. It doesn't have to be a recursive process. You can also determine if a blob was relabeled to another blob and set a flag to do it again. This makes it possible to have an externally visible function have a while loop which keeps calling your labeling function without creating a big stack.

    Area determination is then done by going over the image and counting the instance of a pixel for every labeled blob.

    The center of a certain blob can be found by calulating the moments of a blob and then calculating the center of mass. This is some pretty hefty math so don't be discouraged, it is a though apple to bite through but it is a great solution.

    (small hint: you can take the C++ code from OpenCV and look through their code to find out how it's done)