How to store values continuously without overwriting the previous one? - arrays

My project is "optical flow estimation for flame detection in videos" In that while extracting feature values, I can only retain the last intensity value of the frame.
Here is my code
function [Iy, Ix, It] = grad3D(imNew,bFineScale,bInitialize)
persistent siz gx gg imPrev;
if nargin>2 && bInitialize
[gx, gg]= makeFilters();
if bFineScale
siz = size(imNew);
imPrev= single(imNew);
else% if ~bFineScale
siz = floor(size(imNew)/2);
%initialize imPrev to half the size
imPrev = imresizeNN(single(imNew),siz);
end
end
if ~bFineScale
imNew = imresizeNN(conv2(single(imNew),gg,'same'),siz);
else imNew = single(imNew);
end
Ix = conv2(gg,gx,imNew + imPrev,'same');
Iy = conv2(gx,gg,imNew + imPrev,'same');
It = conv2(gg,gg,imNew - imPrev,'same'); %L3
% finally, store away the current image for use on next frame
imPrev = imNew;
testfeature = mean(imPrev);
save testfeature testfeature
[gx, gg]= makeFilters() x = (-1:1);
gg = single(gaussgen(0.67,3));
gx = single(-x.*gg*3);
In the highlighted coding(testfeature=mean(imprev)). I can be able to get only the intensity value of last frame extracted...But i need the values for all the extracted frames. I need the value to be stored row wise in a matrix file.

Related

Trying to find the mean and variance of a certain section of an array for a given number

I have about 30,000 data points but want to find the mean and variance for a certain angle of attack and chart each into their own array but it just won't seem to work
clear all
clc
load('windflies.mat')
angleofattacks = [0 1.008 2.016 3.024 4.032 5.04 6.048 7.056 8.064 9.072 10.08 11.088 12.096 13.104 14.112 15.12 16.128 17.136 18.144 19.152 20.16];
WOPFast;
[rows,cols] = size(WOPFast);
[r1,c2] = size(angleofattacks);
count = 0;
xc=1;
forcexn = zeros(21,1);
total = 0;
x=[];
for c = 1:21
for r = 1:rows
if WOPFast(r,2) == angleofattacks(1,c)
x(r,xc)= WOPFast(r,3);
end
end
count = count + 1;
forcexn(count,xc)= mean(x);
xc =xc +1;
end

DICOM dimensions in matlab array (all frames end up in last dimension of array)

