Psychtoolbox: Can I save pre-drawn textures to my hard drive? - matlab

In my experiment I am displaying lots of different gratings. To save time during the experiment's execution, I'm pre-drawing the corresponding textures and keep them in a buffer. However, this takes about 10-20 seconds depending on how many stimuli the run uses, and how fast the machine is.
I was wondering whether there is a way of storing the pre-drawn textures on the hard drive and just have them read in?
Here is the current code:
tic
stimulus_matrix = [];
for ifrequencies = 1:length(frequencies)
for iphase = 1:length(phases)
for icontrast_manipulation = 1:length(contrast_manipulation)
for icontrast_values = 1:length(contrast_values(1,:))
grating = makeStimulus(contrast_values(icontrast_manipulation,icontrast_values),grating_size_degrees,phases(iphase),frequencies(ifrequencies,1));
stimulus_matrix(ifrequencies,iphase,icontrast_manipulation,icontrast_values) = Screen('MakeTexture', my_window, grating);
Screen('FillOval', stimulus_matrix(ifrequencies,iphase,icontrast_manipulation,icontrast_values), background, CenterRect(ovalRect,gratingRect));
% Display a progress bar during buffering
% code for progress bar removed for clarity
end
end
end
end

you can use
save('mydata.mat',stimulus_matrix);
and when you need the matrix, you can load it.
load mydata.mat;
then use stimulus_matrix as you want.

Isn't stimulus_matrix just an index to the generated texture? These indices are just pointers. So if you close the textures but keep the windows open, I don't think loading the matrix enables you to draw textures again.

Not sure if this is ideal for your situation, but you could try:
screen_array = Screen('GetImage', my_window);
while the textures are drawn. This would give you a 3D array of the screen content at that time (including your texture), which you could then edit down to include only your texture, and/or subsequently export.

Related

Stitching overlaying images from different cameras in Matlab

Two cameras takes two images of a wooden plank. The images have an overlap of the plank which I need to stitch together in a way that it looks natural and preferably seamless to the human eye for inspection purposes. The images are cropped to the same size and masked to remove the background and most of the non-overlapping areas but the plank can have a slight tilt on the conveyor belt.
Currently I'm using the normxcorr2 function on the general overlay area, following ideas from the Matlab totorial of the normxcorr2 function, to try and identify one of the images in the other and work out an overlay offset, following the tutorial. However, this fails quite often as the normxcorr2 functions returns a zero offset - resulting in a bad stitching:
c = normxcorr2(plank_part1,plank_part2);
Find peak in cross-correlation:
[ypeak, xpeak] = ind(c==max(c(:)));
Account for the padding that normxcorr2 adds:
yoffSet = ypeak-size(onion,1);
xoffSet = xpeak-size(onion,2);
[xoffSet,yoffSet]
ans =
0 0
It would seem normxcorr2 can not always find the correct overlay of the images, or any overlay at all(?), even though I try to make it easier by increasing the gray scale contrast by the function histeq. My guess is that the amount of "gray-ish" area from the sapwood overwhelms the distinct knots, which are the important parts to stitch propperly.
Does anyone know of a way to either increase the likelihood of this stitching process, maybe by some more preprocessing, or use any other matlab skills/functions to make this work better?
P.S I can not use anything but freely accessible scripts as this would probably become license/copyright issues for my project.
Thank you for your time in trying to help!
You should look at the following link. The term that you should be looking for is image registration. There are more advanced methods than normxcorr2

Beginner at kinect - matlab : Kinect does not start

hello I am trying to set up kinect1 in matlab environment and I cannot get joint coordinates out of kinect even though I have a preview of the captured depth. In the preview it says " waiting to start" when I actually started the video.
There are two different features which you don't want to mix up:
There is the preview function. By calling preview(vid) a preview window is opened and the camera runs. The preview is there to help you set up your camera, point it to the right spot etc. When you're finished with that, close the preview manually or via closepreview(vid).
When you are ready for image acquisition, call start(vid). With img = getdata(vid,1) you can then read 1 frame from the camera and save it to img. When you're finished with acquisition, call close(vid) to stop the camera.
The camera itsself starts capturing images as soon as start is called, so even if you wait some seconds after calling start, the first image will be the one captured right then. There exist several properties to control the acquisition, it is best to have a look at all properties of vid.
You can manually specify a trigger to take an image by first setting triggerconfig(vid,'manual'), then starting the camera and finally calling trigger(vid) to take an image.
The number of frames that is acquired after calling start or trigger is specified by the FramesPerTrigger parameter of vid. To continuously acquire images, set it to inf. It is possible to use getdata to read any number of frames, e.g. getdata(vid,5);. Note that this only works if 5 frames are actually available on the camera. You get the number of available frames from the FramesAvailable property of vid.
You can put the image acquisition inside a for loop to continuously acquire images
n = 1000;
vid = videoinput('kinect',2);
set(vid,'FramesPerTrigger',n);
start(vid);
for k=1:n
img = getdata(vid,1);
% do magic stuff with img
end
stop(vid);

Display live processed webcam stream using matlab

