Using a median operator to combine four initial disparity maps into one - matlab

Hi could someone please help I am using matlab to generate a disparity map. I have performed multi-wavelet transforms on two rectified stereo pairs and have used a stereo matching algorithm to combine the corresponding babsebands from each image to produce four intial disparity maps. However, I am now stuck and completely clueless on how to use a median operator to combine the values of these four disparity maps into one. Could someone please help me?
the four of my images are equal in size.
The previous code is irrelevant since it is in a different file(I have just saved the output from the previous file and now I am trying to code this in another file).
My thoughts were to:
1. Read the value of pixel p from each of the four basebands
2. Sort the values into ascending order
3. Calculate the median value of the pixel
4. Write the pixel value to a new image
5. Set p+1 and repeat steps 1-4 until last pixel is reached
Thank you

First, stack the images into a MxNx4 array:
bbstack = cat(3,bb1,bb2,bb3,bb4); % use bb{:} if they are in a single cell array
Then apply the median operator along the third dimension:
medbb = median(bbstack,3);

Related

How to change pixel values of an RGB image in MATLAB?

So what I need to do is to apply an operation like
(x(i,j)-min(x)) / max(x(i,j)-min(x))
which basically converts each pixel value such that the values range between 0 and 1.
First of all, I realised that Matlab saves our image(rows * col * colour) in a 3D matrix on using imread,
Image = imread('image.jpg')
So, a simple max operation on image doesn't give me the max value of pixel and I'm not quite sure what it returns(another multidimensional array?). So I tried using something like
max_pixel = max(max(max(Image)))
I thought it worked fine. Similarly I used min thrice. My logic was that I was getting the min pixel value across all 3 colour planes.
After performing the above scaling operation I got an image which seemed to have only 0 or 1 values and no value in between which doesn't seem right. Has it got something to do with integer/float rounding off?
image = imread('cat.jpg')
maxI = max(max(max(image)))
minI = min(min(min(image)))
new_image = ((I-minI)./max(I-minI))
This gives output of only 1s and 0s which doesn't seem correct.
The other approach I'm trying is working on all colour planes separately as done here. But is that the correct way to do it?
I could also loop through all pixels but I'm assuming that will be time taking. Very new to this, any help will be great.
If you are not sure what a matlab functions returns or why, you should always do one of the following first:
Type help >functionName< or doc >functionName< in the command window, in your case: doc max. This will show you the essential must-know information of that specific function, such as what needs to be put in, and what will be output.
In the case of the max function, this yields the following results:
M = max(A) returns the maximum elements of an array.
If A is a vector, then max(A) returns the maximum of A.
If A is a matrix, then max(A) is a row vector containing the maximum
value of each column.
If A is a multidimensional array, then max(A) operates along the first
array dimension whose size does not equal 1, treating the elements as
vectors. The size of this dimension becomes 1 while the sizes of all
other dimensions remain the same. If A is an empty array whose first
dimension has zero length, then max(A) returns an empty array with the
same size as A
In other words, if you use max() on a matrix, it will output a vector that contains the maximum value of each column (the first non-singleton dimension). If you use max() on a matrix A of size m x n x 3, it will result in a matrix of maximum values of size 1 x n x 3. So this answers your question:
I'm not quite sure what it returns(another multidimensional array?)
Moving on:
I thought it worked fine. Similarly I used min thrice. My logic was that I was getting the min pixel value across all 3 colour planes.
This is correct. Alternatively, you can use max(A(:)) and min(A(:)), which is equivalent if you are just looking for the value.
And after performing the above operation I got an image which seemed to have only 0 or 1 values and no value in between which doesn't seem right. Has it got something to do with integer/float rounding off?
There is no way for us to know why this happens if you do not post a minimal, complete and verifiable example of your code. It could be that it is because your variables are of a certain type, or it could be because of an error in your calculations.
The other approach I'm trying is working on all colour planes separately as done here. But is that the correct way to do it?
This depends on what the intended end result is. Normalizing each colour (red, green, blue) seperately will result in a different result as compared to normalizing the values all at once (in 99% of cases, anyway).
You have a uint8 RGB image.
Just convert it to a double image by
I=imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Cat_poster_1.jpg/1920px-Cat_poster_1.jpg')
I=double(I)./255;
alternatively
I=im2double(I); %does the scaling if needed
Read about image data types
What are you doing wrong?
If what you want todo is convert a RGB image to [0-1] range, you are approaching the problem badly, regardless of the correctness of your MATLAB code. Let me give you an example of why:
Say you have an image with 2 colors.
A dark red (20,0,0):
A medium blue (0,0,128)
Now you want this changed to [0-1]. How do you scale it? Your suggested approach is to make the value 128->1 and either 20->20/128 or 20->1 (not relevant). However when you do this, you are changing the color! you are making the medium blue to be intense blue (maximum B channel, ) and making R way way more intense (instead of 20/255, 20/128, double brightness! ). This is bad, as this is with simple colors, but with combined RGB values you may even change the color itsef, not only the intensity. Therefore, the only correct way to convert to [0-1] range is to assume your min and max are [0, 255].

(matlab matrix operation), Is it possible to get a group of value from matrix without loop?

