Fail to use Screen('Preference') in PsychToolbox for MATLAB - matlab

In PsychToolbox for MATLAB, I try to put
Screen('Preference', 'SyncTestSettings', maxStddev = 0.001, minSamples = 50, maxDeviation = 0.1, maxDuration = 5);
in the MATLAB command window, but it keeps to tell me:
Error in function Preference: Extra input argument described
Error using Screen
Usage:
oldPreferenceValue = Screen('Preference', preferenceName,
[newPreferenceValue])
I was confused. The document given by PsychToolbox is:
[maxStddev, minSamples, maxDeviation, maxDuration] = Screen('Preference',
'SyncTestSettings' [, maxStddev=0.001 secs][, minSamples=50][,
maxDeviation=0.1][, maxDuration=5 secs]);
Is there anything I misunderstand the document? And what is the correct command?
(My MATLAB is R2021a, and PsychToolbox is 3.0.17.12)

What you are trying to accomplish can be done with the following command:
Screen('Preference', 'SyncTestSettings', 0.001, 50, 0.1, 5)
You have to provide these values in the correct order. If you wanted to skip over a value (i.e., leave it as is) then use
[]
like so:
Screen('Preference', 'SyncTestSettings', 0.001, [], 0.1, 5)

Related

Can I set step size of bounds for scipy differential optimization?

I used a optimization stratagy using scipy differential optimization
This is my code
bounds = [(-10.,3.), (-5.,5.), (-5.,5.)]
result = differential_evolution(t.findMax, bounds, maxiter=100)
Is there any way to set the step size of the bounds?
In my case, it is enough to check the step size 0.5
for example at bounds[1]
-5, -4.5, -4, -3.5, ... 4.5, 5
If it is possible it makes me save much time
Thanks

Dynamically setting a 'targetSize' for centerCropWindow2d()

Following the example from the documentation page of the centerCropWindow2d function, I am trying to dynamically crop an image based on a 'scale' value that is set by the user. In the end, this code would be used in a loop that would scale an image at different increments, and compare the landmarks between them using feature detection and extraction methods.
I wrote some test code to try and isolate 1 instance of this user-specified image cropping,
file = 'frameCropped000001.png';
image = imread(file);
scale = 1.5;
scaled_width = scale * 900;
scaled_height = scale * 635;
target_size = [scaled_width scaled_height];
scale_window = centerCropWindow2d(size(image), target_size);
image2 = imcrop(image, scale_window);
figure;
imshow(image);
figure;
imshow(image2);
but I am met with this error:
Error using centerCropWindow2d (line 30)
Expected input to be integer-valued.
Error in testRIA (line 20)
scale_window = centerCropWindow2d(size(image), target_size);
Is there no way to do use this function the way I explained above? If not, what's the easiest way to "scale" an image without just resizing it [that is, if I scale it by 0.5, the image stays the same size but is zoomed in by 2x].
Thank you in advance.
I didn't take into account that the height and width for some scales would NOT be whole integers. Since Matlab cannot crop images that are inbetween whole pixel numbers, the "Expected input to be integer-valued." popped up.
I solved my issue by using Math.floor() on the 'scaled_width' and 'scaled_height' variables.

How to label ('vertically') points in graph

I would like to add labels to some points plotted using the command scatter. For the sake of simplicity, let's say I have only one point:
x = 10;
pointSize = 100;
fontSize = 20;
P = scatter(x, 0, pointSize, [0,0,0], 'filled');
text(x, 0, 'pointLabel',...
'HorizontalAlignment', 'center',...
'VerticalAlignment', 'bottom',...
'FontSize', fontSize);
The problem with the previous commands is that the text pointLabel overlaps with the point P depending on the values assigned to the properties pointsize and fontSize.
I have read the documentation of the text command, but the examples only show how to put a label horizontally aligned with a specific point in the diagram. If the alignment needs to be horizontal it is easy, but I could not find a general way to compute the y coordinate of the label pointLabel from the values of the other dimensions.
Clearly I can reach a good alignment by testing various combinations of values, but I am looking for a general solution.
Is there anyone who can help me?
This assumes you are using >=R2014b, though it can also be accomplished in older versions using set and get commands.
When a text object is created, its default units are data coordinates, but those can be changed. In your case, I'd go with points.
x = 10;
pointSize = 100;
fontSize = 20;
P = scatter(x, 0, pointSize, [0,0,0], 'filled');
t = text(x, 0, 'pointLabel',...
'HorizontalAlignment', 'center',...
'VerticalAlignment', 'bottom',...
'FontSize', fontSize);
% It's always a good idea to switch back to the default units, so remember them.
originalUnits = t.Units;
t.Units = 'points';
% Shift the text up by the sqrt(pi)/2 times the radius of the point
t.Position(2) = t.Position(2) + sqrt(pointSize)/2;
t.Units = originalUnits;
Check out Text Properties for more info. If you want to get really sophisticated, you can use the read-only property Extent and your known marker size and position to calculate when a label is overlapping one of your points. Since the default unit is in data space, no conversions are necessary.
If you're working with an older version of MATLAB, all of these options and properties are still available, you just have to work a little harder to use them. For instance, you can't direction set the position as above, but you would instead use get to assign it to a temporary variable, change it, and then use set to update. More lines of code, but ultimately the same effect.

