I need to detect evaporating diesel spray cones in an image sequence obtained from a combined schlieren scatterlight measurement. Sadly there is a lot of noise in my images. I use a simple background substraction to get a greyscale of my spray. Heres are some samples of the original and the grey:
I have tried detecting the spray using morphological functions to get rid of the noise, but sometimes there is just to much noise so this doesn't work any more.
My newest idea for a more robust detection was to fit a simple shape to the greyscale. I could then use this simple shape to characterize my spray. I used fminsearch
to minimize a merrit function (zielfkt). The merrit function is made up of the mean brightness on the inside and the outside of my cone. I use bwkegelerzeugen
to create my cone.
Long story short, it doesn't quite work out as i want it to. There are some wrinkles in my merrit function where the minimizer gets stuck. (see image)
- Does this approach of fitting a shape make sense?
- Should I use a different merrit function?
- Are there other ways of fitting a shape like pattern recognition (although I don't understand anything of pattern recognition)?
Maybe you also know some good filters to improve my greyscale (a median filter already helps) or a filter to create a different greyscale?
Please answer so a mechanical engineer can understand :)
This is my code
searchfkt=@(x) zielfkt_v1(x(1),x(2),x(3),im4,mask,1);
x = fminsearch(searchfkt,x,options);
function z = zielfkt_v1(alpha,length,spraywin,greyim,mask,ifrund)
param=[1,10];
bwkegel=logical(bwkegelerzeugen(alpha,length,spraywin,size(greyim),ifrund));
meanin =mean(greyim(bwkegel));
meanout=mean(greyim(~bwkegel & ~mask));
z=param(2)*meanout-1*param(1)*meanin;
end
function [ bwkegel ] = bwkegelerzeugen(alpha,length,delta,imsize,ifrund)
bwkegel=zeros(imsize);
mitte=imsize(1)/2;
length=max(30,min(length,imsize(2)));
alpha=max(10,min(alpha,30));
kegellength=round(length/(1+tand(alpha/2)));
radius=round(length-kegellength);
maxdelta=2;
if ifrund
for dd=1:kegellength
kegelbreite=2*dd*tand(alpha/2);
kegelob=max(1,round(mitte-kegelbreite/2));
kegelun=min(imsize(1),round(mitte+kegelbreite/2));
bwkegel(kegelob:kegelun,dd)=1;
end
for dd=kegellength:length
kegelbreite=(radius^2-(dd-kegellength)^2)^0.5;
kegelob=max(1,round(mitte-kegelbreite));
kegelun=min(imsize(1),round(mitte+kegelbreite));
bwkegel(kegelob:kegelun,dd)=1;
end
else
for dd=1:round(length)
kegelbreite=2*dd*tand(alpha/2);
kegelob=max(1,round(mitte-kegelbreite/2));
kegelun=min(imsize(1),round(mitte+kegelbreite/2));
bwkegel(kegelob:kegelun,dd)=1;
end
end
if delta
delta=max(min(delta,maxdelta),-maxdelta);
bwkegelturn=zeros(imsize(1),imsize(2)*2);
bwkegelturn(:,imsize(2)+1:end)=bwkegel;
bwkegelturn=imrotate(bwkegelturn,delta,'crop');
bwkegel=bwkegelturn(:,imsize(2)+1:end);
end
end
There is the other approach. You need to apply an image segmentation and then image analysis. Then you can analyze shapes and textures as well wich may be helpful in this task. As the segmentation techniques I would try different adaptive thresholding methods, then maybe morphological operators. Next step is to use conected components matlab function (CC = bwconncomp(BW)) or region properties function (STATS = regionprops(BW, properties)). After that you have to analyse the shape or texture values of different objects (segments on your binary image) and find the rules for object you want to detect.