Search code examples
pythondictionarygaussiankernel-density

Convert point/dot annotation in to gaussian density map


I'm studying this paper: https://papers.nips.cc/paper/2010/file/fe73f687e5bc5280214e0486b273a5f9-Paper.pdf and I'm struggling at the function below:

image

Basically in an image, each person will be annotated a dot rather than bounding box or segmentation. The paper proposed a way to convert a dot into Gaussian density map, which acts as a ground truth. I have try numpy.random.multivariate_normal but it seems not working.


Solution

  • I am working on a research problem involving density maps. This code assumes you are looping over a list of text files, where each text file has the point annotations (or you are converting from object to point annotations, like I did). It also assumes that you have a list of annotations with (x,y) centre points to work with (after reading/processing said text file).

    You can find a good implementation of this here: https://github.com/CommissarMa/MCNN-pytorch/blob/master/data_preparation/k_nearest_gaussian_kernel.py

    The above has some extra code for adaptive kernels.

    The below code in context (with a lot more 'fluff') is here: https://github.com/MattSkiff/cow_flow/blob/master/data_loader.py

    Here is the code I used:

    # running gaussian filter over points as in crowdcount mcnn
             
    density_map = np.zeros((img_size[1],img_size[0]), dtype=np.float32)
      
    # add points onto basemap
    for point in annotations:
    
        base_map = np.zeros((img_size[1], img_size[0]), dtype=np.float32)       
                            
        # subtract 1 to account for 0 indexing
        base_map[int(round(point[1]*img_size[1])-1),
                 int(round(point[0]*img_size[0])-1)] += 1
    
        density_map += scipy.ndimage.filters.gaussian_filter(base_map, sigma = sigma, mode='constant')
    

    This should create a density map that does what you want. Using 'imshow' on an ax object from matplotlib (e.g. ax.imshow(density,cmap='hot',interpolation='nearest') should produce a density map like so (I've added the aerial image to indicate what is being labelled):

    Left hand side: density map with gaussian kernels placed, right hand side: aerial imagery from land information new zealand