Searching a matrix for duration value and replacing else

I have a 1600 X 821 matrix that is full of 1 and 0's that makes a binary image. I am trying to make a statement that will cycle through each column and find a series of 0's d (duration) long and then replace all other 0's in the column with 1's regardless of if there are more series of 20 zeroes later and move on to the next column. What I have doesn't work, but here's what I have so far.
k=0;
while (1+k:d+k);
if matrix(1+k:d+k);
else matrix(1+k)= 1;
end
k=k+1;
end
Thanks

 採用された回答

Andrei Bobrov
Andrei Bobrov 2012 年 10 月 14 日
編集済み: Andrei Bobrov 2012 年 10 月 14 日

0 投票

use function regionprops from Image Processing Toolbox
a - your array with size < 1600 x 821 >
out = ones(size(a))
for jj = 1:size(a,2)
s = regionprops(~a(:,jj),'Area','PixelIdxList');
out(s(find([s.Area] >= 20,1,'first')).PixelIdxList,jj) = 0;
end
or without Image Processing Toolbox
n = 20;
out = ones(size(a));
t = conv2(0+~a,ones(n,1),'same') == n;
q = fix(n/2);
ii = bsxfun(@plus,find(cumsum([false(1,size(a,2));diff(t)~=0]) == 1),-q+~rem(n,2):q);
out(ii) = 0;
ADD
n = 20;
out = ones(size(a));
for jj = 1:size(a,2)
s = regionprops(~a(:,jj),'Area','PixelIdxList');
ii = [s(find([s.Area] >= n,1,'first')).PixelIdxList];
if ~isempty(ii), out(ii(1),jj) = 0; end
end
or
n = 20;
out = ones(size(a));
t = conv2(0+~a,ones(n,1),'same') == n;
[ii,jj] = find(t);
[i00,i0] = unique(jj,'first');
out(sub2ind(size(a),ii(i0),i00) -fix(n/2)+~rem(n,2) ) = 0;

13 件のコメント

Matthew
Matthew 2012 年 10 月 14 日
Thank you very much, that worked!!
Matthew
Matthew 2012 年 10 月 14 日
Now if I wanted to also take that 20 long sample and pick just the first one, how would I do that?
Andrei Bobrov
Andrei Bobrov 2012 年 10 月 14 日
in part my answer with regionprops:
out(s(find([s.Area] == 20,1,'first')).PixelIdxList,jj) = 0;
Image Analyst
Image Analyst 2012 年 10 月 14 日
Matthew, I'm not sure what you mean. You have the 20 long sample - ok fine - but what does "pick just the first one" mean? The first what in the "20 long sample"? The first pixel in that "20 long sample"???
Matthew
Matthew 2012 年 10 月 14 日
I meant, I have the 20 long sample, and I want to keep the first one a "0" and make the rest "1". So now I would have a single 0 in each coloumn. Sorry about the vagueness.
Andrei Bobrov
Andrei Bobrov 2012 年 10 月 14 日
see ADD in my answer
Matthew
Matthew 2012 年 10 月 14 日
ALright, so now when I try the ADD part I get this error.
??? Too many outputs requested. Most likely cause is missing [] around left hand side that has a comma separated list expansion.
Error in ==> at 67 ii = s(find([s.Area] == n,1,'first')).PixelIdxList;
Andrei Bobrov
Andrei Bobrov 2012 年 10 月 14 日
corrected
Matthew
Matthew 2012 年 10 月 14 日
Sorry, now I get this error message.
??? Attempted to access ii(1); index out of bounds because numel(ii)=0.
Error in ==> at 68 TWTT_200(ii(1),jj) = 0;
Andrei Bobrov
Andrei Bobrov 2012 年 10 月 14 日
corrected
Image Analyst
Image Analyst 2012 年 10 月 14 日
Matthew, seems like an odd thing to want to do, but anyway, see the code in my answer which will do that. It makes a binary (logical) image all 1 (true) except at the pixel of the first row in each column that starts off a stretch of 20 or more 0's (false's).
Matthew
Matthew 2012 年 10 月 14 日
Now I just get a grey image.
Matthew
Matthew 2012 年 10 月 14 日
I tried the second one without the region props and that worked

サインインしてコメントする。

その他の回答 (1 件)

Image Analyst
Image Analyst 2012 年 10 月 14 日

0 投票

