Specifying timeout when reading URL image with MATLAB imread function - matlab

The MATLAB imread function provides the ability to read an image from a URL. This generally works OK, but occasionally I encounter an image that takes a very long time to respond.
For instance, at the time of posting the following URL appears to just be stuck in a 'connecting...' state for over 5 minutes before finally succeeding.
http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg
Is there any way I can set a timeout within MATLAB?
Thanks

I don't know how to interrupt imread with a timer object. Besides, I suspect about its possibility. But I may recommend you to check whether you can access to the file first, and then, you get the file. I have written the following function to check the file and internet status:
function flag = does_url_exist(urlName)
url =java.net.URL(urlName);
try
link = openStream(url);
parse = java.io.InputStreamReader(link);
snip = java.io.BufferedReader(parse);
if ~isempty(snip)
flag = 1;
else
flag = 0;
end
catch exception
flag = 0;
end
end
Then it is as follows:
fname = 'http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg';
if(does_url_exist(fname))
img = imread(fname);
end
Note that for internet connection checking, I took the initial code from this post. Also note that if you are sure that the file exists, it is not efficient to check it again since it increases the running time.

Related

Displaying Data as a String in Simulink RT Display Port

My issue involves using the RS-232 Simulink RT blocks.
A model is uploaded to the target PC (xPC) and it transmits and receives data from a variable frequency drive (VFD) that controls a motor. The issue arises on the receiving end when I take data and try to send that data to a display block in my model as a string. Code would be helpful here:
disp = uint8(zeros(1,24));
display = uint8(zeros(1,length(disp)));
cmd = 0;
status = stat_lb;
%% Start-Up
% Initialization Period
if (status == 0 || status == 1)
cmd = 0;
msg = uint8('Start up');
display = [msg uint8(zeros( 1, length(disp)- length(msg) ))];
end
...
%Multiple status cases with unique displays.
...
disp = display
So, here the cmd portion functions as expected. As noted above, I want to display the display string on a display block in my Simulink model. As you can see, though, it is of type uint8, so I need to convert it to type string; however, when I pass it through either the ascii2str Simulink block or just place it in the function call (e.g. display = ascii2str(display)) I get the following error message:
Executing the 'CheckData' command produced the following error: Invalid parameter/value pair arguments
My thought is that this has something to do with the fact that I am using MEX and this function (ascii2str) is not supported. Anyways, I am wondering if anyone knows why I receive this error and if there is anything I can do to resolve it.
Oh, and one last thing: I can get the display to work if I just remove the ascii2str; however, the only problem with this is that the display is in uint8 form and not really helpful. So, if there is any other way that I can decode the uint8 to a string I am all ears.
Thanks!
I have found that there is no support for this feature in Simulink RT. One option is to use external functions, but I found it better for my application to simply output a number and have a table in the simulation that explained what each number meant.

Cannot identify image file io.BytesIO on raspberry Pi using PiCamera library and PIL

I am having trouble using the output from PiCamera capture function (directed in a BytesIO stream) and opening it using the PIL library. Here is the code (based on the PiCamera basic examples):
#Camera stuff
camera = PiCamera()
camera.resolution = (640, 480)
stream = io.BytesIO()
sleep(2)
try:
for frame in camera.capture_continuous(stream, format = "jpeg", use_video_port = True):
frame.seek(0)
image = Image.open(frame) //THIS IS WHERE IS CRASHES
#OTHER STUFF THAT IS NON IMPORTANT GOES HERE
frame.truncate(0)
finally:
camera.close()
stream.close()
The error is : PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0xaa01cf00>
Any help would be greatly appreciated :)
Have a nice day!
The problem is simple but I am wondering why the io library works that way.
One simply needs to seek back the stream to 0 after truncating it or seek to 0 and then simply call truncate with no parameter (all after you are done opening the image). Like so:
for frame in camera.capture_continuous(stream, format = "jpeg", use_video_port = True):
stream.seek(0)
image = Image.open(stream)
#Do stuff with image
stream.seek(0)
stream.truncate()
Basically when you open the image and do some operation on it, the pointer of the BytesIO can move around and end up somewhere else than the zero position. After that when you call truncate(0) it does not move the pointer back to zero as I thought it would (seems logical to me to move the pointer back to where the truncation occurs). When to code runs once more, the capture writes in the stream but this time it does not start writing at the beginning and everything breaks after that.
Hope this can help someone in the future :)

Processing multiple files from a directory

