2

I am trying to write a program that uses computer vision techniques to detect (and track) tiny blobs in a stream of very noisy images. The image stream comes from an dual X ray imaging setup, which outputs left and right views (different sizes because of collimating differently). My data is of two types: one set of images are not so noisy, which I am just using to try different techniques with, and the other set are noisier, and this is where the detection needs to work at the end. The image stream is at 60 Hz. This is an example of a raw image from the X ray imager:

enter image description here

Here are some cropped out samples of the regions of interest. The blobs that need to be detected are the small black spots near the center of the image.

Sample image 1 enter image description here enter image description here

Initially I started off with a simple contour/blob detection techniques in OpenCV, which were not very helpful. Eventually I moved on to techniques such as "opening" the image using morphological operators, and subsequently performing a Laplacian of Gaussian blob detection to detect areas of interest. This gave me better results for the low-noise versions of the images, but fails when it comes to the high-noise ones: gives me too many false positives. Here is a result from a low-noise image (please note input image was inverted).

enter image description here

The code for my current LoG based approach in MATLAB goes as below:

while ~isDone(videoReader)
    frame = step(videoReader);
    roi_frame = imcrop(frame, [660 410 120 110]);

    I_roi = rgb2gray(roi_frame);
    I_roi = imcomplement(I_roi);
    I_roi = wiener2(I_roi, [5 5]);
    background = imopen(I_roi,strel('disk',3));

    I2 = imadjust(I_roi - background);
    K = imgaussfilt(I2, 5);
    level = graythresh(K);
    bw = im2bw(I2);

    sigma = 3;    
    % Filter image with LoG
    I = double(bw);
    h = fspecial('log',sigma*30,sigma);
    Ifilt = -imfilter(I,h);

    % Threshold for points of interest
    Ifilt(Ifilt < 0.001) = 0;
    % Dilate to obtain local maxima
    Idil = imdilate(Ifilt,strel('disk',50));

    % This is the final image
    P = (Ifilt == Idil) .* Ifilt;

Is there any way I can improve my current detection technique to make it work for images with a lot of background noise? Or are there techniques better suited for images like this?

HighVoltage
  • 722
  • 7
  • 25
  • 1
    is the camera and the scene stationary and only the blobs are moving? – Micka Dec 19 '16 at 07:10
  • How fast are the blobs moving and what is the frame rate? – Mark Setchell Dec 19 '16 at 08:28
  • 2
    Why are your images all different sizes? As your images are part of a stream, I think you need to leverage that to reduce noise. Depending on the frame rate, I would consider keeping a moving average of the last few seconds of frames as a reference and an average of the last 2-4 frames and then differencing so as to remove the noise. Hard to say without knowing more about your setup. This may be useful... http://stackoverflow.com/a/27893051/2836621 – Mark Setchell Dec 19 '16 at 09:06
  • you probably want to use a more robust tracking approach, e.g. https://github.com/gnebehay/DSST – eqzx Dec 19 '16 at 16:01
  • Are your "target objects" of a consistent size, shape, and or reflectivity? (what is the variability) Could you also post an image (if you have it) of a picture without any objects? – Sneaky Polar Bear Dec 19 '16 at 16:21
  • @MarkSetchell: I added more information in the question about the imaging setup. The frame rate of the stream is 60 Hz, and the blobs would be moving quite slowly: but in the samples that I have right now, the blobs are stationary. – HighVoltage Dec 19 '16 at 18:32
  • @SneakyPolarBear: Yes, the blobs should be of consistent size and shape, but as they're quite small, I've seen frames where the noise kind of seems to dominate. Unfortunately, I don't have an image without the objects; but I can get some if that would be helpful for any techniques. – HighVoltage Dec 19 '16 at 18:33

1 Answers1

1

The approach I would take:

-Average background subtraction

-Aggressive Gaussian smoothing (this filter should be shaped based on your target object, off the top of my head I think you want the sigma about half the smallest cross section of your object, but you may want to fiddle with this) Basically the goal is blurring the noise as much as possible without completely losing your target objects (based on shape and size)

-Edge detection. Try to be specific to the object if possible (basically, look at what the object's edge looks like after Gaussian smoothing and set your edge detection to look for that width and contrast shift)

-May consider running a closing operation here.

-Search the whole image for islands (fully enclosed regions) filter based on size and then on shape.

I am taking a hunch that despite the incredibly low signal to noise ratio, your granularity of noise is hopefully significantly smaller than your object size. (if your noise is both equivalent contrast and same ballpark size as your object... you are sunk and need to re-evaluate your acquisition imo)

Another note based on your speed needs. Extreme amounts of processing savings can be made through knowing last known positions and searching locally and also knowing where new targets can enter the image from.

Community
  • 1
  • 1
Sneaky Polar Bear
  • 1,611
  • 2
  • 17
  • 29