Matlab Stepinfo Function - matlab

S = stepinfo(Y,T,180,'SettlingTimeThreshold',ST) ;
ts=S.SettlingTime;
in this does it mean ts is the time at which |Y-180| becomes less than ( ST/100 )or something else...
in my code though |Y-180| is less than ST/100 but i am getting ts = NAN;
pls help me out
My code:
if ee(end)>160
S = stepinfo(ee,times,180,'SettlingTimeThreshold',0.01);
else
S = stepinfo(ee,times,0.5,'SettlingTimeThreshold',1);
end
settling_time = S.SettlingTime;
end
where 'ee' is an array of values at each 'times'
ee is basically error angle which becomes 180 or 0 after some time..
thanks

From the help:
The response has settled when the error |y(t) - yfinal| becomes
smaller than a fraction ST of its peak value.
This means that it's the fraction of the peak error value, not an absolute threshold - e.g. if your system was something that started at around 30, and eventually rose and settled at near 180 (yfinal = 180), then the max error is 150, and the threshold would be 0.01*150 = 1.5. So it would need to get to 178.5 (180-1.5).
If your system started at 100 and settled at about 180, your max error is 80, and the threshold is then only 0.8, so your value needs to be at 179.2.
Look at what your min(ee) and max(ee) are and then decide on what a sensible threshold is.
EDIT:
If you want to set a fixed threshold you'll have to calculate it on the fly:
desiredthreshold = 1.8 % absolute value, e.g. 0.01*180
maxerror = 180-min(ee); % assuming your values are all between 0 and 180
actualthreshold = 1.8/maxerror; %if your min value is 0 then this goes to 0.01, otherwise it will be larger

Related

Calculate hue angle range for red colours

I'm trying to correctly calculate colour hue angle range. Given an input default hue say 120 and a threshold value of 20 the range is between 100 - 140 (yes, I know - complex math).
Now in the application, when filtering an image, I can check if a given pixel falls into that range:
let inputHue = 120
let threshold = 20
let minHue = inputHue - threshold // 100
let maxHue = inputHue + threshold // 140
if (pixelHue > minHue && pixelHue < maxHue) {
// do something
}
Now the problem is with red colours range where the most saturated red colour is at 0/360 on the colour wheel. Given an input hue of 10 the minHue is now -10 (with a threshold of 20) and maxHue is 30. Because of that negative value for minHue the condition fails:
let pixelHue = 355 // this falls into a valid red range I want to get
let minHue = -10
let maxHue = 30
if (pixelHue > minHue && pixelHue < maxHue) {
// do something
}
Does anyone know how to tackle this problem of a colour wheel? I'm trying to develop a general solution that would work for any given input hue (not only red colours).
Thanks in advance.
Hues should be considered modulo 360. Hence the range for red is 0-30 AND 350-360.
Now your value of 355 passes because (355>350 AND 355<30) OR (350>30 AND (355>350 OR 355<30)).
The critical bit here starts after the first OR. In normal arithmetic, you check against lower and upper bound, and you have to pass both tests. But in modular arithmetic, if the lower bound is higher than the upper bound, the range wraps around 0 and you only need to pass one of the two both tests.
To recap: (hue>min AND hue<max) OR (min>max AND (hue>min OR hue<max))
A possible approach: Imagine both hue values as points on a circle, and compare the "shorter" angular distance between these points with the threshold:
let diff = abs(pixelHue - inputHue)
if min(diff, 360 - diff) <= threshold {
// do something
}

How do I combine tf.absolute and tf.square to create the Huber loss function in Tensorflow?

