Matlab: multidimensional array for images - arrays

I am new to the concept of multi-dimensional array and I am trying to apply it to the following image that I have:
What I would like to do is to create a 5D array as follow [number of boxes in a row, number of boxes in a column, size of each box in x, size of each box in y, RGB] in this example it would be [8, 8, 200, 200, 3].
I have written the following code to grab the pixels of the top left box (the red one) (just to test it):
Image = imread('Grid.jpg');
img = zeros(8, 8, 200, 200, 3)
img(1, 1, 1:200, 1:200, :) = Image(1:200, 1:200, :);
imshow(squeeze(img(1,1,:,:,:)))
When I run the code I only get a yellow line.
Could somebody please point out what am I doing wrong and why I am getting the result I am getting now?

Related

How to properly create outline around image using RGB values?

I have an image that I import into Octave 5.2, and I would like to create an outline all the way around the image array using RGB values.
I'm having trouble inserting the RGB values back into the array correctly, inserting / generating the two rows at top, two columns on the left, two columns on the right, and two rows on the bottom all the way around the image / converted double array.
Example of original image:
Example of the image I'm trying to get when done:
My logic was:
To convert the image to a double array so I can do math / insert the RGB values where I wanted them.
Insert the RGB values into the left, right, top, bottom of the array.
Convert the double array back to uint8 to export / view it as image.
My code so far:
pkg load image
img_fn=('https://i.imgur.com/KKxJaOy.png'); %original image
f=imread(img_fn);
[im_r im_c]=size(f);
size_min=min(im_r,im_c); %get minum size from row and col
f_double=double(f); %need to convert to double to do math functions on it
outline_left_of_box=repmat(255,[rows(f_double),2]); %Create left line array of outline red box
f_double_tmp_red(:,:,1)=[outline_left_of_box,f_double];%Create left line of outline red box
red_outline_right_of_box=repmat(255,[rows(f_double),2]); %Create right line array of outline red box
red_outline_top_of_box=repmat(255,[2,columns(f_double)]); %Create top line array of outline red box
red_outline_bottom_of_box=repmat(255,[2,columns(f_double)]); %Create bottom line array of outline red box
%convert back to image
red_outline_img=uint8(f_double);
imshow(red_outline_img); %used to show image in octave plot window
Please note: I'm converting the image array into a double because calculations will be done on the array to get the desired color box around the image, but I'm just trying to get the inserting RGB values into the array issue fixed first.
Maybe it's easier to simply paste the inner part of the input image onto some "background" image with the desired border color, like so:
pkg load image
% Read image, get dimensions, convert to double
f = imread('https://i.imgur.com/KKxJaOy.png');
[im_ro, im_co, im_ch] = size(f);
f_double = double(f);
% Set up width and color of border
bw = 2;
color = ones(1, 1, im_ch);
color(1, 1, :) = [255, 0, 0];
% Create image of same size as input with solid color, and paste inner part of input
red_outline_img = ones(im_ro, im_co, im_ch) .* color;
red_outline_img(bw+1:end-bw, bw+1:end-bw, :) = f_double(bw+1:end-bw, bw+1:end-bw, :);
red_outline_img = uint8(red_outline_img);
imshow(red_outline_img);
That'd be the output:
Another thing you could try is plot the lines as you suggest, which can be done very efficiently with some clever use of xlim/ylim, and then print the whole thing as an -RGBImage to get it back in image form.
The only caveat here though is that you will need to play with the formatting options to get what you're really after (e.g. in case you want higher or lower resolution), since you really are printing what's on your screen at this point.
E.g.
L = imread('leaf.png');
imshow(L)
hold on
plot( [xlim, fliplr(xlim);xlim, xlim], [ylim, ylim;fliplr(ylim), ylim], 'r', 'linewidth', 2 )
hold off
set( gca, 'position', [0, 0, 1, 1] );
set( gcf, 'paperposition', [0, 0, 1, 1] );
R = print( '-RGBImage' );
close
imshow(R); set( gcf, 'color', 'k'); axis off

How to plot legends for all (only 4) types of value in a 2D array using matplotlib?

I have a 2-D array where each value is either of 0,1,2,3 and I am plotting it like:
array = two_d_array #two_d_array is a numpy 2-D array
plt.imshow(array)
This gives me a plot where each pixel is represented by a color i.e. images has 4 different colors. How can I:
plot it by customizing which value (either of 0, 1 ,2, 3) corresponds to which value?
plot a legend which tells which color belongs to 0, which to 1 and so on?
This answer is very close but it chooses which color to recognize and not which value.
Any help will be appreciated!

Applying Movmedian Within Cell Array

