My teacher has assigned me to work combine RGB channels and create a GR image, whose results are like a negative image as shown here:
I have tried the following code:
GR1=(double(100*green_channel/1+red_channel+blue_channel));
GR2=(double(256/1+red_channel+blue_channel+green_channel));
GR=(double(GR1.*GR2));
But this does not produce the desired results.
I assume the main issue is the lack of parentheses in the denominator of your GR1 and GR2 equations. For example, I assume you want something like GR2=double(256/(1+red_channel+blue_channel+green_channel));
Secondarily, how did you display the image? Look at the min and max values of GR and verify that they are compatible with the function you are using. The min and max could also likely have tipped you off to the parentheses issue.
Related
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].
I have a set of ages (over 10000 of them) and I want to plot a graph with the age from 20 to 100 on the x axis and then the number of times each of those ages appears in the data on the y axis. I have tried several ways to do this and I can't figure it out. I also have some other data which requires me to plot values vs how many times they occur so any advice on how to do this would be much appreciated.
I'm quite new to Matlab so it would be great if you could explain how things in your answer work rather than just typing out some code.
Thanks.
EDIT:
So I typed histogram(Age, 80) because as I understand that will plot the values in Age on a histogram split up into 80 bars (1 for each age). Instead I get this:
The bars aren't aligned and it's clearly not 1 per age nor has it plotted the number of times each age occurs on the y axis.
You have to use histogram(), and that's correct.
Let's see with an example.
I extract 100 ages between 20 and 100:
ages=randsample([20:100],100,true);
Now I call histogram() in this manner:
h=histogram(ages,[20:100]);
where h is an histogram object and this will also show the following plot:
However, this might look easy due to the fact that my ages vector is in range 20:100, so it will not contain any other values. If your vector, as instead, contains also ages not in range 20:100, you can specify the additional option 'BinLimits' as third input in histogram() like this:
h=histogram(ages,length([20:100]),'BinLimits',[20:100]);
and this option plots a histogram using the values in ages that fall between 20 and 100 inclusive.
Note: by inspecting h you can actually see and/or edit some proprieties of your histogram. An attribute (field) of such object you might be interested to is Values. This is a vector of length 80 (in our case, since we work with 80 bins) in which the i-th element is the number of items is the i-th bin. This will help you count the occurrences (just in case you need them to go on with your analysis).
Like Luis said in comments, hist is the way to go. You should specify bin edges, rather than the number of bins:
ages = randi([20 100], [1 10000]);
hist(ages, [20:100])
Is this what you were looking for?
When I try to do the following command I get an error.
err = sqrt(mean((xi256-xc256).^2))
I am aware that the matrix sizes are different.
whos xi256 xc256` gives:
Name Size Bytes Class Attributes
xc256 27x1 216 double
xi256 513x1 4104 double
I am supposed to negate find the difference of these two matrices. In fact the command given at the top was in the course notes and the course has been running for several years! I have tried googling ways to resolve this error to perform this subtraction regardless but have found no solution. Maybe one of the matrices can be scaled to match the dimensions of the other? However, I have not been able to find any such functions that would let me do this.
I need to find the RMS error in a given set of data. xc256 was calculated through a numerical method, xi256 gives the true value.
Edit: I was able to use another set of results.
First check that xc256 is correctly computed and that you do not have a matrix transposition gone wrong or something like that. Computing the RMS between two vector of different sizes does not make sense, and padding or replicating will get you rid of the error, but is most probably not what you actually want.
There are just two situations that I can think of, I will list them here:
The line is wrong (not likely as it looks pretty normal, but make sure to check the book!)
The input of the line is wrong
Assuming it is in point 2, again there are two possibilities:
xi256 is of incorrect size (likelyhood of this depends on how you got it)
xc256 is of incorrect size
Assuming it is again point 2, there are yet again 2 likely possibilities:
xc256 should be a scalar
xc256 should be a vector with the same size as xi256
From here on there is insufficient information to continue, but check whether you accidentally made it 27 times as long, or 19 times too short somewhere. Just use some breakpoints throughout the code to see how the size develops.
A quick question because i fear there may already be an answer (although i cant find it)
i am getting the error: Matrix dimensions must agree.
because i am useing '<'
now with all the other operators there is a way around this either by putting '.' infront or by using a different formula. So what do people do about the less than operator????
i don't see why the greater than or equal to (>=) works but yet less than does not!?
am i being stupid and missed something really obvious??
code snippet
matrix 1 represents an array of 16 numbers
matrix 2 can represents anywhere between 10 and 20 numbers
idx = (matrix2 >= matrix1 * 0.1 & matrix2 < matrix1 * 1.5);
any help guidance or advice on the topic would be much appreciated! thank you!
EDIT
i know the matrices are different sizes but is there a way to use less then with different size arrays? as im not bothered about the size of the array but the numbers within
If you want to compare parts of matrices, like M(1:3,10:12)>A(5:7,1:3), you, probably, have to use the function squeeze():
squeeze(M(1:3,10:12))>squeeze(A(5:7,1:3))
This function remotes singleton dimensions and everything works fine after.
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);