Plot 2-d data in Matlab [duplicate] - image

This question already has an answer here:
Creating colormap at specific point and color weights at matlab
(1 answer)
Closed 5 years ago.
I have data like this :
x coordinate| y coordinate | Z
0.01 | 0.15 | 1
0.23 | 0.17 | 5
0.28 | 0.18 | 6
... ... ...
I want to plot all of these data in 2-d such that , in each point (x,y)
we have the corresponding intensity Z which i want to be depicted with a colour . Just like the function 'image' which already exists . But i have a problem that the aforementioned function of matlab plot in a uniform manner all the points. So if i have
x= [0 0.01 1];
y = [0 1];
'Z = [1 1 0;0 1 1];'
Then it will plot the corresponding densities at the (0,0) (0.5,0) , (1 ,0)... So it takes the max of x and the min of x and take uniform pieces .
I want to plot my data in specific points.
Any ideas , is there any other suitable function for this ?
How can i construct something like that ?

If your data is a grid that has sligth variations on the values, but still a grid, do:
surf(x,y,z,'linestyle','none');
axis tight;axis off; view(2)
Example output with
z=peaks;
[x,y]=meshgrid(1:49,1:49);
x=x+rand(size(x))*0.1;
y=y+rand(size(x))*0.1;

Related

Get X and Y positions of a Pixel given the HEIGHT , WIDTH and index of a pixel in FLATTENED array representing the image

Imagine you have this image
[[1 2 3] [4 5 6] [7 8 90]]
You flatten it into this format -
[1 2 3 4 5 6 7 8 90]
Now you are given the index of Pixel 90 to be 8.
How can you find that pixel 90 is in Row 3 and column 3?
OpenCL, similarly to other programming languages like C, C++, Java and so on, uses zero based indexing. So in this terms you are looking for Row 2 and Column 2.
Now to calculate which row that is we need to divide index position 8 by number of columns:
8 / 3 = 2
So in zero based indexing that is a second row.
Now to calculate which column that is we use modulo operator:
8 % 3 = 2
In the 2D case, a point (x,y) in a rectangle with the dimensions (sx,sy) can be represented in 1D space by a linear index n as follows:
n = x+y*sx
Converting the 1D index n back to (x,y) works as follows:
x = n%sx
y = n/sx
For the 3D case, a point (x,y,z) in the a box with dimensions (sx,sy,sz) can be represented in 1D as
n = x+(y+z*sy)*sx
and converted back to (x,y,z) like this:
z = n/(sx*sy);
temp = n%(sx*sy);
y = temp/sx;
x = temp%sx;
Note that "/" here means integer division (always rounds down the result) and "%" is the modulo operator.

Matlab indexing two dimensions with linear indicies while keeping a third dimension constant

