Find sorrunding elements and element from an array
1 次查看(过去 30 天)
显示 更早的评论
I have an array
y = [
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0]
where Index 7,41,75 are the locations where 1 is found .
My requirement is
- create a block around true(1) with a size of 5
- get the indices like 5,6,7,8,9 and data 0 0 1 0 0
25 个评论
Walter Roberson
2020-10-26
What shoud the output be if you have nearby pixels? For example
y = [
0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
0 0 0 0 0 0 0 0 0]
Life is Wonderful
2020-10-26
- include the nearby pixel as well in the block of 5 elements
- if first pixel 1 then include next 4 elements
- if end pixel 1 then include previous 4 elements
Walter Roberson
2020-10-26
So to confirm, you would want [0 0 1 0 1] indices [5 6 7 8 9] and [1 0 1 0 0] indices [7 8 9 10 11] ?
Anyhow, what is your question?
Life is Wonderful
2020-10-26
编辑:Life is Wonderful
2020-10-26
So to confirm, you would want [0 0 1 0 1] indices [5 6 7 8 9] and [1 0 1 0 0] indices [7 8 9 10 11] ?
[0 0 1 0 1]
5 6 7 8 9 ==> Block 1
[1 0 1 0 0]
[7 8 9 10 11] ==> Block 2
we don't need block2 if the indices is in Block 1 . Index repeatation will consume memory and processing time increases.
And more so first indices and last indices should be 1st Indcie + 4(next ) & Last indice - 4 (previous)
Walter Roberson
2020-10-27
we don't need block2 if the indices is in Block 1
So you want a single combined output that is longer, block1 = [0 0 1 0 1 0 0] indices [5 6 7 8 9 10 11] ?
Walter Roberson
2020-10-27
You appear to be doing a homework assignment. When I read the homework assignment, I am left certain that you are intended to always produce blocks of 5. Index duplication and memory consumption is not a primary concern: the block of 5 is imposed by the question.
As such, there is a much easier solution to finding the indices. Hint: find() and min() and max() . You can calculate the starting and ending indices in vectorized form.
Once you have vectors of the starting and ending indices, you can loop or arrayfun to extract the contents.
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
You have a mis understing ! The requirement is
- Block is needed as an input to process the polynomial vector.
- movmax makes the poly bit as 1 .. This is incorrect since it over write poly error information
- A block can start from 1 bit as 1 and trail bit either 0/1 .
- In case of variable block/s, you know the CRC points in a data set then why re-run same data. This is using more memory (buffer) and processs time. I don't understand why this should not be concern
It will be a help to have a very simple code/algorithm if you can share just to have as a starting point,
I shared a sample code below, can you please add more robust logic to get desired results.
Thank you!
Walter Roberson
2020-10-27
start = max(1, position-2);
stop = start + 4;
Now do the fix-up for end of buffer.
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
For end bit , I think padding is needed
For example
y1 = [1 0 0 0 0 ]
y2 = [0 1 0 0 0 ]
y3 = [0 0 1 0 0 ] & so on
to accomadate the block size fit the fixed polynomial size
Walter Roberson
2020-10-27
No, padding is not needed, as long as the length of the input vector y is not less than the blocksize (5)
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
OK, we can do the reverse count from end and put the previous bit in to the array
y = [ 0 0 0 0 0 0 0 0 1 0]
position is 9 then ?
I expect the result should be
blockBits(:,:,1) = [1,0,0,0,0]
blockindcs(:,:,1) = [9, 10, 8,7,6]
Walter Roberson
2020-10-27
No need to do reverse indices.
Think about the code I posted:
start = max(1, position-2);
stop = start + 4;
We started at some unknown position. We go blocksize/2 towards an edge that is of interest to us, which would normally get us the location of the edge. But we check whether taking that step would have positioned that tentative edge beyond the actual edge, and if it did then we substitute the coordinate of the actual edge instead. Then we take that (possibly substituted) coordinate and say that the other end of the block is the blocksize towards the other edge.
It is trivial to extend this to do the same logic against the other edge, detecting if we have passed the actual edge and if so moving the boundary to the actual edge and saying that the other end of the block is blocksize towards the front.
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
No no.. this is wrong explanation for edge detection
As per your logic ,
start = max(1, position-2);
stop = start + 4;
we don't know what is the error value at start but position define error.If you train
a edge detection polynomial with leading edge with non error bit. Then the logic won't make
sense
Below is an example
Leading bit can be 0.
a = [ 1 0 0 0 1 ]; sys = idpoly(a)
sys =
Discrete-time AR model: A(z)y(t) = e(t)
A(z) = 1 + z^-4
Sample time: unspecified
Parameterization:
Polynomial orders: na=4
Number of free coefficients: 4
Use "polydata", "getpvec", "getcov" for parameters and their uncertainties.
Status:
Created by direct construction or transformation. Not estimated.
K>> a = [ 0 0 0 0 1 ]; sys = idpoly(a)
Error using idpoly (line 384)
The leading coefficient of the "A" polynomial must be 1.
But for a polynomial leading position must 1 and tail bits can be 0/1. What if block started with 0. So edge detection will not proceed at the initial state.
For the end block , it is Ok to process 1-4 to additional bits to go pass the edge unless we have a conving logic
as I proposed
- bit reverse
- padd to sufice the block which is a polynomial
- short polynomial
for a block to process for edge detection. The problem with Short polynomial size than a block size then we have size error...
Please have re look into below code and suggest solution for ( I prefer to have offset elements to have 0 filled , then we don't alter edge detection error bit and it will be safe)
if bit_position>= (siz_y-blksize)
blockBits(:,:,i) = y(bit_position:1:siz_y);
blockindcs(:,:,i) = (bit_position:1:siz_y);
end
Current implementation with a bad size for end block
y = [
0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...
0 0 0 0 0 0 0 1 0]
siz_y = size(y,2);
[Val,idx] = find(y>0);
blksize = 5;
blockBits = zeros(1,blksize,size(idx,2));
blockindcs = zeros(1,blksize,size(idx,2));
statelock = 0;
yMax = movmax(y, blksize);
props = regionprops(yMax > 0, 'PixelIdxList'); % Requires the Image Processing Toolbox.
for i = 1:size(idx,2)
bit_position = idx(i);
% blockBits(:,:,i) = y(props(i).PixelIdxList);
% blockindcs(:,:,i) = props(i).PixelIdxList;
% start = max(1, bit_position-2)
% stop = start + 4
% blockBits(:,:,i) = y(start:1:stop)
% blockindcs(:,:,i) = (start:1:stop)
if (bit_position>blksize) && bit_position< (siz_y-blksize)
blockBits(:,:,i) = y(bit_position:1:bit_position+4);
blockindcs(:,:,i) = bit_position:1:bit_position+4;
end
if bit_position<=blksize
blockBits(:,:,i) = y(bit_position:1:bit_position+4);
blockindcs(:,:,i) = bit_position:1:bit_position+4;
end
if bit_position>= (siz_y-blksize)
% bit_position = 100,
% siz_y = 101
% offset = 3
% Fill blockindcs offset & substitute with 0's
% 97 98 99 100 101
% blockindcs = 100 101 99 98 97
% blockBits = 1 0 0 0 0
blockBits(:,:,i) = y(bit_position:1:siz_y); % fill offset with 0's
blockindcs(:,:,i) = (bit_position:1:siz_y);
end
end
Walter Roberson
2020-10-27
All that stuff is irrelevant. You gave the definition at https://www.mathworks.com/matlabcentral/answers/626663-find-sorrunding-elements-and-element-from-a-array#comment_1087903
Though you did omit the definition for the case [0 1 x x x]
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
My apologies,
so what is the proposal for [0 1 x x x] & it's permutation ?
Adam Danz
2020-10-27
Trying to catch up, here.
What doesn't work from this approach?
% Create example input with true at 7,9,41,75
y = false(1,101);
y([7,9,41,75]) = true
y = 1x101 logical array
0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
% Pad 2 false values to the beginning and end
ypad = [false(1,2), y, false(1,2)];
% Find locations of True
I = find(ypad(:)')
I = 1×4
9 11 43 77
●
% Remove any values of I closer than 2-units
I([false,diff(I)<=2]) = []
I = 1×3
9 43 77
●
% Isolate each true-value +/-2 to the right/left
% and remove the effect of padding
A = find(ypad(:)) + (-4:0)
A = 4×5
5 6 7 8 9
7 8 9 10 11
39 40 41 42 43
73 74 75 76 77
●
B = ypad(A+2)
B = 4x5 logical array
0 0 1 0 1
1 0 1 0 0
0 0 1 0 0
0 0 1 0 0
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
Hi Adam,
If we see the B out put we have 4 rows and 5 column.
Each row is a polynomial with a size of 5 ( column). I consider it as block size ( so 4 blocks with polynomial size of 5)
What is not OK in the output B is , starting element is NOT 1 and this will lead to coefficient of the polynomial must be 1 error )
Note: Important point is , we have to keep the polynomial size same (so that I don't have to change the degree of polynomial ) and run the polynomial data having error bits.
So we have to re work the logic !
Thank you
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
Please see the figure,
C - represent , no data & it has a dimension of 3x5 . We dont have to run a error polynomial coeff , so removing.I am looking this solution.
For indices location
A to A' is improvement
A to C' is final expectation
For logical values
B to B' is improvement
B to C' is final expectation
Adam Danz
2020-10-27
I'm still having trouble extracting the set of rules to follow to get the expected matrix. Maybe those rules are scattered about in this thread and I haven't seen them. For example, why would the first row of A' be [7 8 9 6 5]?
Life is Wonderful
2020-10-28
You have A_idx = [5 6 7 8 9] but expectation is A'_idx = [7 8 9 6 5]
You have A_idx = [0 0 1 0 1] but expectation is A'_bits = [1 0 1 0 0]
Rules:
- The first / every row must start with error bit location followed by rest of bit. i.e. leading coefficeint of a the polynomial must be 1
- Tail bits of a polynomial can be any 0/1 in a block size( we get in the array). Bitreversal is done for 5,6 to 6,5
- Once a error bit is processed in a block , we don't need to processs the bit again. Block window should slide further in search of next index / error bit to make a polynomial of fixed size
- Minimum polynomial size i.e. block of 5 is reasonable .
- polynomial size should not change during the execution.
Thank you!
Life is Wonderful
2020-11-19
Hi Adam,
Can you please help me wtih below issue ?
https://www.mathworks.com/matlabcentral/answers/653278-detect-overflow-for-full-range-and-resolution
Thank you!
采纳的回答
Image Analyst
2020-10-26
Try this:
fprintf('Beginning to run %s.m ...\n', mfilename);
y = [
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0]
yMax = movmax(y, 5)
props = regionprops(yMax > 0, 'PixelIdxList') % Requires the Image Processing Toolbox.
for k = 1 : length(props)
fprintf('\nFor block #%d, indexes = ', k);
indexes{k} = props(k).PixelIdxList;
fprintf('%d ', indexes{k});
end
fprintf('\nDone running %s.m ...\n', mfilename);
You'll see:
For block #1, indexes = 5 6 7 8 9
For block #2, indexes = 39 40 41 42 43
For block #3, indexes = 73 74 75 76 77
11 个评论
Life is Wonderful
2020-10-26
编辑:Life is Wonderful
2020-10-26
==================================================================
Your code will NOT work in case first elemet is set to 1. The block size will be reduced to 3 instead of 5 and this does not fit anymore to a predefined block size ( as you took 5 in movmax fcn)
For block #1, indexes = 1 2 3 ==> Bug "doesn't fit in a block"
For block #2, indexes = 5 6 7 8 9
For block #3, indexes = 39 40 41 42 43
For block #4, indexes = 73 74 75 76 77
Done running .m ...
Probably You have to change properties of movmax fcn
==================================================================
Looks good! Since I don't have a image processing toolbox to work on. Could you please help in imroving the below code?
siz_y = size(y,2);
[Val,idx] = find(y>0);
blockBits = zeros(1,5,size(idx,2));
blockindcs = zeros(1,5,size(idx,2));
for i = 1:size(idx,2)
a = idx(i);
if a>1 && a< siz_y
blockBits(:,:,i) = y(a-2:1:a+2);
blockindcs(:,:,i) = a-2:1:a+2;
elseif a==1
blockBits(:,:,i) = y(a:1:a+4);
blockindcs(:,:,i) = (a:1:a+4);
elseif a== siz_y
blockBits(:,:,i) = y(a-4:1:a);
blockindcs(:,:,i) = (a-4:1:a);
end
end
Image Analyst
2020-10-26
Are you sure? It's got to be the most common toolbox out there. I know it is here in Answers. Type ver on the command line to check.
If not, use find() to get the indexes of the 1's, and then use findgroups() to identify the separate blocks of them.
Life is Wonderful
2020-10-27
Thanks- can you please correct the error as I shared below
The code will NOT work in case first elemet is set to 1.
The block size will be reduced to 3 instead of 5 and this does not fit anymore to a predefined block size ( as you took 5 in movmax fcn)
For block #1, indexes = 1 2 3 ==> Bug "doesn't fit in a block"
For block #2, indexes = 5 6 7 8 9
For block #3, indexes = 39 40 41 42 43
For block #4, indexes = 73 74 75 76 77
Image Analyst
2020-10-27
编辑:Image Analyst
2020-10-27
So did you end up using my code? Or did you change it to use findgroups()? If so, attach that code.
If you're able to use the Image Processing Toolbox, you can use bwareaopen() to get rid of regions less than 5 in length:
fprintf('Beginning to run %s.m ...\n', mfilename);
y = [
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0]
yMax = movmax(y, 5) > 0; % A logical vector.
yMax = bwareaopen(yMax, 5); % Keep runs of 5 or longer ONLY.
props = regionprops(yMax, 'PixelIdxList') % Requires the Image Processing Toolbox.
for k = 1 : length(props)
fprintf('\nFor block #%d, indexes = ', k);
blockIndexes{k} = props(k).PixelIdxList;
fprintf('%d ', blockIndexes{k});
end
fprintf('\nDone running %s.m ...\n', mfilename);
You'll see
For block #1, indexes = 5 6 7 8 9
For block #2, indexes = 39 40 41 42 43
For block #3, indexes = 73 74 75 76 77
Life is Wonderful
2020-10-27
编辑:Life is Wonderful
2020-10-27
Looks pretty good, But still improvement is required. Following Issues are observed & listed below
For block #1, indexes = 5 6 7 8 9
For block #2, indexes = 39 40 41 42 43
For block #3, indexes = 73 74 75 76 77
Issue -1:
Starting index is expected to be error bit i.e.I am expecting like below
For block #1, indexes = 7 8 9 6 5
For block #2, indexes = 41 42 43 40 39
For block #3, indexes = 75 76 77 74 73
Issue -2:
There is also a case where we have higher than block size is achieved. This mean higher polynomial order. This will NOT fit into pre-allocated buffer
[For block #1, indexes = 1 2 3 4 5 6 7 8 9 ]
Issue -3:
In case , if I modify y = errors positions(set to 1), I don't get the required output, For example, You can give a try by setting 1 and 101 locations ,
For block #1, indexes = 5 6 7 8 9
For block #2, indexes = 39 40 41 42 43
For block #3, indexes = 73 74 75 76 77
Done running .m ...
>> find(y>0)
ans =
1 7 41 75 101
Also please keep "bwareaopen" function c code translation, coder support is needed for c/c++ code generation, otherwise it is pretty difficult to implement on a 32 bit processor.
Thank you!
Image Analyst
2020-10-27
What is the case where you had indexes 1-9? What do you expect to happen if you have 1's that are closer than 5 elements? Is the solution to just add 2 to all the indexes? Area you saying that bwareaopen() is a function that is explicitly not included in the MATLAB Coder Toolbox?
Life is Wonderful
2020-10-28
- What is the case where you had indexes 1-9?
In case - data altered for testing & verification
y = [
0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 1]
props =
3×1 struct array with fields:
PixelIdxList
For block #1, indexes = 1 2 3 4 5 6 7 8 9
- What do you expect to happen if you have 1's that are closer than 5 elements?
It's OK and they may be , after all 1 are the error bits. The expectation is , we should have constant block size and we don't need to process the already processed error bit in a block . Block must start with a error bit ( leading coefficient of a the polynomial must be 1). And block size should not change. In case block does
not accomadete all error bit, then process the error bit in next block . We should not repeat the already processed error bit.
- Is the solution to just add 2 to all the indexes?
No. If I understood your question correctly , you say adding/pad 2 additional bits. then my answer is you can do but finally we are not altering the output
- Area you saying that bwareaopen() is a function that is explicitly not included in the MATLAB Coder Toolbox?
No. I am saying bwareaopen(), I have to write the c code that might be difficult for me if i don't understand the details of bwareaopen()
Image Analyst
2020-10-29
You said "Also please keep "bwareaopen" function c code translation, coder support is needed for c/c++ code generation, otherwise it is pretty difficult to implement on a 32 bit processor." so I was assuming that you needed the whole program to be converted to C code with the Coder Toolbox because you were going to embed this algorithm in a custom chip on some device. If you don't need Coder support and are not going to generate C code, then I don't know why you said that. Please elaboarate. Also, I don't know that Coder can generate code for 32 bit processors. I know MATLAB stopped supporting 32 bit processors with version 2016b.
If you want
For block #1, indexes = 7 8 9 6 5
For block #2, indexes = 41 42 43 40 39
For block #3, indexes = 75 76 77 74 73
then you can just tack on the first two indexes to the end, like this:
fprintf('Beginning to run %s.m ...\n', mfilename);
y = [
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...
0 0 0 0 0 0 0 0 0]
windowWidth = 5;
halfWindowWidth = floor(windowWidth/2);
yMax = movmax(y, windowWidth) > 0; % A logical vector.
yMax = bwareaopen(yMax, windowWidth); % Keep runs of 5 or longer ONLY.
props = regionprops(yMax, 'PixelIdxList') % Requires the Image Processing Toolbox.
for k = 1 : length(props)
fprintf('\nFor block #%d, indexes = ', k);
theseIndexes = props(k).PixelIdxList';
blockIndexes{k} = [theseIndexes(end-halfWindowWidth : end), fliplr(theseIndexes(1:halfWindowWidth))];
fprintf('%d ', blockIndexes{k});
end
fprintf('\nDone running %s.m ...\n', mfilename);
It prints out:
For block #1, indexes = 7 8 9 6 5
For block #2, indexes = 41 42 43 40 39
For block #3, indexes = 75 76 77 74 73
Life is Wonderful
2020-11-8
Thank you! I'II update further with my comments on your queries with additional information. For the time being this is sufficient
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)