Matthew, try this:
clc;
format compact
%==============================================
% Make sample data.
% Make a 100 row by 4 columns image
binaryImage = true(100, 4);
% Place 30 random zeros around in it.
randomLocations = randperm(numel(binaryImage));
binaryImage(randomLocations(1:30)) = false;
% Put 2 stretches of zeros at least 20 long in each column
binaryImage(3:22, 1) = false;
binaryImage(33:62, 1) = false;
binaryImage(13:33, 2) = false;
binaryImage(73:92, 2) = false;
binaryImage(23:52, 3) = false;
binaryImage(63:86, 3) = false;
binaryImage(43:74, 4) = false;
binaryImage(81:100, 4) = false;
% Display it in the command window:
binaryImage
% Create an output image
output = true(size(binaryImage))
%=======================================
% Now, finally, we have our sample data and we can begin.
for column = 1 : size(binaryImage, 2)
% Find the zeros.
% This is a map that is true where there is a 0 (false)
zeroLocations = ~binaryImage(:, column);
% Get rid of stretches 19 or less
zeroLocations = bwareaopen(zeroLocations, 20);
% Find the first zero of the first 20+ long stretch
% of zeros in this column.
firstZeroRow = find(zeroLocations, 1, 'first')
% Set that one single pixel to 0 in the output image.
output(firstZeroRow, column);
end
% Display it in the command window:
output
% It will be all true (1's) except for pixel 3, 13, 23, and 43
% in columns 1, 2, 3, and 4 respectively.

11 件のコメント

Matthew
Matthew 2012 年 10 月 14 日
I get this message from this code.
??? Undefined function or method 'output' for input arguments of type 'double'.
Error in ==> at 74 output(firstZeroRow, column);
Matthew
Matthew 2012 年 10 月 14 日
oh sorry, one sec
Matthew
Matthew 2012 年 10 月 14 日
now I get a grey picture for this too.
Image Analyst
Image Analyst 2012 年 10 月 14 日
編集済み: Image Analyst 2012 年 10 月 14 日
You didn't copy and paste my code - I know that much. You'd have to show your modifications for me to know how you broke it. For example, you're not using a true binary (logical) image but instead are using your own image which is of type double.
Matthew
Matthew 2012 年 10 月 14 日
You're right, it's not a binary image, it's an 8-bit image and I ran it through a threshold function to turn all values into 1's and 0's and then inverted the image.
Image Analyst
Image Analyst 2012 年 10 月 14 日
OK, let me change my code to reflect your non-binary image. It is below:
clc;
format compact
%==============================================
% Make sample data.
% Make a 100 row by 4 columns image
binaryImage = ones(100, 4, 'uint8');
% Place 30 random zeros around in it.
randomLocations = randperm(numel(binaryImage));
binaryImage(randomLocations(1:30)) = 0;
% Put 2 stretches of zeros at least 20 long in each column
binaryImage(3:22, 1) = 0;
binaryImage(33:62, 1) = 0;
binaryImage(13:33, 2) = 0;
binaryImage(73:92, 2) = 0;
binaryImage(23:52, 3) = 0;
binaryImage(63:86, 3) = 0;
binaryImage(43:74, 4) = 0;
binaryImage(81:100, 4) = 0;
% Display it in the command window:
binaryImage
% Create an output image
output = ones(size(binaryImage), 'uint8')
%=======================================
% Now, finally, we have our sample data and we can begin.
for column = 1 : size(binaryImage, 2)
% Find the zeros.
% This is a map that is 1 where there is a 0
zeroLocations = ~binaryImage(:, column);
% Get rid of stretches 19 or less
zeroLocations = bwareaopen(zeroLocations, 20);
% Find the first zero of the first 20+ long stretch
% of zeros in this column.
firstZeroRow = find(zeroLocations, 1, 'first')
% Set that one single pixel to 0 in the output image.
output(firstZeroRow, column) = 0;
end
% Display it in the command window:
output
% It will be all 1's except for pixel 3, 13, 23, and 43
% in columns 1, 2, 3, and 4 respectively.
Matthew
Matthew 2012 年 10 月 14 日
that worked
Image Analyst
Image Analyst 2012 年 10 月 14 日
Why do you want to do this somewhat unusual thing anyway?
Matthew
Matthew 2012 年 10 月 14 日
My "image" was from a sonar. So the "line" I was making was a 2D picture of the ocean floor while trying to get rid of all the noise.
Image Analyst
Image Analyst 2012 年 10 月 15 日
Do you think it could be even better by using the fact that adjacent columns may be correlated?
Matthew
Matthew 2012 年 10 月 15 日
That is true. But for my purposes at the moment, i didn't have to worry too much about that.

サインインしてコメントする。

Community Treasure Hunt

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

Start Hunting!

Translated by