changin nan values in imagesc to 0 after printing - image

The way I used imagesc is that I added each layer on top of the other because they have different boundries.
the problem is that because I used such ways beyond the boundry at the start there is NaN values.
My question is how can I change the NaN values to 0 after I already printed the function? The code is the following:
N = 2^9;
z = ones(N-1,1);
c = 1;
ranNum = diag(rand([N 1])-ones(N,1)/2);
Nsig = 10^2;
sigma = ones(Nsig,1).';
E = ones(Nsig,N);
IPR = ones(Nsig,N);
sigjump = 0.01;
for j = 1:Nsig
sigma(j) = sigjump + sigjump*(j-1);
H1 = c*(diag(z,1)+ diag(z,-1) + diag(1,N-1)+ diag(1,-N+1));
V1 = sigma(j) * ranNum ;
H = H1 + V1;
[psi,~] = eig(H);
E(j,:) = eig(H);
P1 = abs(psi).^2;
IPR(j,:) = sum(P1.^2);
imagesc(E(j,:),sigma(j)+sigjump*Nsig/2 ,IPR(j,:));
colormap('turbo')
colorbar
xlabel('E')
ylabel('sigma')
h = colorbar;
ylabel(h, 'IPR')
hold on
end
This is the result (the white at the top left), also, you cant see the entire spectrum.

I don't have matlab, but i guess that's the same with Octave (and Scilab):
>> a = rand(2,4)
a =
0.257914 0.775035 0.608284 0.057678
0.162044 0.491000 0.285110 0.766687
>> a(a<0.3) = NaN
a =
NaN 0.7750 0.6083 NaN
NaN 0.4910 NaN 0.7667
>> a(isnan(a)) = 0
a =
0 0.7750 0.6083 0
0 0.4910 0 0.7667

Related

How to avoid overlapping between title and labels in Matlab's pie chart?