I have a cell array (2 x 6) called "output", each cell in row #1 {1 -> 6, 2} contains a 1024 x 1024 x 100 matrix. I want to apply movmedian to each cell in row #1. I would like to apply this function in dimension = 3 with window size = 5.
output = cellfun(#movmedian(5,3), output,'uniform', 0);
This is the code that I have come up with so far, however, it produces an "unbalenced or unexpected parenthesis or bracket" error. I am unsure what is causing this error. I am also somewhat unsure how to instruct matlab to perform this operation only on row 1 of the cell array, please help!
Thank you for your time!!
The function handle passed as the first argument to cellfun will be sequentially passed the contents of each cell (i.e. each 3-D matrix). Since you need to also pass the additional parameters needed by movmedian, you should create an anonymous function like so:
#(m) movmedian(m, 5, 3)
Where the input argument m is the 3-D matrix. If you want to apply this to the first row of output, you just have to index the cell array like so:
output(1, :)
This will return a cell array containing the first row of output, with : indicating "all columns". You can use the same index in the assignment if you'd like to store the modified matrices back in the same cells of output.
Putting it all together, here's the solution:
output(1, :) = cellfun(#(m) movmedian(m, 5, 3), output(1, :),...
'UniformOutput', false);
...and a little trick to avoid having to specify 'UniformOutput', false is to encapsulate the results of the anonymous function in a cell array:
output(1, :) = cellfun(#(m) {movmedian(m, 5, 3)}, output(1, :));

Python 2.7- separating b,g,r in an array

Ok, so what I want to do is go through an entire array of pixels, and for each pixel grab the green value, blue value and red value. This is so later I can see patterns between them.
So, this is what my code looks like.
for frame in camera.capture_continuous(rawCapture, format='bgr', use_video_port =True):
data=frame.array
rawCapture.truncate(0)
ColourCount = Calculations(data)
Ok, now that was just to show you what the general code is. This is where it gets tricky. Also, if that doesn't work for you guys on Pc, just use any opencv, I'm sure they save the data the same.
Calculations(data):
for n in data:
for s in n
B=s[0]
G=s[1]
R=s[2]
Then when I print these, it doesn't yield the result I want.
So s is like [0, 14, 0]
And B is like [0, 0, 0] as is the others. (those are just examples, although the values aren't getting high for some reason.
Now what I would like, is to split it so B is the blue channel, G is the green channel, etc.
So for the N example:
B= 0
G= 14
R = 0
So how do I achieve this?
I want single integers, but it's sending me back an entire pixel nearly?
EDIT: I believe part of my mistake before was that the item I was collecting was in fact a row instead of a pixel. So I put another for loop in, as seen above.
You can use the split() function.
Calculations(data):
bgr = cv2.split(data)
B = bgr[0]
G = bgr[1]
R = bgr[2]

How to detect patterns on a 1D array of measurements

I am developing an IA algorithm for a robot that needs to follow a line. The floor will be black, with a white line and there will be different marks that determine different types of "obstacles". I'm using a sensor that gives me an array of 8 measurements of the floor, as seen on the Figure 1 that give me an array of 8 measurements from 0 to 1000, where 0 there is no white and 1000 is totally white. In the examples bellow is a measurement of a white line in the middle of the sensor array and other cases.
int array[] = {50, 24, 9, 960, 1000, 150, 50, 45} // white line in the middle
int array2[] = {50, 24, 9, 960, 1000, 150, 50, 960} // white line in the middle and a square box on the right
int array3[] = {1000, 24, 9, 960, 1000, 150, 50, 40} // white line in the middle and a square box on the left
int array4[] = {1000, 980, 950, 0, 10, 980, 1000, 960} // black square box in the middle
Witch algorithms I could use to detect the patterns on the images below given this array of measurements? I do not want to use several "hardcoded" conditionals as templates, as I think it will not scale well. Im thinking on implementing a "peak counter" algorithm, but I do not know if it will work robust enough.
On the Figures we can see the different cases, the case I want to detect are the ones with the red circle.
Thanks!
How about doing something simple like treating each measurement like an N-dimensional vector. In your case N=8. Then, all you measurements are contained in a hypercube with sides up to length 1000. For N=8 there will be 256 corners. For each of your cases of interest, associate the hypercube corners that best match up to it. Note, some corners may not get associated. Then, for each measurement find its nearest associated hypercube corner. This tells you which case it is. You can mitigate errors by implementing some checks. For example, if the measurement is close to multiple corners (within some uncertainty threshold) then you label the measurement as being ambiguous and skip it.
It's easier to see this for the case of 3 measurements. The 8 corners of the cube could represent
[0,0,0] = no white
[0,0,1] = white on right
[0,1,0] = white in middle
[0,1,1] = white in middle and right
[1,0,0] = white on left
[1,0,1] = white on left and right
[1,1,0] = white on left and middle
[1,1,1] = all white
The case shown below is an ambiguous measurement in the middle.
(source: ctralie.com)

Resources