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.
Related
So I have this code that draws zigzag-alike line
indicator("Custom zigzag", overlay=true)
bullish(at) => open[at] < close[at]
bearish(at) => open[at] > close[at]
break_up() =>
if close != open
at = 1
while close[at] == open[at]
at += 1
if bearish(at) and bullish(0)
true
else
false
else
false
break_down() =>
if close != open
at = 1
while close[at] == open[at]
at += 1
if bearish(0) and bullish(at)
true
else
false
else
false
u = break_up()
d = break_down()
plot(u?open[0] : d?open[0] : na, color = color.fuchsia, linewidth = 1, style = plot.style_line, offset=0)
I want to use the result in some further calculations, but I dont get it, how can I put the whole u?open[0] : d?open[0] : na in an array?
Roughly pushing values to an array variable leads to recalculation on each bar, IMO.
Or can I access somehow my own previous plot, since custom script call is not possible?
There are two ways to do it depending on do you want na values as it is or previous calculated values in place of na. You can save the whole thing in a variable and then use that to calculate anything like sma etc. First way
//Keeping na value
val=u?open[0] : d?open[0] : na
s=ta.sma(val,10)
plot(s)
Second way
//Replacing na values with previous values
var val=open[0]
val:=u?open[0] : d?open[0] : val[1]
s=ta.sma(val,10)
plot(s)
I've created a program for a project that tests images against one another to see whether or not it's the same image or not. I've decided to use correlation since the images I am using are styled in the same way and with this, I've been able to get everything working up to this point.
I now wish to create an array of images again, but this time, in order of their correlation. So for example, if I'm testing a 50 pence coin and I test 50 images against the 50 pence coin, I want the highest 5 correlations to be stored into an array, which can then be used for later use. But I'm unsure how to do this as each item in the array will need to have more than one variable, which will be the image location/name of the image and it's correlation percentage.
%Program Created By Ben Parry, 2016.
clc(); %Simply clears the console window
%Targets the image the user picks
inputImage = imgetfile();
%Targets all the images inside this directory
referenceFolder = 'M:\Project\MatLab\Coin Image Processing\Saved_Images';
if ~isdir(referenceFolder)
errorMessage = print('Error: Folder does not exist!');
uiwait(warndlg(errorMessage)); %Displays an error if the folder doesn't exist
return;
end
filePattern = fullfile(referenceFolder, '*.jpg');
jpgFiles = dir(filePattern);
for i = 1:length(jpgFiles)
baseFileName = jpgFiles(i).name;
fullFileName = fullfile(referenceFolder, baseFileName);
fprintf(1, 'Reading %s\n', fullFileName);
imageArray = imread(fullFileName);
imshow(imageArray);
firstImage = imread(inputImage); %Reading the image
%Converting the images to Black & White
firstImageBW = im2bw(firstImage);
secondImageBW = im2bw(imageArray);
%Finding the correlation, then coverting it into a percentage
c = corr2(firstImageBW, secondImageBW);
corrValue = sprintf('%.0f%%',100*c);
%Custom messaging for the possible outcomes
corrMatch = sprintf('The images are the same (%s)',corrValue);
corrUnMatch = sprintf('The images are not the same (%s)',corrValue);
%Looping for the possible two outcomes
if c >=0.99 %Define a percentage for the correlation to reach
disp(' ');
disp('Images Tested:');
disp(inputImage);
disp(fullFileName);
disp (corrMatch);
disp(' ');
else
disp(' ');
disp('Images Tested:');
disp(inputImage);
disp(fullFileName);
disp(corrUnMatch);
disp(' ' );
end;
imageArray = imread(fullFileName);
imshow(imageArray);
end
You can use struct() function to create structures.
Initializing an array of struct:
imStruct = struct('fileName', '', 'image', [], 'correlation', 0);
imData = repmat(imStruct, length(jpgFiles), 1);
Setting field values:
for i = 1:length(jpgFiles)
% ...
imData(i).fileName = fullFileName;
imData(i).image = imageArray;
imData(i).correlation = corrValue;
end
Extract values of correlation field and select 5 highest correlations:
corrList = [imData.correlation];
[~, sortedInd] = sort(corrList, 'descend');
selectedData = imData(sortedInd(1:5));
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.
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.
I'm getting a very irritating error whenever I do anything like this with arrays. I have code that sets up the array in the love.load() function:
function iceToolsInit()
objectArray = {} --for object handling
objectArrayLocation = 0
end
and then code that allows for the creation of an object. It basically grabs all of the info about said object and plugs it into an array.
function createObject(x, y, renderimage) --used in the load function
--objectArray is set up in the init function
objectArrayLocation = objectArrayLocation + 1
objectArray[objectArrayLocation] = {}
objectArray[objectArrayLocation]["X"] = x
objectArray[objectArrayLocation]["Y"] = y
objectArray[objectArrayLocation]["renderimage"] =
love.graphics.newImage(renderimage)
end
After this, an update function reads through the objectArray and renders the images accordingly:
function refreshObjects() --made for the update function
arrayLength = #objectArray
arraySearch = 0
while arraySearch <= arrayLength do
arraySearch = arraySearch + 1
renderX = objectArray[arraySearch]["X"]
renderY = objectArray[arraySearch]["Y"]
renderimage = objectArray[arraySearch]["renderimage"]
if movingLeft == true then --rotation for rightfacing images
renderRotation = 120
else
renderRotation = 0
end
love.graphics.draw(renderimage, renderX, renderY, renderRotation)
end
end
I of course clipped some unneeded code (just extra parameters in the array such as width and height) but you get the gist. When I set up this code to make one object and render it, I get this error:
attempt to index '?' (a nil value)
the line it points to is this line:
renderX = objectArray[arraySearch]["X"]
Does anyone know what's wrong here, and how I could prevent it in the future? I really need help with this.
It's off-by-one error:
arraySearch = 0
while arraySearch <= arrayLength do
arraySearch = arraySearch + 1
You run through the loop arrayLength+1 number of times, going through indexes 1..arrayLength+1. You want to go through the loop only arrayLength number of times with indexes 1..arrayLength. The solution is to change the condition to arraySearch < arrayLength.
Another (more Lua-ly way) is to write this as:
for arraySearch = 1, #objectArray do
Even more Lua-ly way is to use ipairs and table.field reference instead of (table["field"]):
function refreshObjects()
for _, el in ipairs(objectArray) do
love.graphics.draw(el.renderimage, el.X, el.Y, movingLeft and 120 or 0)
end
end
objectArray and movingLeft should probably be passed as parameters...