Image processing with z transform - image

I am implementing the z transformation and I am using the built-in function ztrans in Matlab. Now i give
x=imread('lena512.bmp');
x=im2double(x);
z=ztrans(x);
where x contains the pixel values of an image and ztrans(x) should apply z-transformation. But i am getting an error like this
??? Undefined function or method 'ztrans' for input arguments of type 'double'.
How can I use the function and apply z transformation on images?

Z = zscore(X) returns the z-score for each element of X such that columns of X are centered to have mean 0 and scaled to have standard deviation 1. Z is the same size as X.
so in order to do what you wanted you should use this instead
x= zscore(x)
imshow(x,[])
keep in mind that this will give you some weird results as this is done for each column, to create a global transformation you should do the following
[m,n]= size(x)
x= zscore(x(:))
x = reshape(x,m,n)
imshow(x,[])
enjoy
enjoy

Related

How to create a mask or detect image section based on the intensity value?

I have a matrix named figmat from which I obtain the following pcolor plot (Matlab-Version R 2016b).
Basically I only want to extract the bottom red high intensity line from this plot.
I thought of doing it in some way of extracting the maximum values from the matrix and creating some sort of mask on the main matrix. But I'm not understanding a possible way to achieve this. Can it be accomplished with the help of any edge/image detection algorithms?
I was trying something like this with the following code to create a mask
A=max(figmat);
figmat(figmat~=A)=0;
imagesc(figmat);
But this gives only the boundary of maximum values. I also need the entire red color band.
Okay, I assume that the red line is linear and its values can uniquely be separated from the rest of the picture. Let's generate some test data...
[x,y] = meshgrid(-5:.2:5, -5:.2:5);
n = size(x,1)*size(x,2);
z = -0.2*(y-(0.2*x+1)).^2 + 5 + randn(size(x))*0.1;
figure
surf(x,y,z);
This script generates a surface function. Its set of maximum values (x,y) can be described by a linear function y = 0.2*x+1. I added a bit of noise to it to make it a bit more realistic.
We now select all points where z is smaller than, let's say, 95 % of the maximum value. Therefore find can be used. Later, we want to use one-dimensional data, so we reshape everything.
thresh = min(min(z)) + (max(max(z))-min(min(z)))*0.95;
mask = reshape(z > thresh,1,n);
idx = find(mask>0);
xvec = reshape(x,1,n);
yvec = reshape(y,1,n);
xvec and yvec now contain the coordinates of all values > thresh.
The last step is to do some linear polynomial over all points.
pp = polyfit(xvec(idx),yvec(idx),1)
pp =
0.1946 1.0134
Obviously these are roughly the coefficients of y = 0.2*x+1 as it should be.
I do not know, if this also works with your data, since I made some assumptions. The threshold level must be chosen carefully. Maybe some preprocessing must be done to dynamically detect this level if you really want to process your images automatically. There might also be a simpler way to do it... but for me this one was straight forward without the need of any toolboxes.
By assuming:
There is only one band to extract.
It always has the maximum values.
It is linear.
I can adopt my previous answer to this case as well, with few minor changes:
First, we get the distribution of the values in the matrix and look for a population in the top values, that can be distinguished from the smaller values. This is done by finding the maximum value x(i) on the histogram that:
Is a local maximum (its bin is higher than that of x(i+1) and x(i-1))
Has more values above it than within it (the sum of the height of bins x(i+1) to x(end) < the height of bin x):
This is how it is done:
[h,x] = histcounts(figmat); % get the distribution of intesities
d = diff(fliplr(h)); % The diffrence in bin height from large x to small x
band_min_ind = find(cumsum(d)>size(figmat,2) & d<0, 1); % 1st bin that fit the conditions
flp_val = fliplr(x); % the value of x from large to small
band_min = flp_val(band_min_ind); % the value of x that fit the conditions
Now we continue as before. Mask all the unwanted values, interpolate the linear line:
mA = figmat>band_min; % mask all values below the top value mode
[y1,x1] = find(mA,1); % find the first nonzero row
[y2,x2] = find(mA,1,'last'); % find the last nonzero row
m = (y1-y2)/(x1-x2); % the line slope
n = y1-m*x1; % the intercept
f_line = #(x) m.*x+n; % the line function
And if we plot it we can see the red line where the band for detection was:
Next, we can make this line thicker for a better representation of this line:
thick = max(sum(mA)); % mode thickness of the line
tmp = (1:thick)-ceil(thick/2); % helper vector for expanding
rows = bsxfun(#plus,tmp.',floor(f_line(1:size(A,2)))); % all the rows for each column
rows(rows<1) = 1; % make sure to not get out of range
rows(rows>size(A,1)) = size(A,1); % make sure to not get out of range
inds = sub2ind(size(A),rows,repmat(1:size(A,2),thick,1)); % convert to linear indecies
mA(inds) = true; % add the interpolation to the mask
result = figmat.*mA; % apply the mask on figmat
Finally, we can plot that result after masking, excluding the unwanted areas:
imagesc(result(any(result,2),:))

Plotting two variables function

This question is for learning purpose. I am writing my own function to plot an equation. For example:
function e(x) { return sin(x); }
plot(e);
I wrote a plot function that takes function as parameter. The plotting code is simple, x run from some value to some value and increase by small step. This is plot that the plot() manage to produce.
But there is the problem. It cannot express the circle equation like x2 + y2 = 1. So the question would be how should the plot and equation function look like to be able to handle two variables.
Noted that I am not only interesting in two circle equation. A more generalize way of plotting function with two variables.
Well to plot a non function 1D equation (x,y variables) you have 3 choices:
convert to parametric form
so for example x^2 + y^2 = 1 will become:
x = cos(t);
y = sin(t);
t = <0,2*PI>
So plot each function as 1D function plot while t is used as parameter. But for this you need to exploit mathematic identities and substitute ... That is not easily done programaticaly.
convert to 1D functions
non function means you got more than 1 y values for some x values. If you separate your equation into intervals and divide to all cases covering whole plot then you can plot each derived function instead.
So you derive y algebraicaly (let assume unit circle again):
x^2 + y^2 = 1
y^2 = 1 - x^2
y = +/- sqrt (1 - x^2)
----------------------
y1 = +sqrt (1 - x^2)
y2 = -sqrt (1 - x^2)
x = <-1,+1>
this is also not easily done programaticaly but it is a magnitude easier than #1.
do a 2D plot using equation as predicator
simply loop your view through all pixels and render only those for which the equation is true. So again unit circle:
for (x=-1.0;x<=+1.0;x+=0.001)
for (y=-1.0;y<=+1.0;y+=0.001)
if (fabs((x*x)+(y*y)-1.0)<=1e-6)
plot_pixel(x,y,some_color); // x,y should be rescaled and offset to the actual plot view
So you just convert your equation to implicit form:
x^2 + y^2 = 1
-----------------
x^2 + y^2 - 1 = 0
and compare to zero with some threshold (to avoid FPU accuracy problems):
| x^2 + y^2 - 1 | <= threshold_near_zero
The threshold is half size of plot lines width. So this way you can easily change plot width to any pixel size... As you can see this is easily done programaticaly but the plot is slower as you need to loop through all the pixels of the plot view. The step for x,y for loops should match pixel size of the view scale.
Also while using equation as predicate you should handle math singularities as with blind probing you will most likely hit some like division by zero, domain errors for asin,acos,sqrt,etc.
So for arbitrary 1D non function use #3. unless you got some mighty symbolic math engine for #1 or #2.
Defination of a function : A function f takes an input x, and returns a single output f(x).
Now it means for any input there will be one and only one unique output. Like y = sin(x). this is a function on x and y definnes that function.
For equaltion like (x*x) + (y*y) = 1. there are two possible values of y for a single value of `x, hence it can not be termed as a valid equaltion for a function.
If you need to draw it then one possible solution is to plot two points for a single value of x, i.e. sqrt(1-(x*x)) and other -1*sqrt(1-(x*x)). Plot both the values (one will be positive other will be negative with the same absolute value).

MATLAB: how to transform one image to another image

I am trying to transform one image to another in MATLAB, and in the meantime also get the transformation function T(x,y) from this operation (eg. T(x,y) = (x + a(x,y), y + b(x,y)) ). Let's use the following figures as an example. I want to transform the square in the first figure to the circle in the other figure, and output gives me a transformation function, so whenever I use the function on the square I will get the circle.
Functions I have looked into:
I have looked into imwarp, but it should be only for geometric transformation (scaling, rotating, shearing). I don't think this is useful in transforming a square to a circle, while not providing any transformation matrix beforehand.
I have looked into using imregconfig and imregister from a MATLAB example, but it seems to only work for images with same structure but different intensities. Plus, it doesn't give out any transformation function. Please correct me if I am wrong.
Thank you in advance for any help!
The solution space for valid transformations is infinite. How do we choose the "right" one?
One possible transformation for those inputs is to translate the square -0.5 in x and -0.5 in y. Then scale it to double the size (x' = 2x, y' = 2y) and apply a square-to-circle mapping function. (Solution 1)
Another completely valid transformation function could run all the points in the input through the expression
( (x == 0 || x == 1) && (0 <= y <= 1) || ( (y == 0 || y == 1) && (0 <= x <= 1) )
and if all points pass, simply print out "x^2 + y^2 = 1". (Solution 2)
Solutions (1) and (2) both produce code that seems to satisfy the case you've presented, but clearly (2) is so non-general as to be useless. I think you need to define the problem more precisely before we can start writing a solution in code.

Change pixel values on a line in MATLAB

I wish to set values on a line whose endpoints are returned by the hough transforms to zero. I have written the following code snippet
imshow(img);
hold on
img_black = img;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2]; %line end points
[x, y] = bresenham(xy(1,1),xy(1,2),xy(2,1),xy(2,2)); %returns all points on the line
for i = 1:length(x)
plot(x(i),y(i),'*'); %to plot individual pixels on line itself
img_black(x(i),y(i),:) = [0,0,0]; %set rgb values to zero
end
end
Although the points plotted on the image below are as expected
The image where the corresponding pixel values are being set to zero is not as expected.
What is happening here?
It looks like you have mixed up x and y with rows and columns.
img_black(x(i), y(i),:)
Should be
img_black(y(i), x(i),:);
This is because the first dimension of img_black is rows (y) and the second dimension is columns (x).
The resulting image looks like it does because your lines go the wrong way and (sometimes) go outside the bounds of the original image, but MATLAB gladly expands your image (with zeros) and sets the values that you request, hence all the black pixels on the right.
NOTE: This switching back and forth between row, column and x,y is common throughout MATLAB's built-in functions and you should always be careful to note what the output is. A class example is meshgrid vs ndgrid outputs.

once added,how to get back the original images using matlab?

A = imread('ab.jpg');
A = imresize(A,[255 255]); subplot(2,2,1), imshow(A);
B = imread('cd.jpg');
B = imresize(B,[255 255]);subplot(2,2,2), imshow(B);
C = imadd(A,B);subplot(2,2,3),imshow(C);
This is the program i have used to add two images and it is working fine. Now i want to get back both the images. Am not able to figure out how to get it back without taking one of the images as reference (ie subtracting image A from the sum to get image B). Can anyone please help?
Let's not worry about images. Say I have two real integers, x and y. I add them to get z = x+y. Now if I tell someone the integer z is there any way for him or her to get back x and/or y?
Potentially you can retrieve one of the numbers out of the summation, by having the other. But the issue you're facing with is the fact that your image matrices cannot exceed the value 255 since MATLAB uses uint8 type by default. Here is an example for two corresponding pixels in image A and B:
% A(1,1) == 130 is ture
% B(1,1) == 180 is ture
C(1,1) = A(1,1) + B(1,1); %C(1,1) == 310 is false! c(1,1) == 255 is true
expectedB = C(1,1) - A(1,1); % expectedB == 180 is false! expectedB == 125 is true
You can cast the type of your matrices to int16. Whereas by doing so MATLAB's functions sich as imshow do not work as you want them to. Because they assume that your

Resources