I'm currently working on implementing a gradient check function in which it requires to get certain index values from the result matrix. Could someone tell me how to get a group of values from the matrix?
To be specific, for a result matrx res with size M x N, I'll need to get element res(3,1), res(4,2), res(1,3), res(2,4)...
In my case, M is dimension and N is batch size and there's a label array whose size is 1xbatch_size, [3 4 1 2...]. So the desired values are res(label(:),1:batch_size). Since I'm trying to practice vectorization programming and it's better not using loop. Could someone tell me how to get a group of value without a iteration?
Cheers.
--------------------------UPDATE----------------------------------------------
The only idea I found is firstly building a 'mask matrix' then use the original result matrix to do element wise multiplication (technically called 'Hadamard product', see in wiki). After that just get non-zero element out and do the sum operation, the code in matlab should look like:
temp=Mask.*res;
desired_res=temp(temp~=0); %Note: the temp(temp~=0) extract non-zero elements in a 'column' fashion: it searches temp matrix column by column then put the non-zero number into container 'desired_res'.
In my case, what I wanna do next is simply sum(desired_res) so I don't need to consider the order of those non-zero elements in 'desired_res'.
Based on this idea above, creating mask matrix is the key aim. There are two methods to do this job.
Codes are shown below. In my case, use accumarray function to add '1' in certain location (which are stored in matrix 'subs') and add '0' to other space. This will give you a mask matrix size [rwo column]. The usage of full(sparse()) is similar. I made some comparisons on those two methods (repeat around 10 times), turns out full(sparse) is faster and their time costs magnitude is 10^-4. So small difference but in a large scale experiments, this matters. One benefit of using accumarray is that it could define the matrix size while full(sparse()) cannot. The full(sparse(subs, 1)) would create matrix with size [max(subs(:,1)), max(subs(:,2))]. Since in my case, this is sufficient for my requirement and I only know few of their usage. If you find out more, please share with us. Thanks.
The detailed description of those two functions could be found on matlab's official website. accumarray and full, sparse.
% assume we have a label vector
test_labels=ones(10000,1);
% method one, accumarray(subs,1,[row column])
tic
subs=zeros(10000,2);
subs(:,1)=test_labels;
subs(:,2)=1:10000;
k1=accumarray(subs,1,[10, 10000]);
t1=toc % to compare with method two to check which one is faster
%method two: full(sparse(),1)
tic
k2=full(sparse(test_labels,1:10000,1));
t2=toc

Extract data using Matlab

How could I correlate the first (also second and third, etc) line of each function together? I meant I want to pick up the value of the first line of function 1, first line of function 2 and so on... Specially number of these lines (between two #...#) are not always equal.
Let's say the values between (# -#) is one matrix. I see that the problem is I need to break them down into different matrix and then equalize all these matrix to the same size by adding NaN values and then reconstruct them again. That is what I think but I dont know how to ask Matlab do these tasks.
Would you please give me a help?
Thank you very much !!

How to number matrices (histograms of images) with different sizes and retrieve them (Matlab)

Using Matlab, I have 1000 color images, their histograms have the size either 384*256*3 or 256*384*3, so they are matrices.
I want to number them, and later retrieve them. I know I cannot do this:
for z=1:1000
H(:,:,:,z)={imread(strcat('image.orig/',int2str(z-1),'.jpg'))};
end
But my question is how can I number the 1000 matrices and later I can get any of them, like for the first image, simply using
H(:,:,:,1)
to get the matrix. I know their sizes are different so I cannot set
H=zeros(384,256,3,1000);
because that only work for the matrices of the size 384*256*3.
So what I should do to save the matrices and simply using a number from 1 to 1000 within a variable name to get any of the matrix?
It is just how can I number different matrices and get each of them later?
Hope I stated clear what's my problem. Thanks in advance!!
As chappjc said, it is better to store in a cell.
H=cell(1000,1);
for z=1:1000
H{z}=imread(strcat('test',int2str(z),'.jpg'))
end

How do I find frequency of values appearing in all rows of a matrix in MATLAB?

I have a 161*32 matrix (labelled "indpic") in MATLAB and I'm trying to find the frequency of a given number appearing in a row. So I think that I need to analyse each row separately for each value, but I'm incredibly unsure about how to go about this (I'm only new to MATLAB). This also means I'm incredibly useless with loops and whatnot as well.
Any help would be greatly appreciated!
If you want to count the number of times a specific number appears in each row, you can do this:
sum(indpic == val, 2)
where indpic is your matrix (e.g image) and val is the desired value to be counted.
Explanation: checking equality of each element with the value produces a boolean matrix with "1"s at the locations of the counted value. Summing each row (i.e summing along the 2nd dimension results in the desired column vector, where each element being equal to the number of times val is repeated in the corresponding row).
If you want to count how many times each value is repeated in your image, this is called a histogram, and you can use the histc command to achieve that. For example:
histc(indpic, 1:256)
counts how many times each value from 1 to 256 appears in image indpic.
Like this,
sum(indpic(rownum,:) == 7)
obviously change 7 to whatever.
You can just write
length(find(indpic(row_num,:)==some_value))
and it will give you the number of elements equal to "some_value" in the "row_num"th row in matrix "indpic"