Related
OK, we have an image and (0,1,2,3,4,5,6,7) - as images, we need to show image that we have got, next right, the image that got redrawn by numbers (0,1,2,3,4,5,6,7), third on right, is pallete (0,1,2,3,4,5,6,7) and boxes with color.
a) Upload JPEG image. Choose amount rows M and amount columns N for drawing grid. Change image size for required size of grid.
b) Convert image .JPEG in indexed image with 8 colors and show it up as on picture.
c) Prepare image that shows color card.
d) Prepare image that shows grid and color numbers.
m = 80;
n = 60;
im = imresize(imread('1задание.jpg'), [m n] * 10, 'nearest');
small_im = imresize(im, [m n], 'nearest');
[X, map] = rgb2ind(small_im, 8);
big_small_im = im2uint8(ind2rgb(imresize(X, [m n] * 10, 'nearest'), map));
figure;
imshow([im ones(m * 10, 50, 3) * 255 big_small_im ones(m * 10, 50, 3) * 255 ...
generate_cool_map(map, m * 10)]);
digits = [];
for i = 0 : 7
digit = imread([int2str(i) '.png']);
digits = [digits digit];
end
pixel_s = 43;
final_im = im2uint8(ones(m * pixel_s, n * pixel_s, 3) * 255);
for i = 1 : m
for j = 1 : n
final_im((i - 1) * pixel_s + 1 : i * pixel_s, j * pixel_s, :) = zeros(pixel_s, 1, 3);
final_im(j * pixel_s, (j - 1) * pixel_s + 1 : j * pixel_s, :) = zeros(pixel_s, 1, 3);
final_im((i - 1) * pixel_s + 2 : (i - 1) * pixel_s + 2 + 39+4, (j - 1) * pixel_s + 2 : (j - 1) * pixel_s + 2 + 26, :) = digits(:, X(i, j) * 27 + 1 : (X(i, j) + 1) * 27, :);
end
end
figure;
imshow(final_im);
function res = generate_cool_map(map, s)
color_size = floor(s / 8);
m_map = zeros(8, 1, 3);
for i = 1 : 8
m_map(i, 1, :) = map(i, :);
end
res = imresize(m_map, [s, color_size], 'nearest');
res(:, 1:2, :) = zeros(s, 2, 3);
res(:, color_size - 1 : color_size, :) = zeros(s, 2, 3);
for i = 0 : 7
res(i * color_size + 1 : i * color_size + 2, :, :) = zeros(2, color_size, 3);
res(i * color_size + 1 + floor(color_size / 2) : i * color_size + 2 + ...
floor(color_size / 2),1:7,:) = zeros(2,7,3);
res(i * color_size + 1 + floor(color_size / 2) : i * color_size + 2 + ...
floor(color_size / 2), color_size - 6 : color_size, :) = zeros(2,7,3);
end
res(s - 1 : s, :, :) = zeros(2, color_size, 3);
res = [res ones(s, floor(color_size / 3), 3) * 255];
digits = [];
for i = 0 : 7
digit = imread([int2str(i) '.png']);
digits = [digits digit];
end
res = im2uint8(res);
for i = 0 : 7
res(i * color_size + floor(color_size / 3) : i * color_size + ...
floor(color_size / 3) + 39+4, color_size + 6 : color_size + 6 + 26, :) ...
= digits(:, i * 27 + 1 : (i + 1) * 27, :);
end
end
Task how shall look first figure:
I attempted but it seems here is some mistake. :c
Task how shall look second figure:
Figure 1: Resizing and Reducing Unique Colour Count
With the current amount of implementation details here is what I came up with. Resizing the image can be done using the imresize() function and 'nearest' neighbour interpolation. To reduce the number of colours the imapprox() function is used to limit the number of unique colours to 8. Reconstruction of the new image can be done using New_Image_Data (the colour card keys) and New_Colour_Map (the colour card values).
m = 50;
n = 60;
Original_Image = imread('peppers.png');
subplot(1,2,1); imshow(Original_Image);
title("Original Image");
Number_Of_Rows = m;
Number_Of_Columns = n;
%Resizing image%
Resized_Image = imresize(Original_Image,[m n],'nearest');
%Reducing the amount of colours%
Maximum_Intensity = 255;
[Image_Data,Colour_Map] = rgb2ind(Resized_Image,Maximum_Intensity);
[New_Image_Data,New_Colour_Map] = imapprox(Image_Data,Colour_Map,8);
subplot(1,2,2); imshow(New_Image_Data,New_Colour_Map);
title("Resized Image with 8 Colours");
Colour_Bar = colorbar;
set(Colour_Bar,'YTick',(0:7));
Figure 2: Plotting the Grid of Values
%Plotting the grid of card colour values%
Figure_2 = figure(2);
clf;
Figure_2.Position = [0 0 700 700];
x = (0:Number_Of_Rows);
y = (0:Number_Of_Columns);
[X,Y] = meshgrid(x,y);
Z = ones(length(x),length(y)).';
mesh(Y,X,Z);
axis off
hold on
view(0,90);
Image_Data = flip(New_Image_Data);
title("Colour Card Values/Keys");
for Row_Index = 1: Number_Of_Rows
for Column_Index = 1: Number_Of_Columns
text(Column_Index-0.5,Row_Index-0.5,num2str(Image_Data(Row_Index,Column_Index)));
end
end
Ran using MATLAB R2019b
I am trying to implement Floyd Steinberg Dithering in MATLAB, using the pseudocode on the Wikipedia page https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering
My code is below
image = double(imread("dithering.jpg")) ./ 255;
levels = 2;
image_quantised = round(image .* (levels - 1)) ./ (levels - 1);
error = image - image_quantised;
height = size(image(:, :, 1), 1);
width = size(image(:, :, 1), 2);
image_dithered = image_quantised;
for y = 1:height - 1
for x = 2:width - 1
image_dithered(y , x + 1, :) = image_dithered(y , x + 1, :) + error(y, x, :) .* 7 / 16;
image_dithered(y + 1, x - 1, :) = image_dithered(y + 1, x - 1, :) + error(y, x, :) .* 3 / 16;
image_dithered(y + 1, x , :) = image_dithered(y + 1, x , :) + error(y, x, :) .* 5 / 16;
image_dithered(y + 1, x + 1, :) = image_dithered(y + 1, x + 1, :) + error(y, x, :) .* 1 / 16;
end
end
imshow(image_dithered) % Image 1
imshow(dither(mean(image, 3))) % Image 2
Image 1
Image 2
I am expecting the result in Image 2, but I am getting Image 1. It looks as though the algorithm isn't doing anything. Any ideas? :)
Edit: I have tried initialising image_dithered with different values; all zeros, the quantised image, and the original image. None of them work correctly
Edit 2: I'm getting closer by now calculating the error and quantisation within the loop. Still not spot on however.
for y = 1:height - 1
for x = 2:width - 1
new_pixel = round(image_dithered(y, x, :) .* (levels - 1)) ./ (levels - 1);
image_dithered(y, x, :) = new_pixel;
error = image(y, x, :) - new_pixel;
image_dithered(y , x + 1, :) = image_dithered(y , x + 1, :) + error .* 7 / 16;
image_dithered(y + 1, x - 1, :) = image_dithered(y + 1, x - 1, :) + error .* 3 / 16;
image_dithered(y + 1, x , :) = image_dithered(y + 1, x , :) + error .* 5 / 16;
image_dithered(y + 1, x + 1, :) = image_dithered(y + 1, x + 1, :) + error .* 1 / 16;
end
end
Edit 3: Thanks for the #saastn and #Cris Luengo, both of the answers helped me work out where I was going wrong and it appears to be working as expected now!
The fixed code is below for completeness.
height = size(image(:, :, 1), 1);
width = size(image(:, :, 1), 2);
image_dithered = image;
for y = 1:height - 1
for x = 2:width - 1
old_pixel = image_dithered(y, x, :);
new_pixel = round(image_dithered(y, x, :) .* (levels - 1)) ./ (levels - 1);
image_dithered(y, x, :) = new_pixel;
error = old_pixel - new_pixel;
image_dithered(y , x + 1, :) = image_dithered(y , x + 1, :) + error .* 7 / 16;
image_dithered(y + 1, x - 1, :) = image_dithered(y + 1, x - 1, :) + error .* 3 / 16;
image_dithered(y + 1, x , :) = image_dithered(y + 1, x , :) + error .* 5 / 16;
image_dithered(y + 1, x + 1, :) = image_dithered(y + 1, x + 1, :) + error .* 1 / 16;
end
end
imshow(image_dithered)
imshow(dither(mean(image, 3)))
The problem is that you tried to improve the pseudocode and remove oldpixel! Note that the algorithm does not calculate an error between the quantized pixel and its corresponding value in the original image, but rather the error between the quantized pixel and the previous value in the dithered image, which may have been updated while scanning the previous pixels.
Bring oldpixel back and review the whole algorithm one more time.
But even after the modifications, you can not expect the results to match the MATLAB output, which could be the result of differences in the details of the two implementations.
You’re propagating errors in image_quantized instead of in the original image. Remove this quantized image, it is not part of the algorithm.
You need to quantize one pixel, then find the difference with the original value, and propagate that error into future pixels.
Note that Wikipedia pseudocode does this in-place, there is only one copy of the image that works as both input and output.
On this old blog post of mine has MATLAB code for Floyd-Steinberg dithering.
Assuming you first follow saastn's answer (and replying to what it says about the differences between those images) : I'd say that by just looking at them in saastn's image, Matlab's patterns look like they're a sideways version of Floyd-Steinberg here, either by rotation, or more probably by transposition (swap x with y, which is a reflexion across the x+y diagonal axis). This can't be imitated by just changing coefficients, the image has to be processed by columns ("for x" outside of "for y", etc).
I am new to matlab and am trying to loop through an equation from 1 to 1000 and plot the result, but every value is turning out the same and the plot is incrorrect.
Here is my current attempt, but the variable Rm is giving only one results (instead of 1000 separate ones):
Ds = 1.04e-10;
Gamma = 1.9;
Omega = 1.09e-29;
Deltas = 2.5e-10;
Boltzmann = 1.3806e-23;
T = 1123.15;
Beta = 0.83;
Zo = 6.7;
EtaNi = 0.39;
EtaYSZ = 0.61;
Rm0 = 0.29;
RmYSZ0 = 0.265;
lambda = 4.70e-3;
C = Ds * ((Gamma * Omega * Deltas) / (2 * Boltzmann * T)) * (Beta / ((1 - Beta^2) * ((1 + Beta^2)^0.5) * ((1 + Beta)^3))) * Zo * (EtaNi/((EtaNi/Rm0) + (EtaYSZ/RmYSZ0)));
tinit=1; % Initial time value (h)
tend=1000; % End time value (h)
tinc=1; % Increment in time value (h)
t= [tinit:tinc:tend]; % Time vector
n = 1000;
for i=1:n
Rm(i) = (((5*C)/lambda) * (1 - exp(-lambda*i)) + (Rm0)^5)^(1/5);
end
plot(t,Rm);
Expected result is an exponential curve, any help would be appreciated
Your term before R0 is an exponential that ranges from 0 to 4.5e-27. R0^5 is 0.0021. Floating point precision is not enough to preserve the first term when it is added to the second. So (5C/L*(...) + Rm0^5) == Rm0^5, so it is constant.
So I have the following code:
if tau_a == tau_b
ana_nb = NB * exp(-t/tau_a) + t * (NA/tau_a) * exp(-(t/tau_a))
else
ana_nb = NB * exp(-t/tau_b) + NA/((tau_a/tau_b)-1) * (exp(-t/tau_a) - exp(-t/tau_b))
end
Here NA = 100, NB = 80, tau_a = 2, tau_b = 4, t is an array of numbers (with a size of 21)
The error message I get is: "Error using *. Inner matrix dimensions must agree."
How do I fix this?
You will have to use element wise multiplication .*
ana_nb = NB .* exp(-t/tau_a) + t .* (NA/tau_a) .* exp(-(t/tau_a))
The Octave radix-4 FFT code below works fine if I set power of 4 (xp) values case-by-case.
$ octave fft4.m
ans = 1.4198e-015
However, if I uncomment the loop code I get the following error
$ octave fft4.m
error: `stage' undefined near line 48 column 68
error: evaluating argument list element number 1
error: evaluating argument list element number 2
error: called from:
error: r4fftN at line 48, column 22
error: c:\Users\david\Documents\Visual Studio 2010\Projects\mv_fft\fft4.m at line 80, column 7
the "error" refers to a line the in fft function code which otherwise works correctly when xp is not set by a loop ... very strange.
function Z = radix4bfly(x,segment,stageFlag,W)
% For the last stage of a radix-4 FFT all the ABCD multiplers are 1.
% Use the stageFlag variable to indicate the last stage
% stageFlag = 0 indicates last FFT stage, set to 1 otherwise
% Initialize variables and scale to 1/4
a=x(1)*.25;
b=x(2)*.25;
c=x(3)*.25;
d=x(4)*.25;
% Radix-4 Algorithm
A=a+b+c+d;
B=(a-b+c-d)*W(2*segment*stageFlag + 1);
C=(a-b*j-c+d*j)*W(segment*stageFlag + 1);
D=(a+b*j-c-d*j)*W(3*segment*stageFlag + 1);
% assemble output
Z = [A B C D];
end % radix4bfly()
% radix-4 DIF FFT, input signal must be floating point, real or complex
%
function S = r4fftN(s)
% Initialize variables and signals: length of input signal is a power of 4
N = length(s);
M = log2(N)/2;
% Initialize variables for floating point sim
W=exp(-j*2*pi*(0:N-1)/N);
S = complex(zeros(1,N));
sTemp = complex(zeros(1,N));
% FFT algorithm
% Calculate butterflies for first M-1 stages
sTemp = s;
for stage = 0:M-2
for n=1:N/4
S((1:4)+(n-1)*4) = radix4bfly(sTemp(n:N/4:end), floor((n-1)/(4^stage)) *(4^stage), 1, W);
end
sTemp = S;
end
% Calculate butterflies for last stage
for n=1:N/4
S((1:4)+(n-1)*4) = radix4bfly(sTemp(n:N/4:end), floor((n-1)/(4^stage)) * (4^
stage), 0, W);
end
sTemp = S;
% Rescale the final output
S = S*N;
end % r4fftN(s)
% test FFT code
%
xp = 2;
% ERROR if I uncomment loop!
%for xp=1:8
N = 4^xp; % must be power of: 4 16 64 256 1024 4086 ....
x = 2*pi/N * (0:N-1);
x = cos(x);
Y_ref = fft(x);
Y = r4fftN(x);
Y = digitrevorder(Y,4);
%Y = bitrevorder(Y,4);
abs(sum(Y_ref-Y)) % compare fft4 to built-in fft
%end
The problem was the loop-bound for the exponent xp should start from 2 as the fft4 code assumes at least 2 stages of radix-4 butterflies
Sorry folks :(
-David
Please find below a fully worked Matlab implementation of a radix-4 Decimation In Frequency FFT algorithm. I have also provided an overall operations count in terms of complex matrix multiplications and additions. It can be indeed shown that each radix-4 butterfly involves 3 complex multiplications and 8 complex additions. Since there are log_4(N) = log_2(N) / 2 stages and each stage involves N / 4 butterflies, so the operations count is
complex multiplications = (3 / 8) * N * log2(N)
complex additions = N * log2(N)
Here is the code:
% --- Radix-2 Decimation In Frequency - Iterative approach
clear all
close all
clc
% --- N should be a power of 4
N = 1024;
% x = randn(1, N);
x = zeros(1, N);
x(1 : 10) = 1;
xoriginal = x;
xhat = zeros(1, N);
numStages = log2(N) / 2;
W = exp(-1i * 2 * pi * (0 : N - 1) / N);
omegaa = exp(-1i * 2 * pi / N);
mulCount = 0;
sumCount = 0;
M = N / 4;
for p = 1 : numStages;
for index = 0 : (N / (4^(p - 1))) : (N - 1);
for n = 0 : M - 1;
a = x(n + index + 1) + x(n + index + M + 1) + x(n + index + 2 * M + 1) + x(n + index + 3 * M + 1);
b = (x(n + index + 1) - x(n + index + M + 1) + x(n + index + 2 * M + 1) - x(n + index + 3 * M + 1)) .* omegaa^(2 * (4^(p - 1) * n));
c = (x(n + index + 1) - 1i * x(n + index + M + 1) - x(n + index + 2 * M + 1) + 1i * x(n + index + 3 * M + 1)) .* omegaa^(1 * (4^(p - 1) * n));
d = (x(n + index + 1) + 1i * x(n + index + M + 1) - x(n + index + 2 * M + 1) - 1i * x(n + index + 3 * M + 1)) .* omegaa^(3 * (4^(p - 1) * n));
x(n + 1 + index) = a;
x(n + M + 1 + index) = b;
x(n + 2 * M + 1 + index) = c;
x(n + 3 * M + 1 + index) = d;
mulCount = mulCount + 3;
sumCount = sumCount + 8;
end;
end;
M = M / 4;
end
xhat = bitrevorder(x);
tic
xhatcheck = fft(xoriginal);
timeFFTW = toc;
rms = 100 * sqrt(sum(sum(abs(xhat - xhatcheck).^2)) / sum(sum(abs(xhat).^2)));
fprintf('Theoretical multiplications count \t = %i; \t Actual multiplications count \t = %i\n', ...
(3 / 8) * N * log2(N), mulCount);
fprintf('Theoretical additions count \t\t = %i; \t Actual additions count \t\t = %i\n\n', ...
N * log2(N), sumCount);
fprintf('Root mean square with FFTW implementation = %.10e\n', rms);