To be precise, the loss function that I'm looking for is the squared error when the absolute error is lesser than 0.5, and it is the absolute error itself, when the absolute error is greater than 0.5. In this way, the gradient from the error function doesn't exceed 1 because once the gradient of the squared error function reaches 1, the absolute error function kicks in, and the gradient remains constant at 1. I've included my current implementation below. For some reason, it's giving me worse performance than just the squared error.
fn_choice_maker1 = (tf.to_int32(tf.sign(y - y_ + 0.5)) + 1)/2
fn_choice_maker2 = (tf.to_int32(tf.sign(y_ - y + 0.5)) + 1)/2
choice_maker_sqr = tf.to_float(tf.mul(fn_choice_maker1, fn_choice_maker2))
sqr_contrib = tf.mul(choice_maker_sqr, tf.square(y - y_))
abs_contrib = tf.abs(y - y_)-0.25 - tf.mul(choice_maker_sqr, tf.abs(y - y_)-0.25)
loss = tf.reduce_mean(sqr_contrib + abs_contrib)
train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)
choice_maker_sqr is a column tensor that is one whenever the error is between 0.5 and -0.5. The names are pretty self explanatory.
Here is my implementation of the Huber loss function in python tensorflow:
def huber_loss(y_true, y_pred, max_grad=1.):
"""Calculates the huber loss.
Parameters
----------
y_true: np.array, tf.Tensor
Target value.
y_pred: np.array, tf.Tensor
Predicted value.
max_grad: float, optional
Positive floating point value. Represents the maximum possible
gradient magnitude.
Returns
-------
tf.Tensor
The huber loss.
"""
err = tf.abs(y_true - y_pred, name='abs')
mg = tf.constant(max_grad, name='max_grad')
lin = mg*(err-.5*mg)
quad=.5*err*err
return tf.where(err < mg, quad, lin)
You can use tf.select to implement it in a single call:
err = y - y_
huber_loss = tf.select(tf.abs(err) < 1.0,
0.5 * tf.square(err),
tf.abs(err) - 0.5) # if, then, else
err = tf.subtract(x,y)
huber_loss = tf.where(tf.less(x,y),
tf.sqrt(tf.square(err)),
tf.abs(err))
with tf.Session() as sess:
print(sess.run(tf.reduce_mean(huber_loss)))
Not sure if this is still relevant, but I would like to point it out to those seeking this in the future. The tensorflow research losses script has an implementation of the Huber loss for Object detection (like its implemented in the FasterRCNN paper)
Here's the link to the method

Tuning Gabor filter

I am trying to seek out pathologies in pictures of noisy vertical stacked layers
with Gabor filtering. For each column, i regard the neigborhood with 10 pixels to the left and right and filter the part of the image with the gabor kernel. Then I take the frobenious norm, so that I have for each column a scalar value.
Here is my result using that image posted below. For me it seems counterintuitive that the response of 0 degree is that much higher than the response of 45 degrees.
But the desired effect is satisfied, meaning that i can state a condition such that the pathology near the 300th column is hit using that the value of 0 degrees is below the value of 45 degrees.
I expected the other way round or is my image just too noisy?
So my questions are: How can I refine the parameter lambda and gamma to maximize the effect when the structure of vertcal stacked layers are broken?(in the middle of the picture around column 290 - 320)
When I tried to change parameters I got too much false positives such that i can not distinguish anymore.
And how can it be that the values of 0 degree is that greater than the filter response of 45 degrees? For me it seems very odd considering that image.
================
Here is the image
Here is my code
windowRadius = 10;
bw = 1;
for k=0:23
theta(k+1)= k*pi/12;
end
psi = [0 pi/2];
lambda = 8; % std value 8
gamma = 0.5; % std value 0.5
for colIndx=1: size(Img,2)
if colIndx-windowRadius < 1
left = 1;
else
left = colIndx - windowRadius;
end
if colIndx+windowRadius > size(Img,2)
right = size(Img,2);
else
right = colIndx + windowRadius;
end
for i=1:length(theta)
gb{i} = gabor_fn(bw,gamma,psi(1),lambda,theta(i)) ...
+ 1i * gabor_fn(bw,gamma,psi(2),lambda,theta(i));
end
gabor_out0deg{colIndx} = imfilter(Img(:, left : right),gb{1},'symmetric');
gabor_out45deg{colIndx} = imfilter(Img(:, left : right),gb{4},'symmetric');
gabor_out90deg{colIndx} = imfilter(Img(:, left : right),gb{7},'symmetric');
gaborFroNorm0deg(colIndx) = norm(gabor_out0deg{colIndx},'fro') / ((right - left) * size(Img,1));
gaborFroNorm45deg(colIndx)= norm(gabor_out45deg{colIndx},'fro') / ((right - left) * size(Img,1));
gaborFroNorm90deg(colIndx)= norm(gabor_out90deg{colIndx},'fro') / ((right - left) * size(Img,1));
end