How can i do the same math function(eg:average) for a folder containing large number of data files using matlab(2010) and store them in one output?
This is the code I have, but it was unsuccessful.
function A = RepeatForAll()
A = 0;
% audio is the folder name where audio files are saved
path = fullfile(pwd,'audio');
files = dir(path);
for fileIndex=3:length(files)
if (files(fileIndex).isdir == 0)
if (~isempty(strfind(files(fileIndex).name,'wav')))
fullfile(path,files(fileIndex).name)
result = wavread(fullfile(path,files(fileIndex).name));
% Any thing you have to for each audio file
inputz=wavread(result);
outx = mfccx(result);
A(count,:) = mean(outx,2);
count=count+1;
end;
end;
end;
You need to set
count=0;
before going into the for loop, now count is undefined.
Also the line inputz=wavread(result); is both unused and wrong. you don't use inputz anywhere, and you are calling wavread on result, which is not a filename (see the line above). This would generate an error.
Please be more clear next time, at least give us error messages. Describing what you think should happen is also useful.
Last, correctly format your code. In matlab, select al your code (control+a) then press control+i to format it.

Continuously acquire data in MATLAB using callbacks and persistent variables

I have just recently started to use MATLAB to acquire data off of a data acquisition board and was in need of a function to acquire data continuously (i.e. until I ctrl^C out of the function). To do this I am using the data acquisition toolbox on a 32-bit windows OS.
Based on the documentation in matlab help and a few of the answers on this site, I found that after adding channels to my input handle I should:
set my 'SamplesPerTrigger' to Inf
set the 'TimerPeriod' to some value to trigger the 'TimerFcn'
set the 'TimerFcn' to some subfunction callback which appends data to a persistent variable
Is this a correct way to do this?
My code is as follows:
function acquire_arena_test(samprate,daq_device ,device_ID ,channels, saveroot)
setup.SampleRate = samprate;
setup.DAQdevice = {daq_device, device_ID};
setup.AIChannels = channels;
setup.SaveRoot = {saveroot};
ai = analoginput(setup.DAQdevice{1},setup.DAQdevice{2});
addchannel(ai,[setup.AIChannels]);
set(ai,'SamplesPerTrigger',Inf);
set(ai,'TimerPeriod',0.5);
set(ai,'TimerFcn',{#AcquireData,ai});
start(ai);
while(strcmpi(get(ai,'Running'),'On'))
pause(1)
end
stop(ai);
time = datestr(now,30);
save([saveroot time], 'data');
delete(ai);
clear ai;
function AcquireData(hObject, ~)
persistent totalData;
data = getdata(hObject);
if isempty(totalData)
totalData =data;
else
totalData = [totalData; data];
end
The initial analog input is definitely working properly. I have tried many permutations of giving the AcquireData callback to 'TimerFcn'. The error I receive is
`??? Error using ==> acquire_arena_test>AcquireData
Too many input arguments.
Warning: The TimerFcn callback is being disabled.
To enable the callback, set the TimerFcn property. `
Thanks in advance for any help.
I think the syntax you use for setting up your TimerFcn is wrong. You write
set(ai,'TimerFcn',{#AcquireData,ai});
but this means that your function AcquireData will be called with tree parameters: AcquireData(ai, event, ai) as explained here, which then of course triggers the error message since your AcquireData function only accepts two parameters. Just change your code to
set(ai,'TimerFcn',#AcquireData);
and it should work; the ai object is automatically passed as the first parameter (see the link to the MATLAB documentation above).
Sorry about answering my own question, but I figured it out. The trigger was not needed after all. Using a national instruments board (or a sound card, as it turns out) you can just change the LoggingMode to 'disk' and specify a file to save the .daq (data acquisition toolbox) file to save as with LogFileName. If you want to use the memory on your board, change the mode to disk&Memory. Helpful document:
http://www.mathworks.com/help/toolbox/daq/f12-16658.html
The script below acquires data during the pause, which is as long as you want it to be..
daqreset;
clear all;
ai = analoginput('nidaq','Dev1');
chans = addchannel(ai,0:6);
set(ai,'SamplesPerTrigger',Inf);
set(ai,'SampleRate',1000)
set(ai,'LogToDiskMode','Overwrite')
set(ai,'LogFileName','log.daq')
set(ai,'LoggingMode', 'disk')
start(ai)
pause()
stop(ai)
data = daqread('log.daq');
delete(ai);
Note that you still need to set 'SamplesPerTrigger' to Inf for this to work properly. Thank you to Jonas for his help as well.

Controlling a matlab script (Pause, Reset)

I am trying to create a matlab script (m-file) which shall be controlled by an external VBA script.
The matlab script shall do the same operation every time (even params change, but this is not the matter in this case) for a certain number of loops.
If I see it right, I can use matlab funktions in VBA like this: http://www.mathworks.de/help/techdoc/matlab_external/f135590.html#f133975
My main problem is how to implement the matlab part of this problem...at the moment my control part looks like this:
start.m:
run = 1;
reset = 0;
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
doProcess();
pause(1)
end
disp('I am done');
The reset part works very fine while changing the value by the script, but when I manually try to change the value of 'run' or 'reset' to any other value in my workspace, nothing happens...my script doen't abort, neither does the reset-if do it's work...
this seems to me that the script doesn't recognize any changes in the workspace?!
later the variables 'run' and 'reset' shall be set or unset by the VBA script.
Is there any plausible reason why I can't abort the loop by hand?
Thanks for any advice!
greets, poeschlorn
Edit:
It seems that the script loads the variables once before starting and never again during runtime...is there a possibility to have explicit access to a workspace variable?
Edit 2:
I use Matlab 2010b with no additional Toolboxes at the moment
Edit 3:
I found out, that there are several 'workspaces' or RAMs in Matlab. If my function is running, the variables are stored in 'base' (?) workspace, which is not the matlab workspace on which you can click and change every value. So I have to get access to this ominous 'base' space and change the flag 'run' to zero.
I assume your problem is simply that your loop is blocking execution of the external interface. While the loop runs you cannot access the other interfaces.
I wanted to do a similar thing -- allow control of a matlab loop by an external program (either Ruby or another matlab instance). The most flexible solution by far was using UDP. There is a great toolbox called PNET for matlab, and I assume VB must have a socket library too. I simply open a UDP port on both sides, and use simple text commands to control and give feedback.
obj.conn = pnet('udpsocket', 9999);
command = '';
while run ~= 0
nBytes = pnet(obj.conn, 'readpacket');
if nBytes > 0
command = pnet(obj.conn, 'read', nBytes, 'string');
end
switch command
case '--reset--'
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
case '--abort--'
run = 0;
disp('Going to abort');
case '--echo--'
pnet(obj.conn, 'write', '--echo--');
pnet(obj.conn, 'writepacket', remoteAddress, remotePort);
end
doProcess();
end
This way I can build my own extensible control interface without worrying about blocking from the loop, it can work cross-platform and cross-language, can work within a machine or across the network.
UPDATE:
To talk between two UDP clients, you need to set up two complimentary UDP ports, both are clients (this example is all in matlab, pretend obj here is a structure, in my case it is a class i wrap around the pnet functionality):
obj = struct();
obj.success = 0;
obj.client1Port = 9999;
obj.client2Port = 9998;
obj.client1Address = '127.0.0.1';
obj.client2Address = '127.0.0.1';
obj.conn1 = pnet('udpsocket', obj.client1Port);
obj.conn2 = pnet('udpsocket', obj.client2Port);
pnet(obj.conn1, 'write', '--echo--')
pnet(obj.conn1, 'writepacket', obj.client2Address, obj.client2Port);
nBytes = pnet(obj.conn2, 'readpacket');
if nBytes > 0
command = pnet(obj.conn2, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 2 recieved this message: %s\n',command);
pnet(obj.conn2, 'write', '--echo--')
pnet(obj.conn2, 'writepacket', obj.client1Address, obj.client1Port);
end
end
nBytes = pnet(obj.conn1, 'readpacket');
if nBytes > 0
command = pnet(obj.conn1, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 1 got this back: %s\n',command);
end
end
if obj.success == 2
fprintf('\nWe both sent and received messages!\n');
end
Is your script a script m-file or a function?
If it's a function, you'll be losing the scope of the workspace variables which is why it's not working. I'd turn your code into a function like this:
function processRun(run,reset)
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset; % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
[run,reset] = doProcess;
pause(1)
end
You can then set the values of run and reset evertime you call the function from VBA.
If you have a script, try removing the run and reset lines from the top, and set their values in the workspace before you run the script. I think you're overwriting your workspace values by running the script file.
Sorry, I don't have enough rep to make a comment so I'll quote it here:
#Adam Leadbetter: Thanks, this makes sense. The only thing I habe trouble with is how to pause (after this reset and then resume) the script when it has been started by run=1 as param... – poeschlorn Feb 25 at 7:17
If you want to break out of the loop once reset has been set to one, and then wait for the loop to continue again once run = 1 that is pretty much the same as just starting over again?
function processRun()
run = 1;
while run ~= 1
run = doProcess();
end
if doProcess() returns 0 then the function processRun() will end (like the behaviour you want to have when reset), the next time processRun is called it starts over, with "reset"/default values.
Or am I missing something?