Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MATLAB: detecting non-continuous vertical streaks in greyscale image

In the attached image there are periodic vertical streaks which are random along the x axis and vary along the y axis in their intensity.
Any suggestions on how to detect these?
Ideally I would like to detect these with an output of a binary image showing the streaks (I imagine it will end up looking like a bar code).

Thanks!

enter image description here

like image 219
user3470496 Avatar asked Jan 06 '16 06:01

user3470496


2 Answers

Photon's answer is very good: he suggested alongated vertical edge filters to capture the vertical edges of the streaks.
However, if you are interested in locating the streaks themselves and not their edges, you might consider a slightly different approach:

I propose to, first, eliminate the "DC" component, so that the streaks will "pop out" of a roughly constant background, then use a vertical sum to locate them and produce a mask.

Here's a sketch of the code:

img = im2double( imread('http://i.stack.imgur.com/SqZrf.jpg') ); %// read the image

Use a horizontal filter to get an estimate of the local "DC", that is, an image where the streaks are gone:

dc_est = imfilter(img, ones(1,31)/31, 'symmetric' ); 

Looking at the difference between the image and the estimated "DC" should make the streaks pop out and easy to threshold using a global threshold:

global_thr = 0.025;
mask = ones(size(img,1),1)*(mean(img-dc_est,1)>global_thr);
figure; imshow(mask);

And heres' the result (you might want to change the threshold value and see how it affects the result):
enter image description here

The estimated "DC", dc_est looks like:

enter image description here


If you are after a more elaborate adventure, I recommend that you explore this work: I. Horev, B. Nadler, E. Arias-Castro, M. Galun, R.Basri Detection of long edges on a computational budget: a sub-linear approach (SIAM 2015). This method is aimed at finding these elusive edges and ridges in noisy intensity images.

like image 115
Shai Avatar answered Oct 06 '22 04:10

Shai


You can use a simple horizontal filter to collect information about these lines:

I=imread('lines.jpg');
I=double(I)*(1.0/255.0);
J=filter2([-1 0 1;-1 0 1;-1 0 1],I);
s=sum(J);

Which results in the following 1D signal for the image.

Result of initial processing

You can then find the right threshold for you on this signal, and use the index as the line position.

like image 26
Photon Avatar answered Oct 06 '22 05:10

Photon