Inserting multiple links into an image in Matlab? - image

This question is built off of this previous question 'here' I want to make 256 points on the image that all lead to different pdf documents based on the location of the *. I dont want to have to code in 256 separate filepaths. I have attempted some code below and have not been having any luck so far.
for i = 1:256
text(x(i),y(i),'*', 'ButtonDownFcn',['open(''' file ''');']);
end
function [filePath] = file()
%h = impoint;
%position = getPosition(h);
filePath = strcat('C:\Documents and Settings\Sentinelle\Desktop\LCModel\sl5_knt1\sl5_',x(1),'-',y(i),'.pdf');
end

It seems to me that your code is wrong in several places:
the file() function doesn't know the values of x and y
the file() function doesn't use the current value of i
the file path uses x(1) idependently of the value of i
You probably want
for i = 1:256
text(x(i), y(i), '*', 'ButtonDownFcn', ['open(''' file(x(i),y(i)) ''');']);
end
function [filePath] = file( x, y )
filePath = strcat('C:\Documents and Settings\Sentinelle\Desktop\LCModel\sl5_knt1\sl5_',x,'-',y,'.pdf');
end

Assuming x(i) and y(i) are integers, this should work:
prefix = 'C:\Documents and Settings\Sentinelle\Desktop\LCModel\sl5_knt1\sl5_'
for i = 1:256
filePath = [prefix num2str(x(i)) '-' num2str(y(i)) '.pdf'];
text(x(i),y(i),'*', 'ButtonDownFcn',['open(''' filePath ''');']);
end
If they aren't integers, you need to specify how the floating point number will be converted to a string. You can do that with the second argument of num2str, type:
help num2str
for details and browse from there.

Related

How to rename many images after processing with different parameters

Hello dear programmers,
I have a sequence of images and I would like to perform dilation on each of them with different dilation parameters. Then, I would like to save the processed images with new name including both the old name and the corresponding dilation parameter. My codes are as follows.
Input_folder =
Output_folder =
D = dir([Input_folder '*.jpg']);
Inputs = {D.name}';
Outputs = Inputs; % preallocate
%print(length(Inputs));
for k = 1:length(Inputs)
X = imread([Input_folder Inputs{k}]);
dotLocations = find(Inputs{k} == '.');
name_img = Inputs{k}(1:dotLocations(1)-1);
image1=im2bw(X);
vec = [3;6;10];
vec_l = length(vec);
for i = 1:vec_l
%se = strel('disk',2);
fprintf(num2str(vec(i)));
se = strel('diamond',vec(i)); %imdilate
im = imdilate(image1,se);
image2 = im - image1;
Outputs{k} = regexprep(Outputs{k}, name_img, strcat(name_img,'_', num2str(vec(i))));
imwrite(image2, [Output_folder Outputs{k}])
end
end
As it can be seen, I would like to apply dilation with parameters 3,6 and 10. Let us assume that an image has as name "image1", after processing it, I would like to have "image1_3", "image1_6" and "image1_10". However, I am getting as results "image1_3", "image1_6_3" and "image1_10_6_3". Please, how can I modify my codes to fix this problem?
This is because you rewrite each item of the Outputs variable three times, each time using the previous value to create a new value. Instead, you should use the values stored in Inputs new names. Another mistake in your code is that the size of Inputs and Outputs are equal, while for every file in the input folder, three files must be stored in the output folder.
I also suggest using fileparts function, instead of string processing, to get different parts of a file path.
vec = [3;6;10];
vec_l = length(vec);
Outputs = cell(size(Inputs, 1)*vec_l, 1); % preallocate
for k = 1:length(Inputs)
[~,name,ext] = fileparts([Input_folder Inputs{k}]);
% load image
for i = 1:vec_l
% modify image
newName = sprintf('%s_%d%s', name, vec(i), ext);
Outputs{(k-1)*vec_l+i} = newName;
imwrite(image2, [Output_folder newName])
end
end

Returning a 4D array from a function in MATLAB

I am trying to return a 4D array of image data from a function call in MATLAB. I'm not very advanced in MATLAB and I don't know what type of data I have to return from the function. Here is my function:
function classimg = loadImages(classdir,ext)
% create array of all images in directory
neg = dir([classdir ext]);
% get size of array (to loop through images)
numFileNeg = max(size(neg));
% create a 4D array to store our images
classimg = zeros(51,51,3,numFileNeg);
% loop through directory
for i=1:numFileNeg
classimg(:,:,:,i) = imread([myDir neg(i).name]);
end
end
Here is the function call:
negativeImgs = loadImages("C:\Users\example\Documents\TrainingImages\negatives\","*.jpg");
I cannot find any online documentation for the return type? Does anyone know what this would be? classimg is populated correctly so the code inner works.
You initialize classimg to be a 51x51x3xnumFileNeg matrix of zeros. You use the zeros function, so the datatype is double. To see this clearly, call your function from the command window, and then type "whos" to see both the size and datatype of classimg.
As Mike correctly points out, since you initialize classimg using zeros, and the default data type is double, your image data will be converted to double from whatever data type imread returns (often uint8).
If you would like classimg to be the same data type as your images (which I'm assuming all have the same type), you can load one image, get its class, and initialize classimg with that specific class. Here's how you could rewrite your function:
function classimg = loadImages(classdir, ext)
neg = dir(fullfile(classdir, ext));
numFileNeg = numel(neg);
tempImage = imread(fullfile(classdir, neg(1).name));
classimg = zeros(51, 51, 3, numFileNeg, class(tempImage));
classimg(:, :, :, 1) = tempImage;
for i = 2:numFileNeg
classimg(:, :, :, i) = imread(fullfile(classdir, neg(i).name));
end
end
Note that I made a couple of other changes. I used fullfile instead of concatenation of the directory and file names, since it handles any issues with file separators for you. I also used numel to get the number of files as Justin suggested in a comment.

Fast string splitting in MATLAB

I've been using MATLAB to read through a bunch of output files and have noticed that it was reading the files fairly slowly in comparison to a reader that I wrote in Python for the same files (on the order of 120s for MATLAB, 4s for Python on the same set). The files have a combination of letters and numbers, where the numbers I actually want each have a unique string on the same line, but there is no real pattern to the rest of the file. Is there a faster way to read in non-uniformly formatted text files in MATLAB?
I tried using the code profiler in MATLAB to see what takes the most time, and it seemed to be the strfind and strsplit functions. Deeper down, the strfun\private\strescape seems to be the culprit which takes up around 50% of the time, which is called by strsplit function.
I am currently using a combination of strfind and strsplit in order to search through a file for 5 specific strings, then convert the string after it into a double.
lots of text before this
#### unique identifying text here
lots of text before this
sometext X = #####
Y = #####
Z = #####
more text = ######
I am iterating through the file with approximately the following code, repeated for each number that is being found.
fid=fopen(filename)
tline=fgets(fid)
while ischar(tline)
if ~isempty(strfind(tline('X =')))
tempstring=strsplit(tline(13:length(tline)),' ');
result=str2double(char(tempstring(2)));
end
tline=fgets(fid);
end
I'm guessing this will be a bit faster, but maybe not by much.
s = fileread('texto');
[X,s] = strtok(strsplit(s, "X = "){2}); X = str2num(X);
[Y,s] = strtok(strsplit(s, "Y = "){2}); Y = str2num(Y);
[Z,s] = strtok(strsplit(s, "Z = "){2}); Z = str2num(Z);
Obviously this is highly specific to your text example. You haven't given me any more info on how the variables might change etc so presumably you'll have to implement try/catch blocks if files are not consistent etc.
PS. This is octave syntax which allows chaining operations. For matlab, split them into separate operations as appropriate.
EDIT: ach, nevermind, here's the matlab compatible one too. :)
s = fileread('texto');
C = strsplit(s, 'X = '); [X,s] = strtok(C{2}); X = str2num(X);
C = strsplit(s, 'Y = '); [Y,s] = strtok(C{2}); Y = str2num(Y);
C = strsplit(s, 'Z = '); [Z,s] = strtok(C{2}); Z = str2num(Z);

Returning multiple ints and passing them as multiple arguements in Lua

I have a function that takes a variable amount of ints as arguments.
thisFunction(1,1,1,2,2,2,2,3,4,4,7,4,2)
this function was given in a framework and I'd rather not change the code of the function or the .lua it is from. So I want a function that repeats a number for me a certain amount of times so this is less repetitive. Something that could work like this and achieve what was done above
thisFunction(repeatNum(1,3),repeatNum(2,4),3,repeatNum(4,2),7,4,2)
is this possible in Lua? I'm even comfortable with something like this:
thisFunction(repeatNum(1,3,2,4,3,1,4,2,7,1,4,1,2,1))
I think you're stuck with something along the lines of your second proposed solution, i.e.
thisFunction(repeatNum(1,3,2,4,3,1,4,2,7,1,4,1,2,1))
because if you use a function that returns multiple values in the middle of a list, it's adjusted so that it only returns one value. However, at the end of a list, the function does not have its return values adjusted.
You can code repeatNum as follows. It's not optimized and there's no error-checking. This works in Lua 5.1. If you're using 5.2, you'll need to make adjustments.
function repeatNum(...)
local results = {}
local n = #{...}
for i = 1,n,2 do
local val = select(i, ...)
local reps = select(i+1, ...)
for j = 1,reps do
table.insert(results, val)
end
end
return unpack(results)
end
I don't have 5.2 installed on this computer, but I believe the only change you need is to replace unpack with table.unpack.
I realise this question has been answered, but I wondered from a readability point of view if using tables to mark the repeats would be clearer, of course it's probably far less efficient.
function repeatnum(...)
local i = 0
local t = {...}
local tblO = {}
for j,v in ipairs(t) do
if type(v) == 'table' then
for k = 1,v[2] do
i = i + 1
tblO[i] = v[1]
end
else
i = i + 1
tblO[i] = v
end
end
return unpack(tblO)
end
print(repeatnum({1,3},{2,4},3,{4,2},7,4,2))

Load all the images from a directory

I have certain images in a directory and I want to load all those images to do some processing. I tried using the load function.
imagefiles = dir('F:\SIFT_Yantao\demo-data\*.jpg');
nfiles = length(imagefiles); % Number of files found
for i=1:nfiles
currentfilename=imagefiles(i).name;
I2 = imread(currentfilename);
[pathstr, name, ext] = fileparts(currentfilename);
textfilename = [name '.mat'];
fulltxtfilename = [pathstr textfilename];
load(fulltxtfilename);
descr2 = des2;
frames2 = loc2;
do_match(I1, descr1, frames1, I2, descr2, frames2) ;
end
I am getting an error as unable to read xyz.jpg no such file or directory found, where xyz is my first image in that directory.
I also want to load all formats of images from the directory instead of just jpg...how can i do that?
You can easily load multiple images with same type as follows:
function Seq = loadImages(imgPath, imgType)
%imgPath = 'path/to/images/folder/';
%imgType = '*.png'; % change based on image type
images = dir([imgPath imgType]);
N = length(images);
% check images
if( ~exist(imgPath, 'dir') || N<1 )
display('Directory not found or no matching images found.');
end
% preallocate cell
Seq{N,1} = []
for idx = 1:N
Seq{d} = imread([imgPath images(idx).name]);
end
end
I believe you want the imread function, not load. See the documentation.
The full path (inc. directory) is not held in imgfiles.name, just the file name, so it can't find the file because you haven't told it where to look. If you don't want to change directories, use fullfile again when reading the file.
You're also using the wrong function for reading the images - try imread.
Other notes: it's best not to use i for variables, and your loop is overwriting I2 at every step, so you will end up with only one image, not four.
You can use the imageSet object in the Computer Vision System Toolbox. It loads image file names from a given directory, and gives you the ability to read the images sequentially. It also gives you the option to recurse into subdirectories.

Resources