# Calculating distance between two blobs in a binary image in microns

I have a monochrome CCD camera with resolution 960 X 1280 and can give up-to 15 fps
I am working on python opencv.

I want to track the distance between two rectangular blobs in binary images in real time (1 value per 2 or more secs)

My field of view is 40 mm and i want to obtain the resolution of upto 1 micron with +-1% accuracy.

Can this be achieved using binary image or is there any other way to achieve this ?

all suggestions are welcome

• can you please share some sample images? – Atul Ingle Nov 11 '17 at 17:11
• @AtulIngle Please have a look at the attached sample image. The rectangular blobs in the sample image would be moving further apart as the video continues. – Gaurang Deshpande Nov 11 '17 at 17:19

This is relatively straight-forward with OpenCV and numpy.

Step One: Using OpenCV's Blob Detector you can do something like this:

import cv2

params = cv2.SimpleBlobDetector_Params()
params.blobColor = 255
detector = cv2.SimpleBlobDetector_create(params)

keypoints = detector.detect(im)

kpt_image = cv2.drawKeypoints(im, keypoints, numpy.array([]),(0,0,255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

cv2.imshow("Keypoints", kpt_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


Step Two: Write a function to calculate the distance between two keypoints:

import numpy

def distance(kpt1, kpt2):
#create numpy array with keypoint positions
arr = numpy.array([kpt1.pt, kpt2.pt])
#scale array to mm
arr = arr*40/1280
#return distance, calculted by pythagoras
return numpy.sqrt(numpy.sum((arr[0]-arr[1])**2))


Putting it all together:

import cv2
import numpy

def distance(kpt1, kpt2):
#create numpy array with keypoint positions
arr = numpy.array([kpt1.pt, kpt2.pt])
#scale array to mm
arr = arr*40/1280
#return distance, calculted by pythagoras
return numpy.sqrt(numpy.sum((arr[0]-arr[1])**2))

params = cv2.SimpleBlobDetector_Params()
params.blobColor = 255
detector = cv2.SimpleBlobDetector_create(params)

keypoints = detector.detect(im)

kpt_image = cv2.drawKeypoints(im, keypoints, numpy.array([]),(0,0,255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

for i,keypoint in enumerate(keypoints[1:]):
print("Distance: {0:6.3f}mm".format(distance(keypoints[0], keypoint)))

cv2.imshow("Keypoints", kpt_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


I assume that when you say 'real time' you may want to look at annotating the image with the distance. But I'll leave you to work with that yourself. I've not actually done an error analysis, but you may need to tweak the Params above to increase accuracy.

The output image: