Do the same for every part in listdlg (MATLAB) - matlab

I am writing a program and I am using listdlg. I want for each selection of the list to do the same thing BUT it will save them in different part(so that every option will have it's own - let's say- sub folder with its text files and they can be accessed for another function.
So this is my listdlg
global fileCount
F = listdlg('PromptString','Different types', 'SelectionMode',...
'single', 'ListString',{E}, 'Name','Select a type','ListSize',[230 130]);
where {E} is user's input, which might be 3 rows or 6 rows, how many he likes.
So I want if he uses the first row to ask for input and then save it for the first type
if F == 1
[file,path] = uigetfile ('*.txt','Select your text files',...
'MultiSelect','on');
file = cellstr(file);
for k = 1:length(file)
fileCount = length (file);
z = importdata(fullfile(path, file{k}));
end
end
the same will be done for the following types, meaning if he chooses the 2nd then the files will be saved for the 2nd file, but the files of the first type will not be overwrote. So he now has let's say Orange-10files; Pink-2files and Yellow-4files.
Is there a way I can do that? except using if and elseif for every of his choice?
I hope I was clear enough!
Thanks!

Assign E as a cell array rather than inserting it as a cell array in the listdlg call. I'm not entirely clear on your end goal, but this will take the user's selection of E's elements, open whatever files the user selects, and return the path and file name of those files with the added "color" folder:
E = {'Orange','Pink','Yellow'};
F = listdlg('PromptString','Different types', 'SelectionMode',...
'single', 'ListString',E, 'Name','Select a type','ListSize',[230 130]);
[files,path] = uigetfile ('*.txt','Select your text files',...
'MultiSelect','on');
files = cellfun(#(x) fullfile(path,E{F},x),files,'UniformOutput',false);

Related

Matlab: read multiple files

my matlab script read several wav files contained in a folder.
Each read signal is saved in cell "mat" and each signal is saved in array. For example,
I have 3 wav files, I read these files and these signals are saved in arrays "a,b and c".
I want apply another function that has as input each signal (a, b and c) and the name of corresponding
file.
dirMask = '\myfolder\*.wav';
fileRoot = fileparts(dirMask);
Files=dir(dirMask);
N = natsortfiles({Files.name});
C = cell(size(N));
D = cell(size(N));
for k = 1:numel(N)
str =fullfile(fileRoot, Files(k).name);
[C{k},D{k}] = audioread(str);
mat = [C(:)];
fs = [D(:)];
a=mat{1};
b=mat{2};
c=mat{3};
myfunction(a,Files(1).name);
myfunction(b,Files(2).name);
myfunction(c,Files(3).name);
end
My script doesn't work because myfunction considers only the last Wav file contained in the folder, although
arrays a, b and c cointain the three different signal.
If I read only one wav file, the script works well. What's wrong in the for loop?
Like Cris noticed, you have some issues with how you structured your for loop. You are trying to use 'b', and 'c' before they are even given any data (in the second and third times through the loop). Assuming that you have a reason for structuring your program the way you do (I would rewrite the loop so that you do not use 'a','b', or 'c'. And just send 'myfunction' the appropriate index of 'mat') The following should work:
dirMask = '\myfolder\*.wav';
fileRoot = fileparts(dirMask);
Files=dir(dirMask);
N = natsortfiles({Files.name});
C = cell(size(N));
D = cell(size(N));
a = {};
b = {};
c = {};
for k = 1:numel(N)
str =fullfile(fileRoot, Files(k).name);
[C{k},D{k}] = audioread(str);
mat = [C(:)];
fs = [D(:)];
a=mat{1};
b=mat{2};
c=mat{3};
end
myfunction(a,Files(1).name);
myfunction(b,Files(2).name);
myfunction(c,Files(3).name);
EDIT
I wanted to take a moment to clarify what I meant by saying that I would not use the a, b, or c variables. Please note that I could be missing something in what you were asking so I might be explaining things you already know.
In a certain scenarios like this it is possible to articulate exactly how many variables you will be using. In your case, you know that you have exactly 3 audio files that you are going to process. So, variables a, b, and c can come out. Great, but what if you have to throw another audio file in? Now you need to go back in and add a 'd' variable and another call to 'myfunction'. There is a better way, that not only reduces complexity but also extends functionality to the program. See the following code:
%same as your code
dirMask = '\myfolder\*.wav';
fileRoot = fileparts(dirMask);
Files = dir(dirMask);
%slight variable name change, k->idx, slightly more meaningful.
%also removed N, simplifying things a little.
for idx = 1:numel(Files)
%meaningful variable name change str -> filepath.
filepath = fullfile(fileRoot, Files(idx).name);
%It was unclear if you were actually using the Fs component returned
%from the 'audioread' call. I wanted to make sure that we kept access
%to that data. Note that we have removed 'mat' and 'fs'. We can hold
%all of that data inside one variable, 'audio', which simplifies the
%program.
[audio{idx}.('data'), audio{idx}.('rate')] = audioread(filepath);
%this function call sends exactly the same data that your version did
%but note that we have to unpack it a little by adding the .('data').
myfunction(audio{idx}.('data'), Files(idx).name);
end

Load Data in Matlab GUI

I am developing a GUI where I want the input in text or excel format from user. When he will click on "Upload File" button from my GUI, the file browser will open and he will select the text file. Once he clicks open the file should be in workspace so my next code will take the value give results.
What I did is: Have this code under the push button
[filename,pathname] = uigetfile('*.txt')
loaddata = fullfile(pathname,filename)
data = load(loaddata)
A = data(:,1)
B = data(:,2)
C = data(:,3)
D = data(:,4)
handles.input1 = A;
handles.input2 = B;
handles.input3 = C;
handles.input4 = D;
Now when the Browser opens, I can select .txt file which is having 4 columns and 2000 rows of data. But when I go back to workspace, I can't see anything in workspace but all values from 2nd column in command window!
You can use setappdata and the associated getappdata to store application-defined data and retrieve it from elsewhere, for example from a GUI or the base workspace.
In your case, you could store A, B, C and D in the base workspace so they would be available from your other scripts. You can also store the handles structure if you want.
As an example, your code in the GUI could look like this:
[filename,pathname] = uigetfile('*.txt')
loaddata = fullfile(pathname,filename)
data = load(loaddata)
%// Store in the base workspace (i.e. the "0")
setappdata(0,'AllData',data);
Note that you could write anything you want as a name, as long as you retrieve the variable with the same name using getappdata. Here I used AllData but you could leave that as data just as well.
Therefore, in the other script you are running, use getappdata like so:
DataInScript = getappdata(0,'AllData');
A = AllData(:,1)
B = AllData(:,2)
C = AllData(:,3)
D = AllData(:,4)
So now, depending on whether you already assigned A, B, C and D you can access your data directly from AllData.

load folder's images names to a Matlab listbox

I'm trying to load all the images' names that exist in a particular folder that i selected using matlab GUI into a listbox.
the problem is that when i select the folder:
if it's empty, I can see the list empty with a white background color (which is the right thing).
But when i select a folder that contains images, the listbox disappears from the GUI. and i get a warning saying:
Warning: single-selection listbox control requires a scalar Value
Control will not be rendered until all of its parameter values are valid
i'm stuck in this issue for a long time, and i couldn't find a way to solve it.
here's the code i tried:
% --- Load up the listbox with tif files in folder handles.handles.ImageFolder
function handles=LoadImageList(handles)
ListOfImageNames = {};
folder = handles.ImageFolder;
if ~isempty(handles.ImageFolder)
if exist(folder,'dir') == false
warningMessage = sprintf('Note: the folder used when this program was last run:\n%s\ndoes not exist on this computer.\nPlease run Step 1 to select an image folder.', handles.ImageFolder);
msgboxw(warningMessage);
return;
end
else
msgboxw('No folder specified as input for function LoadImageList.');
return;
end
% If it gets to here, the folder is good.
ImageFiles = dir([handles.ImageFolder '/*.*']);
for Index = 1:length(ImageFiles)
baseFileName = ImageFiles(Index).name;
[folder, name, extension] = fileparts(baseFileName);
extension = upper(extension);
switch lower(extension)
case {'.png', '.bmp', '.jpg', '.tif', '.avi'}
% Allow only PNG, TIF, JPG, or BMP images
ListOfImageNames = [ListOfImageNames baseFileName];
otherwise
end
end
set(handles.lstImageList,'string',ListOfImageNames);
return
This happen to a Matlab uicontrol when some of it's parameters are set to an invalid value. Matlab choose to not display them.
In your case, the error message tells you the Value parameter is incorrect.
Your listbox is defined as a "single-selection", which means you can only have one line selected at a time. The Value parameter represent the line number which is selected. This parameter has to be a "scalar", a single number, not a vector which would represent several line selected (possible with "multi-selection" listboxes).
Note that Matlab doesn't support an empty Value either, so if your Value was set to [], it will also error when you populate the lisbox. (at least not on my R2009a version)
The simple way to overcome that, is to set the Value at the same time you populate the listbox:
set(handles.lstImageList,'string',ListOfImageNames,'Value',1);
The problem is with the way you create ListOfImageNames. The result of your code is a long string containing all the image names without any space or delimiter.
The String property of MATLAB's listbox expect a cell array with the strip of each line. You can try this:
ListOfImageNames =[];
NumOfImages = 0;
ImageFiles = dir([handles.ImageFolder '/*.*']);
for Index = 1:length(ImageFiles)
baseFileName = ImageFiles(Index).name;
[folder, name, extension] = fileparts(baseFileName);
extension = upper(extension);
switch lower(extension)
case {'.png', '.bmp', '.jpg', '.tif', '.avi'}
% Allow only PNG, TIF, JPG, or BMP images
NumOfImages = NumOfImages + 1;
ListOfImageNames{NumOfImages} = baseFileName;
otherwise
end
end
set(handles.lstImageList,'string',ListOfImageNames);

MATLAB Reading several images from folder

I have a folder called BasePics within a folder called Images. Inside BasePics there are 30 JPEG images. I'm wondering if the following is possible: Can a script be written that reads all of these images using the imread() command. The names of the images are somewhat sequential: C1A_Base.jpg, C1B_Base.jpg, C1C_Base.jpg, C2A_Base.jpg, C2B_Base.jpg, C2C_Base.jpg, etc.... all the way up to C10C_Base.jpg
Can a loop be used somehow:
file = dir('Images\BasePics');
NF = length(file);
for k = 1:NF
images(k) = imread(fullfile('ImagesBasePics',file(k))
imagesc(images(k))
end
This is a rough idea of what I want to do, but I'm wondering if it can be done with the current naming format I have in the Images folder. I would also like to have each image being read be its own variable with the same or similar name as it is named in the folder Images\BasePics currently, rather than have an concatenated array of 30 images all under the one variable images. I would like to have 30 separate variables, with names such as A1, A2,A3,B1,B2,B3 etc...
Also when I just ask for:
dir images\BasePics
Matlab outputs 33 files, instead of 30. There are two extra files at the beginning of the folder: '.' and '..' and one at the end: 'Thumbs.db' These do not exist when I look at the folder separately, is there a way to programically have Matlab skip over these?
Thanks!!
Since you know the names of the files in advance, you can skip the dir and go ahead and read the files:
for l = 'ABC'
for n=1:10
nm = sprintf('C%d%c_Base.jpg', n, l );
fnm = sprintf('%c%d', l, n );
imgs.(fnm) = imread( fullfile('images','BasePics', nm ) );
end
end
Now you have a struct imgs with fields A1...C10 for each image.
You are very close. I would just use dir('Images\BasePics\*.jpg') to get rid of the extraneous files.
The naming system you want will not lend itself to additional batch processing (do you really want to type all of A1, A2, etc?). I would either keep it sequential, and store a list of the filenames to match, or use a struct array, like images.C1A, etc.
dirlist = dir('Images\BasePics\*.jpg');
for k = 1:length(dirlist);
fname = dirlist(k).name;
[path,name,ext] = fileparts(fname); % separate out base name of file
images.(name) = imread(fullfile('Images\BasePics', fname));
end

How to export data from Matlab to excel for a loop?

I have a code for "for loop"
for i=1:4
statement...
y=sim(net, I);
end
now i need to export the value of y to excel sheet. for that i used..
xlswrite('output_data.xls', y, 'output_data', 'A1')
but my problem is that the ID of excel i.e. "A1" should change according to each iteration... in my case for iteration 1-> A1, iteration-> A2 and so on..
anybody please help me out ..
thanks in advance. for any assistance.. or suggestion..
You can store sim outputs in a vector (y(ii)) and save in the sheet with a single write. This is also more efficient since you perform a single bulk-write instead of many small writes.
Specify the first cell and y will be written starting from there.
last = someNumber;
for i=1:last statement... y(i)=sim(net, I); end
xlswrite('output_data.xls', y', 'output_data', 'A1');
If you prefer specify the range write ['A1:A',num2str(last)] instead of A1.
If you really want to write within the loop try:
for ii=1:last
...
y=sim(net, I);
xlswrite('output_data.xls', y, 'output_data', sprintf('A%d',ii));
end
You can also do for yourself what xlswrite does internally, which is interact using COM. I prefer to do this when I have a frequently used excel template or data file, because it allows for more control (albeit with more lines of code).
Excel = actxserver('Excel.Application');
Workbook = Excel.Workbooks.Open('myExcelFile.xlsx');
MySheet = Excel.ActiveWorkBook.Sheets.Item(1);
set( get(MySheet,'Range','A1:A10'), 'Value', yourValues);
...
invoke(Workbook, 'Save');
invoke(Excel, 'Quit');
delete(Excel);
This would allow you to save new data to new ranges without re-opening excel each time.
Even better would be to define an oncleanup function (as does xlswrite) to prevent lost file locks (especially when you're doing things like exiting out of debug mode):
...
myWorkbook = Excel.Workbooks.Open(filename,0,true);
cleanUp = onCleanup(#()xlsCleanup(Excel, filename));
function xlsCleanup(Excel,filepath)
try
Excel.DisplayAlerts = 0; %// Turn off dialog boxes
[~,n,e] = fileparts(filepath); %// Excel API expects just the filename
fileName = [n,e];
Excel.Workbooks.Item(fileName).Close(false);
end
Excel.Quit;
end
You can put xlswrite after for loop.You just want to do is save you result in a matrix.This function can write a matrix.
also,you can use [] to combine string to change the range.
>> for i=1:4
Range=['A' num2str(i)]
end
Range =
A1
Range =
A2
Range =
A3
Range =
A4
But,this is a bad way.You should open and write Excel file every time.