Can this function work any faster?
Ältere Kommentare anzeigen
Hello All, Well I'm making a function that takes about 0.022 seconds to complete, I need to try to make it even less time then that, just getting peoples opinions. The end result needs to run at 120 Hz, I have tried most matlab built in functions, but there too slow for what I need, I know because I've tried. This is designed to be used for an accelerator beam image, it is just a "spot" on the screen and the image coming in has about 606x1182 pixels in it. The inputs are an image and a threshold(which is usually == 0). I pretty much have striped down to bare essentials for this code, however hope there was something I missed that will make it faster. I was just hoping for peoples comments or options about any way to make this code faster(or if there is a better way):
function [clipedImg,tfr,tfc] = ImageClipper(useImg,threshold)
useImg = double(useImg); %????????????????????????
mx = max(useImg);
my = max(useImg,[],2);
sorted=sort(my(:));
dist=diff([sorted; sorted(end)-1]);
idx=find(dist);
num=[idx(1); diff(idx)];
n=max(num);
ty=sorted(idx(num==n));
v = mx > ty;
na = length(v);
b = [1 -1];
[k,zf] = filter(b, 1, v);
k(na+1:na+2-1) = zf;
P = find(k==1);
L = find(k==-1)-P;
LP = [max(L) P(L==max(L))];
tfc = [false(1,LP(1,2)-threshold) true(1,LP(1,1)+2*threshold) false(1,length(mx)-sum(LP)-threshold)];
v = my > ty;
na = length(v);
b = [1 -1];
[k,zf] = filter(b, 1, v);
k(na+1:na+2-1) = zf;
P = find(k==1);
L = find(k==-1)-P;
LP = [max(L) P(L==max(L))];
tfr = [false(1,LP(1,2)-threshold) true(1,LP(1,1)+2*threshold) false(1,length(my)-sum(LP)-threshold)];
clipedImg = useImg(tfr,tfc);
Thanks!
11 Kommentare
Matt Kindig
am 13 Aug. 2013
Can you post a sample image as well for us to test with?
dpb
am 13 Aug. 2013
Looks like lots of sort and find operations--they're certainly time-consuming.
BUT, have you profiled it to confirm where the bottleneck really are? There's no point in just random attempts at optimization by code changes until you know where the time is being spent.
After that, in general the real gains in speed are virtually always "algorithm, algorithm, algorithm". Suggest you post what the actual processing objective is in definitive descriptive prose -- that has better chance of promoting a more useful direction of discussion on how to implement that more efficiently than having somebody just look at undocumented code.
Chris E.
am 13 Aug. 2013
Chris E.
am 13 Aug. 2013
dpb
am 13 Aug. 2013
I still think it would be more productive to describe the desired algorithm instead...
Chris E.
am 13 Aug. 2013
I'm no image processor...would seem if you can't figure out alternate algorithm to minimize the amount of processing further the way to get speed would be
a) faster processor,
b) mex what you have
(not necessarily in that order)
What's the specific operational definition of " the image of the beam cropped"?
But, isn't the centroid always going to be
[mx,imx]=max(image(:));
[i,j]=sub2ind(size(useImg),imx);
?
That's still a time-consuming MAX, but only one, not multiple and no additional SORTs, FINDs, etc., ...
Then, the more specifics you can provide re: the bounds on what is the range in the image over which you have to operate the better.
Basically, given that image, (again as no imager; never done any "in anger" in 40+ yr career) I'd use the above starting point then look for first crossing below some threshold to the l/r and u/d to find the range boundaries and use that instead of the whole thing. How much more you need will depend on how noisy the input is, basically.
Does the beam size/shape change markedly or only the centroid position? And can it be anywhere in the frame from one to the next or is it going to be somewhere near where was last time once find it the first image? IOW can you not bound the search significantly and update location incrementally rather than start from scratch every cycle?
Chris E.
am 14 Aug. 2013
Akzeptierte Antwort
Weitere Antworten (1)
My simple-minded solution -- undoubtedly will need some robustness added, but try adding sophistication to something as trivial as the following for a first cut...
[mx,imx]=max(image(:)); % find the max point as center
[i,j]=sub2ind(size(useImg),imx); % turn into row, column
lvl=0.05*mx; % a cutoff threshold
% left/right and upper/lower bounds enclosing that level around max
L=find(useImg(i,1:j)>lvl,1,'first');R=find(useImg(i,j:end)<lvl,1,'first')+j;
U=find(useImg(1:i,j)>lvl,1,'first');B=find(useImg(i:end,j)<lvl,1,'first')+i;
imClip=useImg(U:B,L:R); % the bounded image
image(imClip)
As my previous suggestion, I would think that even if take more sophistication the first time, after that if the beam can't be just anywhere you could limit the area over which you have to do the max to a fairly small region and thereby make it quite a lot smaller area for the search and thus be able to add more robustness over a smaller area to gain compute speed.
Then again, if the signal is pretty robust, maybe something as trivial as just doing the bounding on a strip P pixels wide centered on the max location instead of a single row/column as here would do it. Again, I'm no ImageAnalyst by any stretch...
2 Kommentare
Chris E.
am 14 Aug. 2013
dpb
am 15 Aug. 2013
If the size of the beam image is relatively constant I'd think you could take the overall max, then look at an area around it of fixed size and pick a group of points within some relatively small tolerance of that value. From those you ought to be able to get a band in each direction from which you can do the bounding instead of the single line as I illustrated. Overall, however, this could be only a very small fraction of the overall image size which has to help speed.
Then, one thing you might note -- if you do use the diff() approach, it works well if you first subtract a threshold between the noise levels of the min and max and use sign() on that result. Then diff(sign(x-th)) leaves you w/ +/-2 at the zero crossings.
Kategorien
Mehr zu Image Processing Toolbox finden Sie in Hilfe-Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!