I am trying to write a class that uses the Laplacian of Gaussian for blob detection. Here is the class that I wrote:
import cv2 as cv
import numpy as np
from sklearn.preprocessing import normalize
from scipy import ndimage
class Blob:
BlobStack = [[[[]]]]
def _getLGKernel(self,sx,sy):
kx = (int(sx - 0.8)*4+1)*2+1
ky = (int(sy - 0.8)*4+1)*2+1
gaussKernelX = np.float32(cv.getGaussianKernel(kx,sx))
gaussKernelY = np.float32(cv.getGaussianKernel(ky,sy))
d2GaussKernelX = cv.Laplacian(gaussKernelX,cv.CV_32F)[1:kx-1]
d2GaussKernelY = cv.Laplacian(gaussKernelY,cv.CV_32F)[1:ky-1]
d2GaussKernelX = normalize(d2GaussKernelX,axis=0)
d2GaussKernelY = normalize(d2GaussKernelY,axis=0)
return d2GaussKernelX, d2GaussKernelY
def __init__(self,img,mins,maxs,steps):
step = int((maxs-mins)/steps)
r = range(mins,maxs+step,step)
self.BlobStack = np.zeros((np.size(r),np.size(r),np.shape(img)[0],np.shape(img)[1]),dtype= np.float32)
for i,sx in enumerate(r):
for j,sy in enumerate(r):
kernx, kerny = self._getLGKernel(sx, sy)
self.BlobStack[i,j] = np.abs(cv.filter2D(img,cv.CV_64F,kernx,borderType = cv.BORDER_REPLICATE) \
+cv.filter2D(img,cv.CV_64F,np.transpose(kerny),borderType = cv.BORDER_REPLICATE))
return
def findLocalBlobs(self,sz):
LocalBlobs = np.where(ndimage.maximum_filter(self.BlobStack,size=sz) == self.BlobStack)
LocalBlobs = np.asarray(LocalBlobs).transpose()
return LocalBlobs
Right now I am using a test case with two circles of various darkness on a white background. I am getting many extra blobs that shouldn't be there. Some are at the minimum or maximum kernel size but some are at other kernel sizes. There are kernel sizes, which are sometimes the max kernel size in one direction but not always, that have a constant value in a large region that it is detecting a local minimum at. It is lower than the value of the actual blobs I want to detect but still well above what could be a floating point error. A straight forward filtering by the value of the LoG doesn't work because some of the 'phantom' blobs have a higher value than the circle with the lower contrast to the background.
I am more interested in help from a theoretical image processing prospective as this is just a project that I am using to learn from, but any help would be appreciated.