I have function that checks for bottle cap. If there is no cap detected, it writes it as an image into folder. My problem is that if I pass different image, the old one get overridden with new one, is there a way to make new image instead of overwriting old one such as nocap0,jpg, then new one nocap1.jpg etc?
Code:
function [ ] = CHECK_FOR_CAP( image )
%crop loaction of cap
imageCROP = imcrop(image,[130 0 100 50]);
%turn to BW
imageBW=im2bw(imageCROP);
%count black pixels
answer = sum(sum(imageBW==0));
%if <250 black, save it to folder NOCAP
if answer<250
imwrite(image, 'TESTINGFOLDERS/NOCAP/nocap.jpg', 'jpg');
disp('NO CAP DETECTED');
end
UPDATE
I changed the code a bit now. Everytime I give a different image it now writes new one, BUT it overwrites the previous one aswell like so: http://imgur.com/a/KIuvg
My new code:
function [ ] = CHECK_FOR_CAP( image )
folder = 'TESTINGFOLDERS/NOCAP';
filePattern = fullfile(folder, '/*.*');
ImageFiles = dir(filePattern);
%crop loaction of cap
imageCROP = imcrop(image,[130 0 100 50]);
%turn to BW
imageBW=im2bw(imageCROP);
%count black pixels
answer = sum(sum(imageBW==0));
%if <250 black, save it to folder NOCAP
if answer<250
a = length(ImageFiles)-1;
for j = 1:a
baseFileName = [num2str(j),'.jpg'];
filename = fullfile(folder,baseFileName);
if exist(filename,'file')
imwrite(image,filename);
end
imwrite(image, fullfile(filename));
end
disp('NO CAP DETECTED');
end
You write
for j = 1:a
baseFileName = [num2str(j),'.jpg'];
filename = fullfile(folder,baseFileName);
if exist(filename,'file')
imwrite(image,filename);
end
imwrite(image, fullfile(filename));
end
This means that whenever you find a file, you overwrite it. Then you overwrite it again. You do this for as many files as exist (a comes from some dir you do on your folder). What you want is the opposite: find one that does not exist. Something like this:
j = 0;
while true
j = j + 1;
baseFileName = [num2str(j),'.jpg'];
filename = fullfile(folder,baseFileName);
if ~exist(filename,'file')
break
end
end
imwrite(image, fullfile(filename));
This could be further shortened (e.g., by looping while exist(...)) but it conveys the idea...
Related
I have a script called 'main.m' that basically takes the paths where I've saved all my images and insert them in arrays. It saves the images name in a .dat file and call a function named 'selectFolder.m'.
I posted all the script and functions under, my request is at the bottom.
%% Folders
imgFolder = './1.Dataset/';
functFolder = './2.Functions/' ;
%resFolder = './3.Results/';
%% Add path
addpath(genpath(imgFolder));
addpath(genpath(functFolder));
%% Listing Folders where my images are at
myFolder1 = '../Always'; %folder path
[..] %12 folders in total
myFolder12 = '../Random'; %folder path
%% Distinguish folder 'Always' & 'Random'
% Always Folders: subset of images for all users
mfA = {myFolder1, myFolder3, myFolder5, myFolder7, myFolder9, myFolder11};
dimA = length(mfA);
% Random Folders: subset of images randomly showed
mfR = {myFolder2, myFolder4, myFolder6, myFolder8, myFolder10, myFolder12};
dimR = length(mfR);
% check if folders are present
for i = 1:dimA
if ~isdir(mfA{i})
errorMessage = sprintf('Error: The following folder does not exist:\n%s', mfA{i});
uiwait(warndlg(errorMessage));
return;
end
end
for j = 1:dimR
if ~isdir(mfR{j})
errorMessage = sprintf('Error: The following folder does not exist:\n%s', mfR{j});
uiwait(warndlg(errorMessage));
return;
end
end
%% Take images and insert'em in Arrays
% Always
MyImgs1 = dir(fullfile(mfA{1}, '*.jpg'));
[..] %for every cell
MyImgs6 = dir(fullfile(mfA{6}, '*.jpg'));
% Random
MyImgs1r = dir(fullfile(mfR{1}, '*.jpg'));
[..] %for every cell
MyImgs6r = dir(fullfile(mfR{6}, '*.jpg'));
% create arrays with images names
Array_mfA = {MyImgs1.name, MyImgs2.name, MyImgs3.name, MyImgs4.name, MyImgs5.name, MyImgs6.name};
Array_mfR = {MyImgs1r.name, MyImgs2r.name, MyImgs3r.name, MyImgs4r.name, MyImgs5r.name, MyImgs6r.name};
%% Print content of array on file
fileIDA = fopen('2.Functions/Array_Always.dat','w');
formatSpec = '%s,';
nrows = length(Array_mfA);
for row = 1 : nrows
fprintf(fileIDA, formatSpec, Array_mfA{row});
end
fclose(fileIDA);
fileIDR = fopen('2.Functions/Array_Random.dat','w');
formatSpec = '%s,';
nrows = length(Array_mfR);
for row = 1 : nrows
fprintf(fileIDR, formatSpec, Array_mfR{row});
end
fclose(fileIDR);
%disclaimer
nrc = 1;
file = fopen('2.Functions/disclaimer.dat', 'w');
fprintf(file, '%d', nrc);
fclose(file);
%% call function
selectFolder(mfA, mfR);
This function takes two array as input, these array contains all the names of my images sorted. It does some operation and then it calls another function 'selectImage.m' that displays fullscreen the selected image.
function [] = selectFolder(mfA, mfR)
clc
%% Open Arrays from file
% Always
fileID = fopen('2.Functions/Array_Always.dat', 'rt');
Array_A = textscan(fileID,'%s', 'Delimiter', ',');
fclose(fileID);
% Random
fileID2 = fopen('2.Functions/Array_Random.dat', 'rt');
Array_R = textscan(fileID2,'%s', 'Delimiter', ',');
fclose(fileID2);
%% Show Disclaimer
file = fopen('2.Functions/disclaimer.dat', 'r');
dis = fscanf(file, '%d');
fclose(file);
if (dis == 1)
set(gcf,'Toolbar','none','Menubar','none', 'NumberTitle','off');
set(gcf,'units','normalized','outerposition',[0 0 1 1]);
hAx = gca;
set(hAx,'Unit','normalized','Position',[0 0 1 1]);
imshow('1.Dataset/Disclaimer/DIS.jpg');
drawnow;
nrc = 0;
file = fopen('2.Functions/disclaimer.dat', 'w');
fprintf(file, '%d', nrc);
fclose(file);
return;
end
%% select random folder from 'Array_A' aka Always Array
dimA = length(mfA);
if ~isempty(Array_A{1})
rndn = randperm(dimA, 1);
A_check = Array_A;
while isequal(A_check,Array_A)
Array_A = selectImage(mfA{rndn}, Array_A);
if isequal(A_check,Array_A)
rndn = randperm(dimA, 1);
end
end
fileIDA = fopen('2.Functions/Array_Always.dat','w');
formatSpec = '%s,';
nrows = cellfun('length', Array_A);
for row = 1 : nrows
fprintf(fileIDA, formatSpec, Array_A{1}{row});
end
fclose(fileIDA);
return;
end
%% select random folder from 'Array_R' aka Random Array
if ~isempty(Array_R{1})
dimR = length(mfR);
rndnr = randperm(dimR, 1);
R_check = Array_R;
while isequal(R_check,Array_R)
Array_R = selectImage(mfR{rndnr}, Array_R);
if isequal(R_check, Array_R)
rndnr = randperm(dimR, 1);
end
end
fileIDR = fopen('2.Functions/Array_Random.dat','w');
formatSpec = '%s,';
nrows = cellfun('length', Array_R);
for row = 1 : nrows
fprintf(fileIDR, formatSpec, Array_R{1}{row});
end
fclose(fileIDR);
end
end
selectImage:
function [ Array ] = selectImage( myFolder, Array )
%% Check
MyImgs = dir(fullfile(myFolder, '*.jpg'));
dim = length(MyImgs);
n = 0;
for i = 1 : dim
MyImgs(i).name
if ~any(strcmp(Array{1}, MyImgs(i).name))
disp(MyImgs(i).name);disp('not present in ');disp(myFolder);
n = n + 1;
end
end
if (n == dim)
disp('empty folder')
return;
end
rN = randperm(dim, 1);
baseFileName = MyImgs(rN).name;
while ~any(strcmp(Array{1}, baseFileName))
fprintf(1, 'not present %s\n', baseFileName);
rN = randperm(dim, 1);
baseFileName = MyImgs(rN).name;
end
%% Dispay image
dim = cellfun('length', Array);
for i = 1 : dim
if strcmp(baseFileName, Array{1}(i))
Array{1}(i) = [];
break
end
end
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray = imread(fullFileName);
set(gcf,'Toolbar','none','Menubar','none', 'NumberTitle','off');
set(gcf,'units','normalized','outerposition',[0 0 1 1]);
hAx = gca;
set(hAx,'Unit','normalized','Position',[0 0 1 1]);
imshow(imageArray); % Display image.
drawnow;
end
Now I have to integrate these functions in my gui. What I want to do is call the 'main.m' script just one time with a button like 'Let's Start' and with that will show the disclaimer.
Then repeat the process calling only the 'Next' button, which calls 'selectFolder.m' and display the images with the procedure described above.
Is it possibile to do it this way? I mean, how can I pass the variable 'mfA' and 'mfR' to selectFolder? Is there a better and simpler way to do it?
The code in the gui is like:
-main:
% --- Executes on button press in Start.
function Start_Callback(hObject, eventdata, handles)
% hObject handle to Start (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
axes(handles.axes1);
figure
main
-selectFolder:
function Next_Callback(hObject, eventdata, handles)
% hObject handle to Next (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
axes(handles.axes1);
figure %show the image in another window
selectFolder(mfA, mfR)
An easy way to share variables among the callback of a GUI is to use the
guidata function.
With respect to your specific variables mfA and mfR you can use guidata
to store them, this way: in the callback in which you generate the variables you want to share with other callback you can insert the following code:
% Get the GUI data
my_guidata=guidata(gcf);
%
% section of your code in which you create the mfA and mfR vars
%
% Store the variables to be shared among the callbacks in the guidata
my_guidata.mfA=mfA;
my_guidata.mfR=mfR;
% Save the updated GUI data
guidata(gcf,my_guidata);
In the callback in which you wnat to retreive the data, you can insert the
following code:
% Get the GUI data
my_guidata=guidata(gcf);
% Retrieve the data from the GUI data structure
mfA=my_guidata.mfA;
mfR=my_guidata.mfR;
In both the examples, the struct my_guidata holds the handles of the GUI and the additional varaibles you have defined.
With respect to the the architecture of the GUI, there are lots of possibilities.
Firt a comment: looking at the two callback you've posted at the bottom of your question, it seems that your GUI has, at least, one axes, nevertheless, you create, in both of them a new figure so it is not clear the role of that axes
Considering now your questions
What I want to do is call the 'main.m' script just one time with a button like 'Let's Start' and with that will show the disclaimer. Then repeat the process calling only the 'Next' button, which calls 'selectFolder.m' and display the images with the procedure described above
call the 'main.m' script just one time with a button like 'Let's Start' and with that will show the disclaimer
You have just to copy the relevant code of your main in the Start pushbutton callback.
Notice that the code which shows the disclaimer is actually in your selectFolder function, so you have to move it in the
Start callback.
Then repeat the process calling only the 'Next' button, which calls 'selectFolder.m' and display the images with the procedure described above
to do this, you have to remove the call to selectFolder from the main and move the body of your in the Next pushbotton callback.
Also you can copy the selectImage in the GUI .m file.
Hope this helps.
Qapla'
Reading the content of the directory and for every JPEG image converting to grey scale
srcFiles = dir('R:\...\images - Copy\*.jpeg');
for i = 1 : length(srcFiles)
filename = srcFiles(i).name;
try
I = imread(filename);
catch ME
continue
end
IGrey = rgb2gray(I);
imshow(IGrey);
pathOfNewFile = strcat(pathOfGSFolder,filename,'jpeg');
imwrite(IGrey,pathOfNewFile,'jpeg');
end
'R:\...\images - Copy\' is not a valid path. A folder cannot be called ...
When trying to execute the first line you will probably get an error and the variable srcFiles will be empty, so the length of this variable will be 0 and therefore the loop will not execute.
I'm trying to create an image array and save it into a variable called manosData. I already tried this code
myFolder = 'C:\MATLAB\fotos';
filePattern = fullfile(myFolder, '*.jpg');
jpegFiles = dir(filePattern);
manosData = cell(1,numel(jpegFiles));
for k = 1:length(jpegFiles)
baseFileName = jpegFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray64x64 = imread(fullFileName);
imageArray64x64New = imresize(imageArray64x64, [64 64]);
manosData{k} = imageArray64x64New;
end
%Save
But when i try to plot my 8 images, i just get a blank window. This is the code am using for that:
load manosData
for j=1:9
subplot(3,3,j)
end
Thanks, Cath.
Try instead:
load manosData
for j=1:9
subplot(3,3,j)
image(manosData{j})
end
the command subplot just creates a subaxis to the current figure. You need to apply a plotting command, for example image, plot, or line to draw any content to the axes.
I have written this code to help me compare different image histograms however when i run it i get a figure window popping up. I can't see anywhere in the code where i have written imshow and am really confused. Can anyone see why? thanks
%ensure we start with an empty workspace
clear
myPath= 'C:\coursework\'; %#'
number_of_desired_results = 5; %top n results to return
images_path = strcat(myPath, 'fruitnveg');
images_file_names = dir(fullfile(images_path, '*.png'));
images = cell(length(images_file_names), 3);
number_of_images = length(images);
%textures contruction
%loop through all textures and store them
disp('Starting construction of search domain...');
for i = 1:length(images)
image = strcat(images_path, '\', images_file_names(i).name); %#'
%store image object of image
images{i, 1} = imread(image);
%store histogram of image
images{i, 2} = imhist(rgb2ind(images{i, 1}, colormap(colorcube(256))));
%store name of image
images{i, 3} = images_file_names(i).name;
disp(strcat({'Loaded image '}, num2str(i)));
end
disp('Construction of search domain done');
%load the three example images
RGB1 = imread('C:\coursework\examples\salmon.jpg');
X1 = rgb2ind(RGB1,colormap(colorcube(256)));
example1 = imhist(X1);
RGB2 = imread('C:\coursework\examples\eggs.jpg');
X2 = rgb2ind(RGB2,colormap(colorcube(256)));
example2 = imhist(X2);
RGB3 = imread('C:\coursework\examples\steak.jpg');
X3 = rgb2ind(RGB3,colormap(colorcube(256)));
example3 = imhist(X3);
disp('three examples loaded');
disp('compare examples to loaded fruit images');
results = cell(length(images), 2);
results2 = cell(length(images), 2);
results3 = cell(length(images), 2);
for i = 1:length(images)
results{i,1} = images{i,3};
results{i,2} = hi(example1,images{i, 2});
end
results = flipdim(sortrows(results,2),1);
for i = 1:length(images)
results2{i,1} = images{i,3};
results2{i,2} = hi(example2,images{i, 2});
end
results2 = flipdim(sortrows(results2,2),1);
for i = 1:length(images)
results3{i,1} = images{i,3};
results3{i,2} = hi(example3,images{i, 2});
end
results3 = flipdim(sortrows(results3,2),1);
The colormap function sets the current figure's colormap, if there is no figure one is created.
The second parameter of imhist should be the number of bins used in the histogram, not the colormap.
Run your code in the Matlab debugger, step through it line by line, and see when the figure window pops up. That'll tell you what's creating it.
Etienne's answer is right for why you're getting a figure, but I'd just like to add that colormap is unnecessary in this code:
images{i, 2} = imhist(rgb2ind(images{i, 1}, colormap(colorcube(256))));
All you need is:
images{i, 2} = imhist(rgb2ind(images{i, 1}, colorcube(256)));
The second input of rgb2ind should be a colormap, yes. But the output of colorcube is a colormap already. Unless you've got an existing figure and you either want to set the colormap of it or retrieve the colormap it is currently using, the actual function colormap is not necessary.
Other than opening an unnecessary figure, the output of your existing code won't be wrong, as I think in this situation colormap will just pass as an output argument the colormap it was given as an input argument. For example, if you want to set the current figure colormap to one of the inbuilts and return the actual colormap:
cmap = colormap('bone');
I have designed the following GUI in which there are an axes. I want to save the plot drawn inside them to a jpeg file. However, the file obtained is an image of the overall figure window. This is my code:
X = 0:pi/100:2*pi;
Y = sin(X);
fh = figure;
Pan1 = uipanel(fh,'Units','normalized','Position',[0 0 0.5 1],'title',...
'Panel1');
Pan2 = uipanel(fh,'Units','normalized','Position',[0.5 0 0.5 1],'title',...
'Panel2');
haxes = axes('Parent',Pan2,'Units', 'normalized','Position',...
[0.25 0.25 0.5 0.5]);
hplot = plot(haxes,X,Y);
xlabel(haxes,'Time (second)');
ylabel(haxes,'Amplitude (meter)');
title(haxes,'Sine function');
FileName = uiputfile('*.jpg','Save as');
saveas(hplot,FileName);
saveas only saves figures, not individual plots.
If you have a subplot, or a plot within a uicontrol like you have, you can make a temporary copy of the plot, save it, then delete the temporary copy:
ftmp = figure; atmp = axes;
copyobj(hplot, atmp);
saveas(ftmp, FileName);
delete(ftmp);
If you don't want the temporary copy to flash up on the screen during the copying step, you can use the 'Position' property of the figure to create it off-screen.
Hope that helps!
#Sam's answer is spot on, I just want to add that Matlab is smart enough to know what kind of file you want to save by inspecting the FileName string variable. If you set FileName to something that ends in .jpg, you can save a jpeg. Check out the saves docs to see all the other possible filetypes.
When using the saveas function to create jpeg the resolution is different as when manually saving the figure with File-->Save As..., It's more recommended to use hgexport instead, as follows:
hgexport(gcf, 'figure1.jpg', hgexport('factorystyle'), 'Format', 'jpeg');
This will do exactly as manually saving the figure.
source:
http://www.mathworks.com/support/solutions/en/data/1-1PT49C/index.html?product=SL&solution=1-1PT49C
This is my solution based on Sam Roberts and eykanal's answer:
X = 0:pi/100:2*pi;
Y = sin(X);
fh = figure('toolbar','none','menubar','none');
Pan1 = uipanel(fh,'Units','normalized','Position',[0 0 0.5 1],'title',...
'Panel1');
Pan2 = uipanel(fh,'Units','normalized','Position',[0.5 0 0.5 1],'title',...
'Panel2');
haxes = axes('Parent',Pan2,'Units', 'normalized','Position',...
[0.125 0.1 0.75 0.75]);
hplot = plot(haxes,X,Y);
xlabel(haxes,'Time (second)');
ylabel(haxes,'Amplitude (meter)');
title(haxes,'Sine function');
FileName = uiputfile('*.bmp;*.png;*.jpg;*.tif','Save as');
ftmp = figure('Menu','none','Toolbar','none','Units','normalized',...
'Position',[-1000 -1000 1 1]);
new_axes = copyobj(haxes, ftmp);
set(new_axes,'Units','normalized','Position',[0.1 0.1 0.8 0.8]);
saveas(ftmp, FileName);
delete(ftmp);
delete(fh);