I'm trying to calculate the contrast of the image 'tire.tif' in Matlab using this formula Contrast formula
I did this little program in Matlab with two methods. The problem is that I don't get the same result. Can someone check my code and tell me what did I do wrong.
[M,N]=size(I);
Lumi=1/(M*N)*sum(I(:)); % which gives 53.66
Cont_method1=sqrt(1/(N*M)*sum(I(:)-Lumi)^2); % gives 5.478+03
Cont_method2=sqrt(1/prod(size(I))*sum(power((I(:)-Lumi),2))); % gives 9.0292
Your first method,
Cont_method1 = sqrt(
1/(N*M) * sum(
I(:)-Lumi
)^2
);
computes the sum of I(:)-Lumi, then squares the sum. The equation you link takes the sum of squares:
Cont_method1 = sqrt(
1/(N*M) * sum(
( I(:)-Lumi )^2
)
);
This is equivalent to your second method:
Cont_method2 = sqrt(
1/prod(size(I)) * sum(
power( ( I(:)-Lumi ), 2 )
)
);
Note that N*M and prod(size(I)) are the same thing, and both equivalent to the more efficient numel(I). And note that dividing the sum by the number of elements is the same as computing the mean using mean. So you can simplify:
Cont_method3 = sqrt( mean( ( I(:)-Lumi )^2 ));
But note that all you're doing here is computing a scaled norm:
Cont_method4 = norm(I(:)-Lumi) / sqrt(numel(I));
Related
I'm having trouble plotting a set of complex numbers in maple.
I know what it should look like from a drawing I produced but I'd like to plot it in maple. My code is as follows;
z := x + I*y;
plots:-implicitplot([abs(z) <= 2, abs(z) >= 1, abs(arg(z)) >= Pi/4,
abs(arg(z)) <= Pi/2], x = -3...3, y = -3...3, filled = true);
The issue is that the inequalities are being plotted independently of each other rather than all together, so even the first pair of inequalities together fill the entire plane. Is there any way I can have the $4$ conditions imposed in $S$ be taken into account at the same time, rather than separately?
Didn't you mean for the second inequality to be reversed? Otherwise the first is redundant.
The command that you need is inequal, not implicitplot. Your args should be arguments. Your z expressions should be wrapped in evalc. (I don't why that's necessary, but it seems to be.) There's no need for filled= true. So, the command is
plots:-inequal(
[evalc(abs(z)) <= 2, evalc(abs(z)) >= 1,
evalc(abs(argument(z))) >= Pi/4, evalc(abs(argument(z))) <= Pi/2
], x = -3...3, y = -3...3
);
Sometimes using plots:-inequal takes a long time, in those cases I just use plots:-implicitplot with filledregions = true option. But I don't use a list of inequalities as its argument. For one plot only, implicitplot needs one equation/inequality, so what function can you use that gives you the intersection of regions for your inequalities? Very simple, just define a binary piecewise function with piecewise command. Here is how I do your plot.
f := piecewise( And( abs( x + y*I ) <= 2, abs( x + y*I ) >= 1, abs( argument( x + y*I ) ) >= Pi/4, abs( argument( x + y*I ) ) <= Pi/2 ), 1, 0 );
plots:-implicitplot( f > 1/2, x = -3..3, y = -3..3, filledregions = true, coloring = [yellow, white], view = [-3..3, -3..3] );
The output plot is the following.
Note that plots:-inequal gives a more accurate output, but plots:-implicitplot takes less time, so you should consider the trade-off between them and see which is better on your specific example.
I am using PCA before feeding the training set into a neural network. It reduces 13 features down to 8 and trains over 2200 training sets. The MAPE I get with this is close to 2.5 - 2.6 %.
If I train the raw data with simple feedforwardnet, I get a lower error of 2.1%.
I am suffering from a similar situation in a different problem, where I have close to 50000 training sets where PCA gives 2.5% error and simple ANN gives me ~2% MAPE.
What is the reason behind this? Is this a normal occurrence? Can you give me any way by which I can reduce the error? I am trying to forecast the electric load demand on the basis of weather and previous load data.
EDIT: (Added Scree Plot )
I had the same problem as you back a few Months ago but with SVMs instead of NNs. So the reason why you're getting such poor results is because you haven't normalized your data before feeding it into the PCA function. You can do this using Matlab's mapminmax function. Since mapminmax noramlizes the rows, you need to do a transpose of the input and output as follows.
[normX,PS] = mapminmax( X' );
normX = normX';
max( normX ) % Returns 1
min( normX ) % Returns -1
To plot the scree plot, you can use this code.
[C,~,~,~,explained] = pca( normX );
figure; plot( explained );
This is the Scree plot. You can probably keep the first 5 components of your data.
After you perform the minmax mapping, you can feed it into your NN as follows. This assumes you want to keep PC 1-5.
trainX = normX * C(:,1:5);
Now if you ever need to transform your noramlized data back to
returnedX = mapminmax( 'reverse', normX', PS );
returned = returnedX';
Collectively your code should be as follows
% Normalize Data
[normX,PS] = mapminmax( X' );
normX = normX';
max( normX ) % Returns 1
min( normX ) % Returns -1
% Perform PCA
[C,~,~,~,explained] = pca( normX );
figure; plot( explained );
% Transform Data
trainX = normX * C(:,1:5);
EDIT: Performance
The code I used to test performance is below.
clear all
load input
load output
% Normalize Data
[normX,PS] = mapminmax( X' );
normX = normX';
max( normX ) % Returns 1
min( normX ) % Returns -1
% Perform PCA
[C,~,~,~,explained] = pca( normX );
figure; plot( explained );
% Transform Data
trainX1 = normX(1:1826,:) * C(:,1:5);
trainX2 = X(1:1826,:);
trainY = dailyPeakLoad(1:1826);
testX1 = normX(1827:end,:) * C(:,1:5);
testX2 = X(1827:end,:);
testY = dailyPeakLoad(1827:end);
netFeb = newfit(trainX1', trainY', 35);
netFeb.performFcn = 'mae';
netFeb = trainlm(netFeb, trainX1', trainY');
forecastLoadFeb = sim(netFeb, testX1')';
errFeb = testY - forecastLoadFeb;
errpct = abs(errFeb)./testY*100;
MAPEFeb = mean(errpct(~isinf(errpct)));
netFeb2 = newfit(trainX2', trainY', 35);
netFeb2.performFcn = 'mae';
netFeb2 = trainlm(netFeb2, trainX2', trainY');
forecastLoadFeb2 = sim(netFeb2, testX2')';
errFeb2 = testY - forecastLoadFeb2;
errpct2 = abs(errFeb2)./testY*100;
MAPEFeb2 = mean(errpct(~isinf(errpct2)));
The trained NN are here. This is the one with PCA.
This is the one without PCA.
Note that performance is different because of initial values and number of iterations.
Is there any function in Matlab like conv(u,v) but that sums up 'u(x)' and 'v(x)' instead of multiplying them?
Imagine:
u(x) = 66*(x-6)
v(x) = 6*(x-9)
Applying this "wanted function"...
sum = wantedfunction(u,v)
So,
sum(x) = 66*(x-6) + 6*(x-9)
Any ideas?
I believe you can do what you are asking for using anonymous functions:
u = #( x ) ( 66 * (x - 6) );
v = #( x ) ( 6 * (x - 9) );
w = #( x ) ( u(x) + v(x) );
This makes w the "sum" function you wanted - if I understood your question correctly.
Example: after I keyed in the above, I found
w(1:5)
Gave
-378 -306 -234 -162 -90
It's possible I completely missed the point of your question - if so, please leave a comment.
If by "conv" function you mean convolution then the equivalent of that for your case is simply adding two functions you want and then multiply them by delta(your desired spacing on x axis) and then sum over that, gives your function. Still you need to iterate this process by a "for" loop for different delays.
I need help debugging my median function under the if statement. I am getting an input error. Also if there is a simpler way to write the median function it will be greatly appreciated. I am writing this code to clean up the above image for a project. Thanks. Also, I am pretty new with MATLAB.
``clear
clc
format compact
filenameIN = uigetfile('.bmp','Picture');
noisyRGBarray = imread(filenameIN);
%figure(1)
%imshow(noisyRGBarray)
y = noisyRGBarray;
[m,n]=size(y)
cleanRGBarray = y;
for i = 2:m-1
for j = 2:n-1
if y(i,j) == 0 | y(i,j) == 255 % clean add new
cleanRGBarray(i,j) = median( ( y ( (i-1),(j-1) ) ) , ( y ( (i-1),(j) ) ) , ( y ( (i-1),(j+1) ) ) ; ( y ( (i),(j-1) ) ), ( y ( (i),(j) ) ) ; ( y ( (i),(j+1) ) ) ; ( y ( (i+1),(j-1) ) ), ( y ( (i+1),(j) ) ), ( y ( (i+1),(j+1) ) ) ) ;
end
end
end
You are making this very hard on yourself! The simplest way to re formulate the innermost loop is
block = y((-1:1)+i, (-1:1)+j);
cleanRGBarray(i,j) = median(block(:));
A couple of things to note:
You attempted to create a vector of arguments for median but didn't surround it with []
I used the fact that when indexing over more than one dimension, Matlab does "nested loops" to get all the numbers (so my block variable ends up being 3x3)
I feed a column vector block(:) with dimensions 9x1 into median - if you give it an N dimensional matrix, it will operate on the first non-singleton dimension only (so give it 3x3 and it returns 1x3 medians)
There are techniques for doing this much more efficiently - built in median filters, and things like blockproc - but you need the Image Processing Toolbox for those.
I hope this helps a bit.
matlab has a built-in median filter medfilt2 you can also try ordfilt2
Is the following code a correct way of calculating PSNR for grayscale images in Matlab?
function p = psnr(x,y, vmax)
if nargin<3
m1 = max( abs(x(:)) );
m2 = max( abs(y(:)) );
vmax = max(m1,m2);
end
d = mean( (x(:)-y(:)).^2 );
p = 10*log10( vmax^2/d );
For 8-bit input, vmax=255.
Yes, according to the Wikipedia article about Peak signal-to-noise ratio, your code is a faithful implementation of PSNR; it corresponds directly to the first definition given there.
In case vmax is not given, you could also imagine using intmax to determine it for a given data type (depending on your application; your implementation also makes sense).