How do I fix my array indices? Error says must be positive or logical values.

169 visualizzazioni (ultimi 30 giorni)
Error:
Array indices must be positive integers or logical values.
Error in lefthalfdonutcode (line 155)
profileSums(thisDistance) = profileSums(thisDistance) + double(grayImage(row, column));
I am very beginner to matlab and I am trying to get my attached script to work.
My code is attempting to count the number of dots (using a left half donut shaped mask) over 12 (or 9 the number is arbitrary) consecutive locations evenly distributed across the image and plot the count of the content as a function of the location.
My issues are the integer values are either not logical, or not positive and my code doesn't like that. Everytime I think I fix it, some other related error pops up. I thought the issue was the mask, then the maxDistance but now i am unsure. What would you suggest to get it working? Thank you.
I'm not an artist but i have attached a drawing of what I am trying to accomplish..
I want to make 12 equal bins that segment across the image in a radial mask shape to count the (in this image) purple dots then plot them as a function of their bin locations in a graph. The count would be normalized to the bin area so that the counts in the different bins can be comparable. once I get the code working to do that i think I can finish it up but i have been stuck for weeks on this part and would appreciate help because to me it is not trivial!! Thanks. -N.

Risposta accettata

Neo
Neo il 3 Mar 2023
Thank you everyone especially @Image Analyst and @Walter Roberson i finally got it to work.

Più risposte (3)

Image Analyst
Image Analyst il 28 Feb 2023
I gave you a program for when the zones were 12 vertical rectangles in your other post. Why do you need annular zones now? I see nothing in the image you posted that would indicate annular zones were what you should use.
And, like I said before, when you post stuff like this you need to post the original image and not just the annotated/marked-up one.
If you do want annular zones, you'd need to specify the center of the circles so the zones can be properly computed.
  7 Commenti
Neo
Neo il 1 Mar 2023
Here is a flow chart of what i am trying to make my code perform:
+-----------------+
| Original Image |
+--------+--------+
|
|
+--------v--------+
| Subtract |
| Background |
+--------+--------+
|
|
+--------v--------+
| Gaussian Filter |
+--------+--------+
|
|
+--------v--------+
| Threshold |
+--------+--------+
|
|
+--------v--------+
| Binarization |
+--------+--------+
|
|
+--------v--------+
| Masking |
+--------+--------+
|
|
+--------v--------+
| Count Spots |
| 12 Segments |
+--------+--------+
|
|
+--------v--------+
| Normalize to |
| Area of Bin |
+--------+--------+
|
|
+--------v--------+
| Plotting |
+--------+--------+
I attached a skeleton script (its not completly functional but hopefully it explains the path I am trying to follow clearly). The only thing besides it actually working is to input the user specified coordinates like in your radial profile program. Can you show me how you would get it functional? @Image Analyst
Neo
Neo il 2 Mar 2023
I made my code to produce angular masks but the masks is still not shaped like the way I want in the image I attached. Can you fix it to be shaped like a left half donut masks as I'm trying to do? Here is my updated code, I tried really hard and I just need a little push to get it across the finish line but I am almost there!

Accedi per commentare.


Morten Sparre Andersen
Morten Sparre Andersen il 27 Feb 2023
You need to submit more of your code before anybody can comment on what went wrong.
However a variable termed ThisDistance sounds to me as potentially non-integer. Using either floor, round or ceil could possibly be a solution. See help for floor, ceil and round to select the bes for your purpose
  2 Commenti
Neo
Neo il 27 Feb 2023
@Morten Sparre Andersen Sorry, what do you mean by more of my code? I only have the script I attached which is my full code. I also looked into the non-integer problem and came up with this:
% Scan the original image getting gray level, and scan edtImage getting distance.
% Then add those values to the profile.
for column = 1 : columns
for row = 1 : rows
thisDistance = round(sqrt((row-y)^2 + (column-x)^2));
if thisDistance <= 0 || thisDistance > maxDistance % Add a check to ensure that thisDistance is positive and within range
continue;
end
profileSums(thisDistance) = profileSums(thisDistance) + double(grayImage(row, column));
profileCounts(thisDistance) = profileCounts(thisDistance) + 1;
end
end
Even once i add it does not run all the way and the mask doesn't iterate through the image as I illustrated in the picutre. What do you suggest? Can you try to get it to wrok as intended and show me what you changed? Thanks.
Morten Sparre Andersen
Morten Sparre Andersen il 27 Feb 2023
Sorry! I didn't look for the code you included.
It is late in my part of the world. I may take a look on your code tomorrow.

Accedi per commentare.


Walter Roberson
Walter Roberson il 27 Feb 2023
thisDistance = round(sqrt((row-y)^2 + (column-x)^2));
Your x and y are 300 x 300 arrays, so (row-y) returns an array and then (row-y)^2 is matrix power -- (row-power) matrix multiplied by (row-power) . Which is permitted because it happens to be a square matrix, but probably you would want .^ instead.
The result in thisDistance would be an 2d array of distances
if thisDistance <= 0
continue;
end
so you are checking whether the 2D array of distances is <= 0 . If x and y contain only real values, then sqrt((row-y)^2 + (column-x)^2) would be non-negative -- possibly 0 but never negative -- so <= 0 would effectively be testing for == 0 (since < 0 cannot occur for reals in this situation.) Well, at least not once you repair the ^2 to be .^2 .
When you if a non-scalar, the test is considered true only if all of the values being tested are non-zero. So in order for the test to be considered true, all of the values in thisDistance would have to be non-positive, and if there is even a single positive distance then the test would be false and you would not continue
profileSums(thisDistance) = profileSums(thisDistance) + double(grayImage(row, column));
and there you are using the 2D array as indices -- but because of the mistake in the if test, you failed to reject the case where at least one value was 0 but not all of the values were 0. So you potentially have 0 as a subscript, which is not permitted.
Be further warned: the values in thisDistance will have numerous duplicates. So there will, for example, probably be about 12 places that are distance 2 away, so your code is like (for example) profileSums([3 2 2 2 3; 2 1 1 1 2]) = profileSums([3 2 2 2 3; 2 1 1 1 2]) + double(grayImage(row,column)) . This is at the very least going to cause you confusion. Should the value be added to index 2 once for each different place the distance was computed as 2? Or should the value be added to index 2 once on if at least one place computed the distance as 2? If the answer is "once for each time" then you are calculating that incorrectly. If you want "once only" then you should unique(thisDistance) to find the indices that should be incremented.
  8 Commenti
Neo
Neo il 1 Mar 2023
Modificato: Neo il 1 Mar 2023
The way where you create 12 angular masks.
Neo
Neo il 2 Mar 2023
Where in my code do I start to go two different ways? I’m going to have a good look tomorrow and see if I can fix it based on your feedback so far but if you can give me how you would fix it to check against afterwards would be awesome, thanks

Accedi per commentare.

Categorie

Scopri di più su Images in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by