Time-optimization? Digital image processing

2 次查看(过去 30 天)
Hello,
For each column of the mask, I calculate the first non-zero pixel position (2000 images). Then, I save them to an array and compute the maximum; between other simple operations.
It is working fine, but it is not at all time-efficient. Would you have any suggestion?
Thank you very much,
Best regards,
Santiago
Base= Mask;
i=1;
b= zeros (y,1,num_images,'double'); %preallocating
rows= x;
columns= y;
for k= 1:num_images;
for col= 1: columns
a = find(D(:, col,k), 1, 'first'); %find the first non-zero pixel
if a > 0
b(i,k) = a;
c = max (b(:,k));
i= i+1;
else
continue
end
end
Base(c:rows,:,k)=1; %keeping the top part
end

采纳的回答

Walter Roberson
Walter Roberson 2017-1-3
The vectorized method of finding the first non-zero pixel for each column is:
leading_zero_count = sum( cumprod( ~D ) );
This will do the operation for all columns for all images simultaneously. The output will be 1 x number_of_columns x number_of_images
This is the count of the number of leading zeros, which is not exactly the same as the location of the first non-zero pixel. For any column that has a non-zero pixel, the leading zero count will be 1 less than the position of the first non-zero pixel. For any column that does not have any non-zero pixels, the leading zero count will be the same as the number of rows, which is a non-empty value, where-as the result of find() for such a case would be [] (the empty vector). A leading zero count can be easier to work with:
D(leading_zero_count(1,J,K)+1:end, J, K)
is easy to code without having to test for the [] that find() can return.
  2 个评论
Santi
Santi 2017-1-3
Dear Walter Roberson,
Your approach works fine (just in few seconds) and of course I accept your answer.
However, I do not fully understand how the sum of the cumulative product acts in a logical matrix (in my opinion, the cumulative product of 0*1= 0). If posible, could you please elaborate on that very briefly? Thank you very much for your help!
Regards
Base= D;
rows= x;
leading_zero_count = sum( cumprod( ~D ) );
leading_zero_count(leading_zero_count==rows)=0;
leading_zero_count=leading_zero_count+1;
a= zeros (1,num_images); %preallocating
tic;
for k= 1:num_images;
a(:,k)= max (leading_zero_count(:,:,k));
Base(a(k):rows,:,k)=1; %keeping the top part
end
disp(['Elapsed time (topLine) = ',num2str(toc),' seconds']);
figure, imshow3D (Base);

请先登录,再进行评论。

更多回答(1 个)

Image Analyst
Image Analyst 2017-1-3
编辑:Image Analyst 2017-1-3
It looks like you're finding the lowest of the top-most pixels in each image and then setting Base array from that row downwards to 1. Well you don't have to do that setting of the Base matrix for each and every column. It can be done once, after the col loop ends. Inifialize c to -inf inside the k loop but before the col loop starts.
c = -inf;
Then set c like this:
c = max ([c ; b(:,k))];
Also, you should use
if ~isempty(a)
rather than
if a > 0

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by