필터 지우기
필터 지우기

Find the average between each pair of points in a matrix

조회 수: 17 (최근 30일)
JIAN-HONG YE ZHU
JIAN-HONG YE ZHU 2023년 4월 11일
댓글: Joe Vinciguerra 2023년 4월 13일
Hello, I have a 61x61 random generated double matrix, I want to calculate the average between each point in a row of a column, and after going through all the rows in that column and calculating their corresponding averages, go to the next column.
If the average is >= 2 or <= -2 I would like to then set that data point to 1, otherwise set it to 0.
I managed to do this using for loops and if statements, but how would I do this using a vectorized approach?
I attatch what I have right now for reference.
Thanks.
Edit: Forgot to add, I would like to then, find the average between each point horizontally (what I stated above was vertically) so averaging between points in the 1st row and all columns, and then going to the 2nd row and so on. The average criteria is the same but if previously the data point is set to 1 and now it was calculated to be 0, keep it as 1, and if it was 0 and now was calculated as 1, then overwrite it to 1.
(I included two images to show what I mean by averaging horizontally and vertically.)

채택된 답변

Joe Vinciguerra
Joe Vinciguerra 2023년 4월 11일
편집: Joe Vinciguerra 2023년 4월 11일
I'm a little unclear on the specifics, but I think this is basically what you want:
z = randi([-5 5],61,61,'double')
zMeanV = movmean(z, [0 1], 1)
zMeanVH = movmean(zMeanV,[0 1], 2)
avgMap = or(zMeanVH >= 2, zMeanVH <= -2)
[edit]
After re-reading your post and looking closer at your code, it sounds like it should be more like this:
z = randi([-5 5],61,61,'double');
zMeanV = movmean(z, [0 1], 1);
zMeanV(end,:) = zMeanV(end-1,:);
avgMapV = or(zMeanV >= 2, zMeanV <= -2);
zMeanH = movmean(z,[0 1], 2);
zMeanH(:,end) = zMeanH(:, end-1);
avgMapH = or(zMeanH >= 2, zMeanH <= -2);
avgMap = or(avgMapV, avgMapH)
  댓글 수: 7
JIAN-HONG YE ZHU
JIAN-HONG YE ZHU 2023년 4월 13일
Sorry for that silly mistake. The context to the 'random matrix' (which I used to ask the question) is that the actual matrix is intended to be filled with points in a position of a map, and the value of each point is the height of that point in the map.
By calculating the average between points, then I could see whether it is feasible or not for a vehicle to go from two certain points, so if the average surpasses certain value, it means a vehicle could not drive through it, or it's a cliff (-4 4...).
That being said, I realized if I want this I should instead calculate the gradient instead which would be more relevant to this.
Thank you very much for your help I appreciate it
Joe Vinciguerra
Joe Vinciguerra 2023년 4월 13일
A 2D gradient() of the entire array definately seems to make more sense for the application. Cheers!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

dpb
dpb 2023년 4월 11일
편집: dpb 2023년 4월 11일
I'd do it as
z=randi([-5 5],8)
z = 8×8
-4 -1 0 5 -5 -4 0 5 -1 -2 5 -1 -5 0 2 -4 1 -1 -1 -5 -4 -3 -1 3 2 5 -4 4 4 -1 -1 -2 4 1 -3 4 -3 2 1 2 -4 -5 0 5 -4 5 -1 1 4 0 0 -1 5 5 -4 1 -1 5 -2 5 -4 -4 1 -2
za=filter2(ones(2)/4,z) % averaging 2D filter with same size as input (zero padded)
za = 8×8
-2.0000 0.5000 2.2500 -1.5000 -3.5000 -0.5000 0.7500 0.2500 -0.7500 0.2500 -0.5000 -3.7500 -3.0000 -0.5000 -0.0000 -0.2500 1.7500 -0.2500 -1.5000 -0.2500 -1.0000 -1.5000 -0.2500 0.2500 3.0000 -0.2500 0.2500 2.2500 0.5000 0.2500 -0.0000 -0.0000 -1.0000 -1.7500 1.5000 0.5000 0.0000 1.7500 0.7500 0.7500 -1.2500 -1.2500 1.0000 1.2500 2.7500 1.2500 -0.7500 0.5000 2.0000 0.7500 0.5000 1.2500 0.5000 -0.5000 -1.0000 -0.2500 1.0000 0.7500 0.7500 0.2500 -2.0000 -0.7500 -0.2500 -0.5000
zv=filter2(ones(2)/4,z,'valid') % keep only non-padded elements
zv = 7×7
-2.0000 0.5000 2.2500 -1.5000 -3.5000 -0.5000 0.7500 -0.7500 0.2500 -0.5000 -3.7500 -3.0000 -0.5000 -0.0000 1.7500 -0.2500 -1.5000 -0.2500 -1.0000 -1.5000 -0.2500 3.0000 -0.2500 0.2500 2.2500 0.5000 0.2500 -0.0000 -1.0000 -1.7500 1.5000 0.5000 0.0000 1.7500 0.7500 -1.2500 -1.2500 1.0000 1.2500 2.7500 1.2500 -0.7500 2.0000 0.7500 0.5000 1.2500 0.5000 -0.5000 -1.0000
Alternatively, you can choose 'valid' and get the averages only where there is no zero padding. This then returns a filtered array that is in your case over averaging over two elements, one less in each direction.
The description of the scaling is confusing, however, but by the first description, it would be
za=double(abs(za)>=2) % scales to 0, 1 based on average (throws away sign???)
za = 8×8
1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  댓글 수: 4
JIAN-HONG YE ZHU
JIAN-HONG YE ZHU 2023년 4월 12일
Thank you very much for your insight, I have one question, after reading through 2-D digital filter - MATLAB filter2 - MathWorks United Kingdom , 'filter2' has a syntax of Y = filter2(H,X), in this case, the matrix H is ones(2)/4. I do not understand how this matrix H is defined?
dpb
dpb 2023년 4월 12일
편집: dpb 2023년 4월 12일
Ir's your 2x2 averaging kernel -- multiplies each set of four locations by 1/4 and adds which is the average over the four locations. As the doc also points out, filter is just conv (convolution) with the kernel rotated 90 degrees. Since yours is symmetric, it doesn't make any difference which.
You'll note that the first case, 'Same' is padded w/ zeros on bottom and right; those values are half of the average the the last two points. Sometimes (and what your code does if my glance-thru was correct) I'll multiply that last row/column by the ratio of the kernel size and the number of padded rows/columns(*). Here, of course, with a 2x2 kernel, it just has to pad the one row/column so the multiplier is 2/1-->2. You can see that result by inspection with the integer values it's easy to add and divide by four.
In the second example, 'Valid', the result is one row/column less than the original, but there's no padding and so the last row/column of the result are full 4-element averages.
Which to use and whether to reweight or not is all dependent upon what your needs are for the result; we can't know anything about that.
(*) If you do choose to normalize the last row/column, remember to only address the lower RH corner element once; otherwise you'll end up doing it twice!

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Annotations에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by