I'm using the next code to plot in a pie chart the percentage of values in a matrix that are greater/smaller than 1. The thing is that when I want to put the title above the graph, it overlaps with the label of one of the groups.
I tried replacing it with text() but it didn't worked, and Documentation on pie say nothing to this. How can I avoid this overlap?
eigen = []; % Modes array
c2 = 170; % Sound speed divided by 2
%% Room dimensions
lx = 5.74;
ly = 8.1;
lz = 4.66;
i = 1; % Index for modes array
for nz = 0:50
for ny = 0:50
for nx = 0:50
aux = c2 * sqrt((nx/lx)^2+(ny/ly)^2+(nz/lz)^2);
if aux < 400 %% If value is into our range of interest
eigen(i) = aux;
i=i+1;
end
end
end
end
eigen = round(sort(eigen'),1);
eigen
% dif = eigen(2:end)-eigen(1:end-1); % Distance between modes
x = 0; %% dif >= 1
y = 0; %% dif <= 1
dif = [];
for i=2:length(eigen)
if eigen(i)-eigen(i-1) >= 1
x = x+1;
else
y = y+1;
end
end
figure
dif = [x,y];
explode = [1 1];
graf = pie(dif,explode);
hText = findobj(graf,'Type','text');
percentValues = get(hText,'String');
txt = {'Smaller than 1 Hz: ';'Greater than 1 Hz: '};
combinedtxt = strcat(txt,percentValues);
oldExtents_cell = get(hText,'Extent');
oldExtents = cell2mat(oldExtents_cell);
hText(1).String = combinedtxt(1);
hText(2).String = combinedtxt(2);
title('Distance between modes')
You can rotate the pie chart so that the figure look better. Further, you can use position to allocate your text as follows,
figure
dif = [x,y];
explode = [1 1];
graf = pie(dif,explode);
hText = findobj(graf,'Type','text');
percentValues = get(hText,'String');
txt = {'Smaller than 1 Hz: ';'Greater than 1 Hz: '};
combinedtxt = strcat(txt,percentValues);
oldExtents_cell = get(hText,'Extent');
oldExtents = cell2mat(oldExtents_cell);
hText(1).String = combinedtxt(1);
hText(2).String = combinedtxt(2);
view([90 90]) % this is to rotate the chart
textPositions_cell = get(hText,{'Position'});
textPositions = cell2mat(textPositions_cell);
textPositions(:,1) = textPositions(:,1) + 0.2; % replace 0.2 with any offset value you want
hText(1).Position = textPositions(1,:);
hText(2).Position = textPositions(2,:);
title('Distance between modes')
You can change only the text position (without rotation) by deleting view command.

How to calculate the mean of 3D matrices in an image without NaN?

I need to calculate the mean of a 3D matrices (last step in the code). However, there are many NaNs in the (diff_dataframe./dataframe_vor) calculation. So when I use this code, some results will be NaN. How could I calculate the mean of this matrix by ignoring the NaNs? I attached the code as below.
S.amplitude = 1:20;%:20;
S.blocksize = [1 2 3 4 5 6 8 10 12 15 20];
S.frameWidth = 1920;
S.frameHeight = 1080;
S.quality=0:10:100;
image = 127*ones(S.frameHeight,S.frameWidth,3);
S.yuv2rgb = [1 0 1.28033; 1 -0.21482 -0.38059; 1 2.12798 0];
i_bs = 0;
for BS = S.blocksize
i_bs = i_bs + 1;
hblocks = S.frameWidth / BS;
vblocks = S.frameHeight / BS;
i_a = 0;
dataU = randi([0 1],vblocks,hblocks);
dataV = randi([0 1],vblocks,hblocks);
dataframe_yuv = zeros(S.frameHeight, S.frameWidth, 3);
for x = 1 : hblocks
for y = 1 : vblocks
dataframe_yuv((y-1)*BS+1:y*BS, ...
(x-1)*BS+1:x*BS, 2) = dataU(y,x) * 2 - 1;
dataframe_yuv((y-1)*BS+1:y*BS, ...
(x-1)*BS+1:x*BS, 3) = dataV(y,x) * 2 - 1;
end
end
dataframe_rgb(:,:,1) = S.yuv2rgb(1,1) * dataframe_yuv(:,:,1) + ...
S.yuv2rgb(1,2) * dataframe_yuv(:,:,2) + ...
S.yuv2rgb(1,3) * dataframe_yuv(:,:,3);
dataframe_rgb(:,:,2) = S.yuv2rgb(2,1) * dataframe_yuv(:,:,1) + ...
S.yuv2rgb(2,2) * dataframe_yuv(:,:,2) + ...
S.yuv2rgb(2,3) * dataframe_yuv(:,:,3);
dataframe_rgb(:,:,3) = S.yuv2rgb(3,1) * dataframe_yuv(:,:,1) + ...
S.yuv2rgb(3,2) * dataframe_yuv(:,:,2) + ...
S.yuv2rgb(3,3) * dataframe_yuv(:,:,3);
for A = S.amplitude
i_a = i_a + 1;
i_q = 0;
image1p = round(image + dataframe_rgb * A);
image1n = round(image - dataframe_rgb * A);
dataframe_vor = ((image1p-image1n)/2)/255;
for Q = S.quality
i_q = i_q + 1;
namestrp = ['greyjpegs/Img_BS' num2str(BS) '_A' num2str(A) '_Q' num2str(Q) '_1p.jpg'];
namestrn = ['greyjpegs/Img_BS' num2str(BS) '_A' num2str(A) '_Q' num2str(Q) '_1n.jpg'];
imwrite(image1p/255,namestrp,'jpg', 'Quality', Q);
imwrite(image1n/255,namestrn,'jpg', 'Quality', Q);
error_mean(i_bs, i_a, i_q) = mean2((abs(diff_dataframe./dataframe_vor)));
end
end
end
mean2 is a shortcut function that's part of the image processing toolbox that finds the entire average of a 2D region which doesn't include handling NaN. In that case, simply remove all values that are NaN and find the resulting average. Note that the removal of NaN unrolls the 2D region into a 1D vector, so we can simply use mean in this case. As an additional check, let's make sure there are no divide by 0 errors, so also check for Inf as well.
Therefore, replace this line:
error_mean(i_bs, i_a, i_q) = mean2((abs(diff_dataframe./dataframe_vor)));
... with:
tmp = abs(diff_dataframe ./ dataframe_vor);
mask = ~isnan(tmp) | ~isinf(tmp);
tmp = tmp(mask);
if isempty(tmp)
error_mean(i_bs, i_a, i_q) = 0;
else
error_mean(i_bs, i_a, i_q) = mean(tmp);
We first assign the desired operation to a temporary variable, use isnan and isinf to remove out the offending values, then find the average of the rest. One intricacy is that if your entire region is NaN or Inf, then the removal of all these entries in the region results in the empty vector, and finding the mean of this undefined. A separate check is there to be sure that if it's empty, simply assign the value of 0 instead.

Inverse image rotation

I have written the following code without any Matlab built-in functions to rotate an image. I tried to write another loop to invert the rotation. the image does rotate back but I still get the size of the previously rotated image. How can I get rid of the black parts in the image?
INPUT_IMAGE = 'forest.png';
img_in=double(imread(INPUT_IMAGE))./255;
h=size(img_in,1);
w=size(img_in,2);
R=[cos(th) -sin(th) 0 ; sin(th) cos(th) 0 ; 0 0 1];
T=[1 0 (-w/2) ; 0 1 (-h/2) ; 0 0 1];
F=inv(T)*R*T;
img_out=zeros(h,w,3);
%Rotate image
for i=1:w
for j=1:h
a = [i ; j ; 1];
b = inv(F) * a;
x = b(1)/b(3);
y = b(2)/b(3);
x = floor(x);
y = floor(y);
if (x>0 & x<=W & j>0 & j<=H)
img_out(y,x,:)=img_in(j,i,:);
end
end
end
img_out2=zeros(h,w,3);
%invert rotation
for i=1:w
for j=1:h
a = [i ; j ; 1];
b = F * a;
x = b(1)/b(3);
y = b(2)/b(3);
x = floor(x);
y = floor(y);
if (x>0 & x<=W & j>0 & j<=H)
img_out2(y,x,:)=img_out(j,i,:);
end
end
end
The result:
I know the image has black gaps due to the forward mapping but I'm not concerned about that as I'm trying to implement a code without built-in functions that would only rotate the image back so I can calculate the error.
Instead of iterating the source image, inverse transformation matrix, and iterate destination image.
Iterating destination image guarantees to have no holes (each pixel gets a value).
The code you have posted is not working, please fix it...
I based my answer on your previous post: Matlab image rotation
I used 'peppers.png' instead of 'forest.png' (I can't find 'forest.png', next time, please add the image to your post).
The example code do the following:
Rotate input image (You may treat it as "reverse transformation").
Rotate result image back (using inverse transformation matrix).
Display absolute difference of original image and result image.
close all;
clear all;
img_in = 'peppers.png';
img_in =double(imread(img_in))./255;
orig_in = img_in;
h=size(img_in,1);
w=size(img_in,2);
th = pi/4;
R=[cos(th) -sin(th) 0 ; sin(th) cos(th) 0 ; 0 0 1];
T=[1 0 (-w/2) ; 0 1 (-h/2) ; 0 0 1];
F=inv(T)*R*T;
img_out=zeros(h,w,3);
%Rotate image
for i=1:w
for j=1:h
x = [i ; j ; 1];
y = F * x;
a = y(1)/y(3);
b = y(2)/y(3);
a = round(a);
b = round(b);
if (a>0 && a<=w && b>0 && b<=h)
img_out(j,i,:)=img_in(b,a,:);
end
end
end
figure;imshow(img_out);
%Rotate back
%---------------------------------------------------------
img_in = img_out;
img_out = zeros(h,w,3);
%Inverse transformation matrix.
F = inv(F);
%Rotate image (back)
for i=1:w
for j=1:h
x = [i ; j ; 1];
y = F * x;
a = y(1)/y(3);
b = y(2)/y(3);
a = round(a);
b = round(b);
if (a>0 && a<=w && b>0 && b<=h)
img_out(j,i,:)=img_in(b,a,:);
end
end
end
figure;imshow(img_out);
img_diff = abs(orig_in - img_out);
figure;imshow(img_diff);
img_diff image:

zero padding zoom fourier

I'm trying to implement a zero padding zoom using fourier.
I'm using octave and I can't add zeros around my matrix.
The result (after inverse fourier transformation) is very dark.
My goal:
My code:
I=double(imread('montagne.jpeg'));
I = I/255;
%%scaling factor
facteur = 4;
[m,n,r] = size(I);
H=fft2(I);
H = fftshift(H);
%%the new image
B = zeros(facteur*m,facteur*n,3);
%%try to add zeros around my matrix
%% r : rgb channels
for r=1:3
for i=1:m
for j=1:n
B(i+((facteur*m)/4),j+((facteur*n)/4),r) = H(i,j,r);
end
end
end
%% show the image
B= ifftshift(B);
final = ifft2(B);
figure;
imshow(final);
Any suggestions ?
Don't use for-loops to copy matrices. I would try something like:
I = im2double (imread ('IMG_2793.JPG'));
facteur = 4; %%scaling factor
[m, n, r] = size (I);
H = fftshift (fft2 (I));
B = zeros(facteur*m, facteur*n, 3);
ms = round (m * (facteur/2 - 0.5));
ns = round (n * (facteur/2 - 0.5));
B(ms:(m+ms-1), ns:(n+ns-1), :) = H;
final = abs (ifft2 (ifftshift (B)));
figure;
imshow(final * facteur^2);
EDIT:
Btw, there is also the function padarray which does what you want:
octave:1> padarray (magic(3), [1, 1])
ans =
0 0 0 0 0
0 8 1 6 0
0 3 5 7 0
0 4 9 2 0
0 0 0 0 0

Convert RGB to HSV

i want to convert RGB values to HSV values . But if I devide 9 by 28, octave calculate 0. Can anyone explain me the reason??
function [hsv] = RGBtoHSV()
im = imread('picture.png');
R = im(:,:,1);
G = im(:,:,2);
B = im(:,:,3);
len = length(R); % R, G, B should have the same length
for i = 1:len
MAX = max([R(i),G(i),B(i)]);
MIN = min([R(i),G(i),B(i)]);
S = 0;
if MAX == MIN
H = 0;
elseif MAX == R(i)
disp(G(i) - B(i)); % 9
disp(MAX - MIN); % 28
H = 0.6 * ( 0 + ( (G(i) - B(i)) / MAX - MIN) ); % 0
disp(H) % why i get 0 if try to calculate ( 0 + ( (G(i) - B(i)) / MAX - MIN)?
....
end
return;
end
endfunction
RGBtoHSV()
Chris :D
You must cast the image into Double by doing:
im = double(imread('picture.png'));
This will solve your issues which happens since the image is type UINT8.
You can also use Octave's builtin rgb2hsv function instead of writing your own.
im_rgb = imread ("picture.png");
im_hsv = rgb2hsv (im_rgb);
If this is an exercise, then I'd suggest you look at its source, enter type rgb2hsv at the Octave prompt, and see how its implemented.

Resources