How to create paraview slice

I want to make Paraview slice in normal z direction (0,0,1) in python shell.
paraview.simple.Slice(*input, **params)
what should be input in paraview.simple.Slice to get a slice at particular location
Here's an example script:
from paraview import simple as pvs
dataProducer = pvs.Wavelet()
slicer = pvs.Slice(Input=dataProducer, SliceType="Plane")
slicer.SliceType.Origin = [0, 0, 0]
slicer.SliceType.Normal = [0, 0, 1]
# To render the result, do this:
Show(slicer)
Render()
You can also you Tools | Start Trace to generate Python trace for actions you perform in the UI.

Matlab gradient equivalent in opencv

I am trying to migrate some code from Matlab to Opencv and need an exact replica of the gradient function. I have tried the cv::Sobel function but for some reason the values in the resulting cv::Mat are not the same as the values in the Matlab version. I need the X and Y gradient in separate matrices for further calculations.
Any workaround that could achieve this would be great
Sobel can only compute the second derivative of the image pixel which is not what we want.
(f(i+1,j) + f(i-1,j) - 2f(i,j)) / 2
What we want is
(f(i+i,j)-f(i-1,j)) / 2
So we need to apply
Mat kernelx = (Mat_<float>(1,3)<<-0.5, 0, 0.5);
Mat kernely = (Mat_<float>(3,1)<<-0.5, 0, 0.5);
filter2D(src, fx, -1, kernelx)
filter2D(src, fy, -1, kernely);
Matlab treats border pixels differently from inner pixels. So the code above is wrong at the border values. One can use BORDER_CONSTANT to extent the border value out with a constant number, unfortunately the constant number is -1 by OpenCV and can not be changed to 0 (which is what we want).
So as to border values, I do not have a very neat answer to it. Just try to compute the first derivative by hand...
You have to call Sobel 2 times, with arguments:
xorder = 1, yorder = 0
and
xorder = 0, yorder = 1
You have to select the appropriate kernel size.
See documentation
It might still be that the MatLab implementation was different, ideally you should retrieve which kernel was used there...
Edit:
If you need to specify your own kernel, you can use the more generic filter2D. Your destination depth will be CV_16S (16bit signed).
Matlab computes the gradient differently for interior rows and border rows (the same is true for the columns of course). At the borders, it is a simple forward difference gradY(1) = row(2) - row(1). The gradient for interior rows is computed by the central difference gradY(2) = (row(3) - row(1)) / 2.
I think you cannot achieve the same result with just running a single convolution filter over the whole matrix in OpenCV. Use cv::Sobel() with ksize = 1, then treat the borders (either manually or by applying a [ 1 -1 ] filter).
Pei's answer is partly correct. Matlab uses these calculations for the borders:
G(:,1) = A(:,2) - A(:,1);
G(:,N) = A(:,N) - A(:,N-1);
so used the following opencv code to complete the gradient:
static cv::Mat kernelx = (cv::Mat_<double>(1, 3) << -0.5, 0, 0.5);
static cv::Mat kernely = (cv::Mat_<double>(3, 1) << -0.5, 0, 0.5);
cv::Mat fx, fy;
cv::filter2D(Image, fx, -1, kernelx, cv::Point(-1, -1), 0, cv::BORDER_REPLICATE);
cv::filter2D(Image, fy, -1, kernely, cv::Point(-1, -1), 0, cv::BORDER_REPLICATE);
fx.col(fx.cols - 1) *= 2;
fx.col(0) *= 2;
fy.row(fy.rows - 1) *= 2;
fy.row(0) *= 2;
Jorrit's answer is partly correct.
In some cases, the value of the directional derivative may be negative, and MATLAB will retain these negative numbers, but OpenCV Mat will set the negative number to 0.