0
$\begingroup$

enter image description hereI 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

$\endgroup$
  • $\begingroup$ can you please share some sample images? $\endgroup$ – Atul Ingle Nov 11 '17 at 17:11
  • $\begingroup$ @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. $\endgroup$ – Gaurang Deshpande Nov 11 '17 at 17:19
1
$\begingroup$

This is relatively straight-forward with OpenCV and numpy.

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

import cv2

im = cv2.imread("blobs.png", cv2.IMREAD_GRAYSCALE)
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))

im = cv2.imread("blobs.png", cv2.IMREAD_GRAYSCALE)
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: Blob detected image

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.