I am trying to employ a chroma key algorithm on a live video. I need to take a live webcam input, process it in real time and display it. I already have the chroma key algorithm working on images.
How do I process the webcam input and display it immediately. I have tried using snapshot() and passing the image to the chroma key algorithm but it is too slow even if I increase the rate of snapshots. I want a smooth output.
[ Also, if there is a better alternative than Matlab please let me know. ]
Instead of using getsnapshot() which connects to the camera and disconnects on EVERY single frame (thus slow framerates), try to use videoinput and then preview the connection: http://www.mathworks.de/de/help/imaq/preview.html
This example is made for you:
http://www.mathworks.de/products/imaq/code-examples.html?file=/products/demos/shipping/imaq/demoimaq_LiveHistogram.html
As shown you can even define a callback-handler-function which is called on every newly received frame.
You must set TriggerType to manual, or else getsnapshot() will create (and destroy) a conection to the camera everytime you need a frame. By setting it to manual, you can start the camera once, get the frames and stop the camera when you're done.
Here is an example:
vidobj = videoinput('winvideo', 1, 'RGB24_640x480');
triggerconfig(vidobj, 'manual');
start(vidobj);
while true % Or any stop condition
img = getsnapshot(vidobj);
% Process the frame.
...
imshow(img);
drawnow;
end

Matlab: How to distribute workload?

I am currently trying to record footage of a camera and represent it with matlab in a graphic window using the "image" command. The problem I'm facing is the slow redraw of the image and this of course effects my whole script. Here's some quick pseudo code to explain my program:
figure
while(true)
Frame = AcquireImageFromCamera(); % Mex, returns current frame
image(I);
end
AcquireImageFromCamera() is a mex coming from an API for the camera.
Now without displaying the acquired image the script easily grabbs all frames coming from the camera (it records with a limited framerate). But as soon as I display every image for a real-time video stream, it slows down terribly and therefore frames are lost as they are not captured.
Does anyone have an idea how I could split the process of acquiring images and displaying them in order to use multiple cores of the CPU for example? Parallel computing is the first thing that pops into my mind, but the parallel toolbox works entirely different form what I want here...
edit: I'm a student and in my faculty's matlab version all toolboxes are included :)
Running two threads or workers is going to be a bit tricky. Instead of that, can you simply update the screen less often? Something like this:
figure
count = 0;
while(true)
Frame = AcquireImageFromCamera(); % Mex, returns current frame
count = count + 1;
if count == 5
count = 0;
image(I);
end
end
Another thing to try is to call image() just once to set up the plot, then update pixels directly. This should be much faster than calling image() every frame. You do this by getting the image handle and changing the CData property.
h = image(I); % first frame only
set(h, 'CData', newPixels); % other frames update pixels like this
Note that updating pixels like this may then require a call to drawnow to show the change on screen.
I'm not sure how precise your pseudo code is, but creating the image object takes quite a bit of overhead. It is much faster to create it once and then just set the image data.
figure
himg = image(I)
while(true)
Frame = AcquireImageFromCamera(); % Mex, returns current frame
set(himg,'cdata',Frame);
drawnow; %Also make sure the screen is actually updated.
end
Matlab has a video player in Computer vision toolbox, which would be faster than using image().
player = vision.VideoPlayer
while(true)
Frame = AcquireImageFromCamera(); % Mex, returns current frame
step(player, Frame);
end

Improve animation rendering in Matlab

I have written a code to create an animation (satellite movement around the Earth). When I run it, it works fine. However, when it is modified to be part of a code much more complex present in a Matlab GUI, the results produced changes (mainly because of the bigger number of points to plot). I also have noticed that if I use the OpenGL renderer the movement of the satellite is quicker than when the other renderers (Painters and Zbuffer) are used. I do not know if there are further possibilities to achieve an improvement in the rendering of the satellite movement. I think the key is, perhaps, changing the code that creates the actual position of the satellite (handles.psat) and its trajectory along the time (handles.tray)
handles.tray = zeros(1,Fin);
handles.psat = line('parent',ah4,'XData',Y(1,1), 'YData',Y(1,2),...
'ZData',Y(1,3),'Marker','o', 'MarkerSize',10,'MarkerFaceColor','b');
...
while (k<Fin)
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
handles.tray(k) = line([Y(k-1,1) Y(k,1)],[Y(k-1,2) Y(k,2)],...
[Y(k-1,3) Y(k,3)],...
'Color','red','LineWidth',3);
set(handles.psat,'XData',Y(k,1),'YData',Y(k,2),'ZData',Y(k,3));
pause(0.02);
k = k + 1;
if (state == 1)
state = 0;
break;
end
end
...
Did you consider to apply a rotation transform matrix on your data instead of the axis?
I think <Though I haven't checked it> that it can speedup your code.
You've used the typical tricks that I use to speed things up, like precomputing the frames, setting XData and YData rather than replotting, and selecting a renderer. Here are a couple more tips though:
1) One thing I noticed in your description is that different renderers and different complexities changed how fast your animation appeared to be running. This is often undesirable. Consider using the actual interval between frames (i.e. use tic; dt = toc) to calculate how far to advance the animation, rather than relying on pause(0.2) to generate a steady frame rate.
2) If the complexity is such that your frame rate is undesirably low, consider replacing pause(0.02) with drawnow, or at least calculate how long to pause on each frame.
3) Try to narrow down the source of your bottleneck a bit further by measuring how long the various steps take. That will let you optimize the right stage of the operation.