In one of my GUIs I load DICOM images. Sometimes they are just a volume and another dimension and when I load them in Matlab everything ends up where I want it.
handles.inf = dicominfo([filepath filename]);
handles.dat = dicomread(handles.inf);
size(handles.dat)
ans = 128 128 128 512
For an 128 by 128 by 128 volume at 512 timepoints for example (actually the third dimension would not even be 128, the third dimension is stacks, of which I don't know what it is). However sometimes There are more dimensions in the dicom, but the reader just puts all of them in the fourth dimension.
handles.inf = dicominfo([filepath filename]);
handles.dat = dicomread(handles.inf);
size(handles.dat)
ans = 128 128 1 4082
For a single 128 by 128 slice with 512 timepoints, two echoes and magnitude, phase, real and imaginary data for example.
It is then very hard to unscramble them. Manually I can do this for every DICOM I load but when in a GUI I would want to have a general approach that just creates a dimension in the array for each dimension in the dicom.
This is especially important not just for data-analysis, but also to transform the coordinates from image space to patient space. My own approach was to look at the header, but there's no guarantee that certain entries will work, and the order in which they are applied I can't find. The header entries I found so far:
inf.Rows;%inf.width;%inf.MRAcquisitionFrequencyEncodingSteps;%inf.MRAcquisitionPhaseEncodingStepsInPlane
inf.Columns;% inf.height; % inf.NumberOfKSpaceTrajectories;
inf.MRSeriesNrOfSlices
inf.MRSeriesNrOfEchoes
inf.MRSeriesNrOfDynamicScans
inf.MRSeriesNrOfPhases
inf.MRSeriesReconstructionNumber % not sure about this one
inf.MRSeriesNrOfDiffBValues
inf.MRSeriesNrOfDiffGradOrients
inf.MRSeriesNrOfLabelTypes
reshapeddat = reshape(dat, [all dimension sizes from header here]);
I'm not sure how to check if I've got all variables and what the right order for the reshape. Anybody knows of a sure-fire way to get all dimension sizes from the DICOM header and the order in which they are stacked?
Ok so I now manually go by all possible dimensions. When a stack also contains reconstructed data which has less dimensions than the rest, remove those first.
This is how I check the dimensions:
info = dicominfo(filename);
datorig = dicomread(filename);
%dimension sizes per frame
nrX = double(info.Rows); %similar nX;% info.width;% info.MRAcquisitionFrequencyEncodingSteps;% info.MRAcquisitionPhaseEncodingStepsInPlane
nrY = double(info.Columns); %similar nY;% info.height;% info.NumberOfKSpaceTrajectories;
%dimensions between frames
nrEcho = double(info.MRSeriesNrOfEchoes);
nrDyn = double(info.MRSeriesNrOfDynamicScans);
nrPhase = double(info.MRSeriesNrOfPhases);
nrSlice = double(info.MRSeriesNrOfSlices); %no per frame struct entry, calculate from offset.
%nr of frames
nrFrame = double(info.NumberOfFrames);
nrSeq = 1; % nSeq not sure how to interpret this, wheres the per frame struct entry?
nrBval = double(info.MRSeriesNrOfDiffBValues); % nB
nrGrad = double(info.MRSeriesNrOfDiffGradOrients); % info.MRSeriesNrOfPhaseContrastDirctns;%similar nGrad?
nrASL = 1; % info.MRSeriesNrOfLabelTypes;%per frame struct entry?
imtype = cell(1, nrFrame);
for ii = 1:nrFrame
%imtype(ii) = eval(sprintf('info.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageTypeMR', ii));
imtype{ii} = num2str(eval(sprintf('info.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageTypeMR', ii)));
end
imType = unique(imtype, 'stable');
nrType = length(imType);
This is how I reformat the dimensions:
%% count length of same dimension positions from start
if nrEcho > 1
for ii = 1:nrFrame
imecno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.EchoNumber', ii));
end
lenEcho = find(imecno ~= imecno(1), 1, 'first') - 1;
else
lenEcho = nrFrame;
end
if nrDyn > 1
for ii = 1:nrFrame
imdynno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.TemporalPositionIdentifier', ii));
end
lenDyn = find(imdynno ~= imdynno(1), 1, 'first') - 1;
else
lenDyn = nrFrame;
end
if nrPhase > 1
for ii = 1:nrFrame
imphno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImagePhaseNumber', ii));
end
lenPhase = find(imphno~=imphno(1), 1, 'first') - 1;
else
lenPhase = nrFrame;
end
if nrType > 1
q = 1;
imtyno(1, 1) = q;
for ii = 2:nrFrame
if imtype{:, ii-1} ~= imtype{:, (ii)}
q = q+1;
end
imtyno(1, ii) = q;
%for jj = 1:nrType
%if imtype{:,ii} == imType{:,jj}
% imtyno(1, ii) = jj;
%end
%end
end
if q ~= nrType
nrType = q;
end
lenType = find(imtyno ~= imtyno(1), 1, 'first') - 1;
else
lenType = nrFrame;
end
% slices are not numbered per frame, so get this indirectly from location
% currently not sure if working for all angulations
for ii = 1:nrFrame
imslice(:,ii) = -eval(['inf.PerFrameFunctionalGroupsSequence.Item_',sprintf('%d', ii),'.PlanePositionSequence.Item_1.ImagePositionPatient']);
end
% stdsl = std(imslice,[],2); --> Assumption
% dirsl = max(find(stdsl == max(stdsl)));
imslices = unique(imslice', 'rows')';
if nrSlice > 1
for ii = 1:nrFrame
for jj = 1:nrSlice
if imslice(:,ii) == imslices(:,nrSlice - (jj-1)); %dirsl or :?
imslno(1, ii) = jj;
end
end
end
lenSlice = find(imslno~=imslno(1), 1, 'first')-1;
else
lenSlice = nrFrame;
end
if nrBval > 1
for ii = 1:nrFrame
imbno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageDiffBValueNumber', ii));
end
lenBval = find(imbno~=imbno(1), 1, 'first') - 1;
else
lenBval = nrFrame;
end
if nrGrad > 1
for ii = 1:nrFrame
imgradno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageGradientOrientationNumber', ii));
end
lenGrad = find(imgradno~=imgradno(1), 1, 'first')-1;
else
lenGrad = inf.NumberOfFrames;
end
lenSeq = nrFrame; % dont know how to get this information per frame, in my case always one
lenASL = nrFrame; % dont know how to get this information per frame, in my case always one
%this would have been the goal format
goaldim = [nrSlice nrEcho nrDyn nrPhase nrType nrSeq nrBval nrGrad nrASL]; % what we want
goallen = [lenSlice lenEcho lenDyn lenPhase lenType lenSeq lenBval lenGrad lenASL]; % what they are
[~, permIX] = sort(goallen);
dicomdim = zeros(1, 9);
for ii = 1:9
dicomdim(1, ii) = goaldim(permIX(ii));
end
dicomdim = [nrX nrY dicomdim];
%for any possible zero dimensions from header use a 1 instead
dicomdim(find(dicomdim == 0)) = 1;
newdat = reshape(dat, dicomdim);
newdim = size(newdat);
newnonzero = length(newdim(3:end));
goalnonzero = permIX(1:newnonzero);
[dummyy, goalIX] = sort(goalnonzero);
goalIX = [1 2 goalIX+2];
newdat = permute(newdat, goalIX);
newdat = reshape(newdat, [nrX nrY goaldim]);
When Ive used this as a function for a longer period and debugged it a bit I might post in on the file exchange of mathworks.

Conversion of MetaTrader4 to NinjaTrader

I am trying to write an indicator originally from MT4 into NT7.
I have the following calculations in MT4:
dayi = iBarShift(Symbol(), myPeriod, Time[i], false);
Q = (iHigh(Symbol(), myPeriod,dayi+1) - iLow(Symbol(),myPeriod,dayi+1));
L = iLow(NULL,myPeriod,dayi+1);
H = iHigh(NULL,myPeriod,dayi+1);
O = iOpen(NULL,myPeriod,dayi+1);
C = iClose(NULL,myPeriod,dayi+1);
myperiod is a variable where I place the period in minutes (1440 = 1day).
What are the equivalent functions in NT7 to iBarShift, iHigh and so on?
Thanks in advance
For NinjaTrader:
iLow = Low or Lows for multi-time frame
iHigh = High or Highs
iOpen = Open or Opens
iClose = Close or Closes
So an example would be
double low = Low[0]; // Gets the low of the bar at index 0, or the last fully formed bar (If CalculateOnBarClose = true)
In order to make sure you are working on the 1440 minute time frame, you will need to add the following in the Initialize() method:
Add(PeriodType.Minute, 1440);
If there are no Add statements prior to this one, it will place it at index 1 (O being the chart default index) in a 2 dimensional array. So to access the low of the 1440 minute bar at index 0 would be:
double low = Lows[1][0];
For iBarShift look at
int barIndex = Bars.GetBar(time);
which will give you the index of the bar with the matching time. If you need to use this function on the 1440 bars (or other ones), use the BarsArray property to access the correct Bar object and then use the GetBar method on it. For example:
int barIndex = BarsArray[1].GetBar(time);
Hope that helps.

Appending Int to an Array Matlab

I am using an API to get real data times of trains and am trying to get the closest train time to a user entered time and then display that train time, and the next 4 granted the trains are running. I am reading in the information and the code goes through what its supposed to do but when I look at the array its a bunch of [] brackets in 7 cells instead of the calculated numbers. Any suggestions? Code is below with the API
TEST VALUES:
requestStationSelected = 'University%20City' and requestEndStation = 'Roslyn'
%this is the API link for the live data from Septa this will get 30
%results and see which time is closer to the user entered time
requestInfoSeptaLive = ['http://www3.septa.org/hackathon/NextToArrive/' requestStationSelected '/' requestEndStation '/30'];
%Again tries to get the information and if there is a failure it will give
%a probable cause and terminate the program
try
getInfoSeptaLive = urlread(requestInfoSeptaLive);
catch
if getInfoSeptaLive ~= '[]'
disp...
('Either the arrival/depart stations dont quite match up or theres a server error. Try again.');
return;
else
disp('Unable to fetch the information from Septa, please try again')
return;
end
end
%parses the information returned from the Live API
dataReturnedFromLiveAPI = parse_json(getInfoSeptaLive);
dataReturnedFromLiveAPI = dataReturnedFromLiveAPI{1};
%gets the size of the API in case there are no trains running
sizeOfDataNoTrains = size(dataReturnedFromLiveAPI, 1);
sizeOfData = size(dataReturnedFromLiveAPI, 2);
counter = 0;
for i = 1:sizeOfData
scanForClosestTime = dataReturnedFromLiveAPI{1,i}.orig_departure_time;
trainTimeGivenH = sscanf(scanForClosestTime, '%i');
findColonTrain = strfind(scanForClosestTime, ':');
trainTimeGivenMStr = scanForClosestTime(findColonTrain+1:4);
trainTimeGivenM = int32(str2num(trainTimeGivenMStr));
trainDepartTimeM = (trainTimeGivenH(1,1) * 60) + (trainTimeGivenM);
differenceBetweenTimes = trainDepartTimeM - userEnteredMins;
if trainDepartTimeM < userEnteredMins
differenceBetweenTimes = userEnteredMins - trainDepartTimeM;
end
stopAtEndOfData = sizeOfData;
goodTimeFrame = 60;
closestTime = cell(1, stopAtEndOfData);
storeTheDifference = cell(1, stopAtEndOfData);
if(differenceBetweenTimes < 60)
if (counter < 5)
closestTime{i} = scanForClosestTime;
storeTheDifference{i} = differenceBetweenTimes;
counter = counter + 1;
end
end
end
You assign your cell arrays inside the for loop:
for i = 1:sizeOfData
...
closestTime = cell(1, stopAtEndOfData);
storeTheDifference = cell(1, stopAtEndOfData);
...
end
This means that you turn both of them into an array of {[],[],[],[],[]...} on every iteration of the loop - so unless the last iteration has a valid "closest Time" in it, your cell array will be all empty arrays - and if it does, all but the last element will still be [].
To fix this, move the two lines to before the start of the for loop.
The second problem seems to be the indexing of the arrays where you store the results. If you only want five results, I am assuming you want to store them in elements 1 - 5 of your array, and not in "just any" locations. I would change the code to
if (counter < 5)
counter = counter + 1;
closestTime{counter} = scanForClosestTime;
storeTheDifference{counter} = differenceBetweenTimes;
end
But maybe I misinterpreted how you want to handle that?
Unrelated to your question, you might want to take a look at the line
trainTimeGivenMStr = scanForClosestTime(findColonTrain+1:4);
It is quite possible that this is not what you intended to do - looking at an example of the response, I found the string "orig_departure_time":"11:57PM". I expect that findColonTrain == 3, so that the above line becomes
trainTimeGivenMStr = scanForClosestTime(4:4);
just a single character. Perhaps you meant
trainTimeGivenMStr = scanForClosestTime(findColonTrain+(1:4));
which would turn into
trainTimeGivenMStr = scanForClosestTime(4:7);
so that
trainTimeGivenMStr = '57PM';
I hope these three things help you get it all working!
EDIT: had a chance to run your code this morning - discovered a number of other problems. I include below an annotated "working" code: the biggest problem was most likely that you were not handling AM/PM in your code. Note that I used a different json parser - this changed a couple of lines very slightly. I'm sure you can put it back together to work the way you want. This returned valid data in all cells.
dataReturnedFromLiveAPI = loadjson(getInfoSeptaLive);
% next line not needed - loadjson returns struct array, not cell array
%dataReturnedFromLiveAPI = dataReturnedFromLiveAPI{1};
%gets the size of the API in case there are no trains running
sizeOfDataNoTrains = size(dataReturnedFromLiveAPI, 1);
sizeOfData = size(dataReturnedFromLiveAPI, 2);
counter = 0;
stopAtEndOfData = sizeOfData;
closestTime = cell(1, stopAtEndOfData);
storeTheDifference = cell(1, stopAtEndOfData);
userEnteredMins = 12*60+30; % looking for a train around 12:30 pm
for ii = 1:sizeOfData
scanForClosestTime = dataReturnedFromLiveAPI(ii).orig_departure_time;
trainTimeGivenH = sscanf(scanForClosestTime, '%i');
% since we'll be considering AM/PM, have to set 12 = 0:
if (trainTimeGivenH == 12), trainTimeGivenH = 0; end
findColonTrain = strfind(scanForClosestTime, ':');
% change next line to get minutes plus AM/PM:
trainTimeGivenMStr = scanForClosestTime(findColonTrain+(1:4));
% look at just minutes:
trainTimeGivenM = int32(str2num(trainTimeGivenMStr(1:2)));
% adjust for AM/PM:
if(trainTimeGivenMStr(3:4)=='PM'), trainTimeGivenH = trainTimeGivenH+12; end;
% compute time in minutes:
trainDepartTimeM = (trainTimeGivenH * 60) + (trainTimeGivenM);
differenceBetweenTimes = trainDepartTimeM - userEnteredMins;
if trainDepartTimeM < userEnteredMins
differenceBetweenTimes = userEnteredMins - trainDepartTimeM;
end
% added a couple of lines to see what is happening:
fprintf(1, 'train %d: depart %s - in minutes this is %d vs user entered %d\n', ...
ii, scanForClosestTime, trainDepartTimeM, userEnteredMins);
goodTimeFrame = 60;
if(differenceBetweenTimes < 600)
if (counter < 10)
counter = counter + 1;
closestTime{counter} = scanForClosestTime;
storeTheDifference{counter} = differenceBetweenTimes;
end
end
end

Getting current position of one of the multiple objects in a figure?

I wrote a script that returns several text boxes in a figure. The text boxes are moveable (I can drag and drop them), and their positions are predetermined by the data in an input matrix (the data from the input matrix is applied to the respective positions of the boxes by nested for loop). I want to create a matrix which is initially a copy of the input matrix, but is UPDATED as I change the positions of the boxes by dragging them around. How would I update their positions? Here's the entire script
function drag_drop=drag_drop(tsinput,infoinput)
[x,~]=size(tsinput);
dragging = [];
orPos = [];
fig = figure('Name','Docker Tool','WindowButtonUpFcn',#dropObject,...
'units','centimeters','WindowButtonMotionFcn',#moveObject,...
'OuterPosition',[0 0 25 30]);
% Setting variables to zero for the loop
plat_qty=0;
time_qty=0;
k=0;
a=0;
% Start loop
z=1:2
for idx=1:x
if tsinput(idx,4)==1
color='red';
else
color='blue';
end
a=tsinput(idx,z);
b=a/100;
c=floor(b); % hours
d=c*100;
e=a-d; % minutes
time=c*60+e; % time quantity to be used in 'position'
time_qty=time/15;
plat_qty=tsinput(idx,3)*2;
box=annotation('textbox','units','centimeters','position',...
[time_qty plat_qty 1.5 1.5],'String',infoinput(idx,z),...
'ButtonDownFcn',#dragObject,'BackgroundColor',color);
% need to new=get(box,'Position'), fill out matrix OUT of loop
end
fillmenu=uicontextmenu;
hcb1 = 'set(gco, ''BackgroundColor'', ''red'')';
hcb2 = 'set(gco, ''BackgroundColor'', ''blue'')';
item1 = uimenu(fillmenu, 'Label', 'Train Full', 'Callback', hcb1);
item2 = uimenu(fillmenu, 'Label', 'Train Empty', 'Callback', hcb2);
hbox=findall(fig,'Type','hggroup');
for jdx=1:x
set(hbox(jdx),'uicontextmenu',fillmenu);
end
end
new_arr=tsinput;
function dragObject(hObject,eventdata)
dragging = hObject;
orPos = get(gcf,'CurrentPoint');
end
function dropObject(hObject,eventdata,box)
if ~isempty(dragging)
newPos = get(gcf,'CurrentPoint');
posDiff = newPos - orPos;
set(dragging,'Position',get(dragging,'Position') + ...
[posDiff(1:2) 0 0]);
dragging = [];
end
end
function moveObject(hObject,eventdata)
if ~isempty(dragging)
newPos = get(gcf,'CurrentPoint');
posDiff = newPos - orPos;
orPos = newPos;
set(dragging,'Position',get(dragging,'Position') + [posDiff(1:2) 0 0]);
end
end
end
% Testing purpose input matrices:
% tsinput=[0345 0405 1 1 ; 0230 0300 2 0; 0540 0635 3 1; 0745 0800 4 1]
% infoinput={'AJ35 NOT' 'KL21 MAN' 'XPRES'; 'ZW31 MAN' 'KM37 NEW' 'VISTA';
% 'BC38 BIR' 'QU54 LON' 'XPRES'; 'XZ89 LEC' 'DE34 MSF' 'DERP'}
If I understand you correctly (and please post some code if I'm not), then all you need is indeed a set/get combination.
If boxHandle is a handle to the text-box object, then you get its current position by:
pos = get (boxHandle, 'position')
where pos is the output array of [x, y, width, height].
In order to set to a new position, you use:
set (boxHandle, 'position', newPos)
where newPos is the array of desired position (with the same structure as pos).
EDIT
Regarding to updating your matrix, since you have the handle of the object you move, you actually DO have access to the specific text box.
When you create each text box, set a property called 'UserData' with the associated indices of tsinput used for that box. In your nested for loop add this
set (box, 'UserData', [idx, z]);
after the box is created, and in your moveObject callback get the data by
udata = get(dragging,'UserData');
Then udata contains the indices of the elements you want to update.

Resources