Say I have 2D linear indicies:
linInd = sub2ind(imSize,rowPnts,colPnts);
And I have a 3D color image I:
I = rand(64,64,3)*255
Is there any way that I can index something like this in order to get all coordinates in the 2D plane but for each channel of the image? That is, can I get all of the color channel information for each pixel with one command using linear indicies that are specified for 2D?
I(linInd,:)
So I don't have to split up the image into 3 parts and then reassemble again?
Thanks.
You can broadcast the 2D linear indices to a 3D case using bsxfun without messing with the input array, like so -
[m,n,r] = size(I);
out = I(bsxfun(#plus,linInd,(m*n*(0:r-1))'))
Sample setup
%// ---------------- 2D Case ---------------------
im = randi(9,10,10);
imSize = size(im);
rowPnts = [3,6,8,4];
colPnts = [6,3,8,5];
linInd = sub2ind(imSize,rowPnts,colPnts);
%// ---------------- 3D Case ---------------------
I = randi(9,10,10,4);
%// BSXFUN solution
[m,n,r] = size(I);
out = I(bsxfun(#plus,linInd,(m*n*(0:r-1))')); %//'
%// Tedious work of splitting
Ir = I(:,:,1);
Ig = I(:,:,2);
Ib = I(:,:,3);
Ia = I(:,:,4);
Output
>> Ir(linInd)
ans =
8 9 1 6
>> Ig(linInd)
ans =
1 5 9 8
>> Ib(linInd)
ans =
8 5 3 8
>> Ia(linInd)
ans =
8 8 3 3
>> out
out =
8 9 1 6
1 5 9 8
8 5 3 8
8 8 3 3
To my knowledge, reshaping the matrix first is the only way to use linear indexing this way.
I2=reshape(I,[],3)
I2(ind,:)
Is it specifically necessary for you to keep that dimension as the third? If not, you could permute the array to move that dimension to the 1st position, then use arr(i3d, linInd).

In Matlab Finding gradient of an image using first derivative

How can I do enhancements on an image using the first derivative.
I do not want to use operators like sobel..
I want to find the gradient using the first derivative
You're always free to define your own impulse response and then convolve that with your image.
diff1X =[1/2, 0, -1/2] %first derivative in the x direction
diff1Y = [1/2; 0; -1/2] %first derivative in the y direction
%These are finite difference approximations to the first derivative note they
%are time reversed because the convolution involves a time reversal
x = [1,2,3; 2,4,6; 4,8,12]
x =
1 2 3
2 4 6
4 8 12
conv2(x, diff1X, 'same') %same parameter cuts results to initial image size
ans =
1 1 -1
2 2 -2
4 4 -4
%note that the image is zero padded so the derivative at the edges reflects this
conv2(x, diff1Y, 'same')
ans =
1.0000 2.0000 3.0000
1.5000 3.0000 4.5000
-1.0000 -2.0000 -3.0000

draw random number following a custom distribution [duplicate]

This question already has answers here:
Weighted random numbers in MATLAB
(4 answers)
Closed 8 years ago.
I need to draw random numbers following a distribution I chose.
Example: draw 7 numbers from 1 to 7 with those probabilities:
1: 0.3
2: 0.2
3: 0.15
4: 0.15
5: 0.1
6: 0.05
7: 0.05
Since in my actual application I need to draw potentially 1000 numbers I need this to be as much efficient as possible (ideally linear).
I know there is a function in MATLAB that draws random numbers from a normal distribution; is there any way to adapt it?
Think you can use randsample too from Statistics Toolbox as referenced here.
%%// Replace 7 with 1000 for original problem
OUT = randsample([1:7], 7, true, [0.3 0.2 0.15 0.15 0.1 0.05 0.05])
numbers = 1:7;
probs = [.3 .2 .15 .15 .1 .05 .05];
N = 1000; %// how many random numbers you want
cumProbs = cumsum(probs(:)); %// will be used as thresholds
r = rand(1,N); %// random numbers between 0 and 1
output = sum(bsxfun(#ge, r, cumProbs))+1; %// how many thresholds are exceeded
You can use gendist from matlab file exchange: http://www.mathworks.com/matlabcentral/fileexchange/34101-random-numbers-from-a-discrete-distribution/content/gendist.m
This generates 1000 random numbers:
gendist([.3,.2,.15,.15,.1,.05,.05],1000,1)
If you do not have randsample, you can use histc like it does internally, just without all the fluff:
N = 100;
nums = 1:7;
p = [.3 .2 .15 .15 .1 .05 .05];
cdf = [0 cumsum(p(:).'/sum(p))]; cdf(end)=1; %' p is pdf
[~, isamps] = histc(rand(N,1),cdf);
out = nums(isamps);

Using Bi-cubic Interpolation

I read about it on Wikipedia, theory sounds good, but I don't know to apply to practice.
I have an small example like this one:
Original Image Matrix
1 2
3 4
If I want to double size the image, then the new matrix is
x x x x
x x x x
x x x x
x x x x
Now, the fun part is how to transfer old values in original matrix to the new matrix, I intend to do like this
1 x 2 x
x x x x
3 x 4 x
x x x x
Then applying the Bi cubic Interpolation on it (at this moment just forget about using 16 neighbor pixel, I don't have enough space to demonstrate such a large matrix here).
Now my questions are:
1. Do I do the data transferring (from old to new matrix) right? If not, what should it look like?
2. What should be the value of x variables in the new matrix? to me , this seems correct because at least we have some values to do the calculation instead of x notations.
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
3. Will all of the pixels in new matrix be interpolated? Because the pixels at the boundary do not have enough neighbor pixels to perform the calculation.
Thank you very much.
Interpolation means estimating a value for points that don't physically exist. You need to start with a coordinate system, so let's just use two incrementing integers for X position and Y position.
0, 0 1, 0
0, 1 1, 1
Your output requires 4x4 pixels which should be spaced at 0.5 intervals instead of the 1.0 intervals of the input:
-0.25,-0.25 0.25,-0.25 0.75,-0.25 1.25,-0.25
-0.25, 0.25 0.25, 0.25 0.75, 0.25 1.25, 0.25
-0.25, 0.75 0.25, 0.75 0.75, 0.75 1.25, 0.75
-0.25, 1.25 0.25, 1.25 0.75, 1.25 1.25, 1.25
None of the coordinates in the output exist in the input, so they'll all need to be interpolated.
The offset of the first coordinate of -0.25 is chosen so that the first and last coordinate will be equal distances from the edges of the input, and is calculated by the difference between the output and input intervals divided by 2. For example if you wanted a 10x zoom the interval is 0.1, the initial offset is (0.1-1)/2 and the points would be (-0.45, -0.35, -0.25, -0.15, ... 1.35, 1.45).
The Bicubic algorithm will require data for points outside of the original image. The easiest solution comes when you use a premultiplied alpha representation for your pixels, then you can just use (0,0,0,0) as the value for anything outside the image boundaries.

Resources