Rotation of image manually in matlab

I am trying to rotate the image manually using the following code.
clc;
m1 = imread('owl','pgm'); % a simple gray scale image of order 260 X 200
newImg = zeros(500,500);
newImg = int16(newImg);
rotationMatrix45 = [cos((pi/4)) -sin((pi/4)); sin((pi/4)) cos((pi/4))];
for x = 1:size(m1,1)
for y = 1:size(m1,2)
point =[x;y] ;
product = rotationMatrix45 * point;
product = int16(product);
newx =product(1,1);
newy=product(2,1);
newImg(newx,newy) = m1(x,y);
end
end
imshow(newImg);
Simply I am iterating through every pixel of image m1, multiplying m1(x,y) with rotation matrix, I get x',y', and storing the value of m1(x,y) in to `newImg(x',y')' BUT it is giving the following error
??? Attempted to access newImg(0,1); index must be a positive integer or logical.
Error in ==> at 18
newImg(newx,newy) = m1(x,y);
I don't know what I am doing wrong.
Part of the rotated image will get negative (or zero) newx and newy values since the corners will rotate out of the original image coordinates. You can't assign a value to newImg if newx or newy is nonpositive; those aren't valid matrix indices. One solution would be to check for this situation and skip such pixels (with continue)
Another solution would be to enlarge the newImg sufficiently, but that will require a slightly more complicated transformation.
This is assuming that you can't just use imrotate because this is homework?
The problem is simple, the answer maybe not : Matlab arrays are indexed from one to N (whereas in many programming langages it's from 0 to (N-1) ).
Try newImg( max( min(1,newX), m1.size() ) , max( min(1,newY), m1.size() ) ) maybe (I don't have Matlab at work so I can tell if it's gonna work), but the resulting image will be croped.
this is an old post so I guess it wont help the OP but as I was helped by his attempt I post here my corrected code.
basically some freedom in the implementation regarding to how you deal with unassigned pixels as well as wether you wish to keep the original size of the pic - which will force you to crop areas falling "outside" of it.
the following function rotates the image around its center, leaves unassigned pixels as "burned" and crops the edges.
function [h] = rot(A,ang)
rotMat = [cos((pi.*ang/180)) sin((pi.*ang/180)); -sin((pi.*ang/180)) cos((pi.*ang/180))];
centerW = round(size(A,1)/2);
centerH = round(size(A,2)/2);
h=255.* uint8(ones(size(A)));
for x = 1:size(A,1)
for y = 1:size(A,2)
point =[x-centerW;y-centerH] ;
product = rotMat * point;
product = int16(product);
newx =product(1,1);
newy=product(2,1);
if newx+centerW<=size(A,1)&& newx+centerW > 0 && newy+centerH<=size(A,2)&& newy+centerH > 0
h(newx+centerW,newy+centerH) = A(x,y);
end
end
end

Changing Auriotouch Linear scale to logarithmic

I don't know if this is even possible to do, but thought I would ask, I suspect that if it is possible, it would be changed in the - (void) renderFFTToTex routine. Does anybody have any ideas about doing this or other suggestions that they could recommend? Thank you.
To rescale the frequency, we need to scale this parameter:
CGFloat yFract = (CGFloat)y / (CGFloat)(maxY - 1);
which has a value between 0..1, and determines which fft output to take to display on display line y.
To get a logarithmic scale, first do the math: a frequency f (0.1kHz-20kHz) must be displayed on a position log(f). Call the low bound (0.1kHz) L, the high bound (20kHz) H. Then after some math [[skipped]] you get:
yFract = ( exp(yFract*log(H/L)) - 1 ) / ( H/L - 1 );
where you should fill in what you think is the H/L ratio, e.g.
yFract = ( exp(yFract*log(20)) - 1 ) / ( 20 - 1 );
(you should check if 0 gives 0 and 1 gives 1, which is the case)