I have a set of images in a folder which their names are: 2 days.bmp 3 days.bmp ..... 28 days.bmp. Also, I have a folder with the background images exactly with the same names. I want to use the calculator plus and divide each image to its relevant background. I want to save time and do that at the same time instead of doing it for each image one by one. Is there any idea how can I do that? I have written a macro but it didn't work for me.
macro "Batch calculate images [1]" {
LocationOfFiles = getDirectory("Select Folder");
LocationOfbackgrounds = getDirectory("Select Folder of backgrounds");
LocationOfSave = getDirectory("Select Save Location");
setBatchMode(true);
FileList = getFileList(LocationOfFiles);
NumberOfFiles = FileList.length;
for (i=0; i<NumberOfFiles; i+=1) {
FileName = FileList[i];
pathtofile1 = LocationOfFiles+FileName;
open(pathtofile1);
name1 = getTitle();
pathtofile2 = LocationOfbackgrounds+FileName;
open(pathtofile2);
name2 = getTitle();
run("Calculator Plus", "i1="+name1+" i2="+name2+" operation=[Divide: i2 = (i1/i2) x k1 + k2] k1=255 k2=0 create");
selectWindow("Result");
SaveName = replace(name, ".bmp", "_backgroud subtracted.jpg");
saveAs("BMP", LocationOfSave+SaveName);
selectWindow(BackgroundImage);
close("\\Others");
Related
I have a structure array with a large number of fields that I don't care about, so I want to extract the limited number of fields I DO care about and put it into a separate structure array.
For a structure array of size one, I've done this by creating the new array from scratch, for example:
structOld.a = 1;
structOld.b = 2;
structOld.usefulA = 'useful information';
structOld.usefulB = 'more useful information';
structOld.c = 3;
structOld.d = 'words';
keepFields = {'usefulA','usefulB'};
structNew = struct;
for fn = keepFields
structNew.(fn{:}) = structOld.(fn{:});
end
which gives
structNew =
usefulA: 'useful information'
usefulB: 'more useful information'
Is there a more efficient way of doing this? How can I scale up to an structure array (vector) of size N?
N = 50;
structOld(1).a = 1;
structOld(1).b = 2;
structOld(1).usefulA = 500;
structOld(1).usefulB = 'us';
structOld(1).c = 3;
structOld(1).d = 'ef';
structOld(2).a = 4;
structOld(2).b = 5;
structOld(2).usefulA = 501;
structOld(2).usefulB = 'ul';
structOld(2).c = 6;
structOld(2).d = 'in';
structOld(3).a = 7;
structOld(3).b = '8';
structOld(3).usefulA = 504;
structOld(3).usefulB = 'fo';
structOld(3).c = 9;
structOld(3).d = 'rm';
structOld(N).a = 10;
structOld(N).b = 11;
structOld(N).usefulA = 506;
structOld(N).usefulB = 'at';
structOld(N).c = 12;
structOld(N).d = 'ion';
In this case, I'd like to end up with:
structNew =
1x50 struct array with fields:
usefulA
usefulB
Keeping elements with empty usefulA/usefulB fields is fine; I can get rid of them later if needed.
Using rmfield isn't great because the number of useless fields far outnumbers the useful fields.
You can create a new struct array using existing data as follows:
structNew = struct('usefulA',{structOld.usefulA},'usefulB',{structOld.usefulB});
If you have an arbitrary set of field names that you want to preserve, you could use a loop as follows. Here, I'm first extracting the data from strcutOld into a cell array data, which contains each of the arguments the the struct call in the previous line of code. data{:} is now a comma-separated list of these arguments, the last line of code below is identical to the line above.
keepFields = {'usefulA','usefulB'};
data = cell(2,numel(keepFields));
for ii=1:numel(keepFields)
data{1,ii} = keepFields{ii};
data{2,ii} = {structOld.(keepFields{ii})};
end
structNew = struct(data{:});
I'm trying to find a way to batch combine multiple pairs of images into a single image horizontally. I have a folder of hundreds of photos (img01, img02,etc) and I'm trying to merge pairs of these:
img1 + img2 --> img1_2
img 519 + img 520 --> img519_520
The images are 3 x 4 inches and I want to combine them into pairs of horizontal 6 x 4 inch images.
I have found a way to do this for 2 specific photos but I don't know how to loop the code for all the photos in my image folder and save this as a 6x4 photo.
import numpy as np
from PIL import Image
images_list = ['img52.JPG', 'img53.JPG']
imgs = [ Image.open(i) for i in images_list ]
min_img_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]
img_merge = np.hstack( (np.asarray( i.resize(min_img_shape,Image.ANTIALIAS) ) for i in imgs )
img_merge = Image.fromarray( img_merge)
img_merge.save( 'Merged image.jpg' )
I am using a Mac OS High Sierra 10.13.4 and python Python 3.6.4.
Any help would be really appreciated!
Source of the above code: https://kanoki.org/2017/07/12/merge-images-with-python/
Update (as of 12 April 2018):
The following should work for a folder with an even number of photos, where the photos are named: img1.jpg, img2.jpg, etc. The script will take a pair of photos (e.g. img1.jpg and img2.jpg) and combine them.
#Note: I run the program in terminal after I change directory to my folder.
import numpy as np
from PIL import Image
images_list = []
for i in range(1,78): #insert last number of photo + 1 (in this case, I have 77 photos)
images_list.append('img'+str(i)+'.JPG')
count = 1;
directory = "path of directory" #change to directory where your photos are
ext = ".jpg"
new_file_name = "vimage-" #change to what you would like to name your photos
new_directory = "path of directory" # change to path of new directory where you want your photos to be saved
for j in range(0,len(images_list),2):
name = new_file_name + str(j) + ext
two_images_list = [images_list[j],images_list[j+1]]
imgs = [ Image.open(i) for i in two_images_list ]
min_img_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]
imgs_comb = np.hstack( (np.asarray( i.resize(min_img_shape) ) for i in imgs ) )
imgs_comb = Image.fromarray( imgs_comb)
imgs_comb.save(new_directory+'/'+name )
count +=1
Thanks a lot to #C. Tim for the helpful response!
Update (as of 12 April 2018):
If your images have a name as "img01.JPG", "img42.JPG", this code should work :
you generate all the names and put them in a list. For each pair of images your algorithm converts them into one image and the name of the images created change for every pair.
You must have an even number of images and the images need to be of the same dimension. Thanks a lot to #C. Tim for the helpful response.
# Note: I run the program in terminal after I change directory to my folder.
import numpy as np
from PIL import Image
images_list = []
for i in range(1,78): #insert last number of photo
images_list.append('img'+str(i)+'.JPG')
count = 1;
directory = "path of photos to resize" #change to directory where your photos are
ext = ".jpg"
new_file_name = "vimage-"
new_directory = "path to save in" # change to path of new directory where you want your photos to be saved
for j in range(0,len(images_list),2):
name = new_file_name + str(j) + ext
two_images_list = [images_list[j],images_list[j+1]]
imgs = [ Image.open(i) for i in two_images_list ]
min_img_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]
imgs_comb = np.hstack( (np.asarray( i.resize(min_img_shape) ) for i in imgs ) )
imgs_comb = Image.fromarray( imgs_comb)
imgs_comb.save(new_directory+'/'+name )
count +=1
I am fairly new to Matlab and I created this script to help me gather 4 numbers out of an excel file. This one works so far:
clear all
cd('F:/Wortpaare Analyse/Excel')
VPNumber = input('Which Participant Number?', 's');
filename = (['PAL_',VPNumber,'_Gain_Loss.xlsx']);
sheet = 1;
x1Range = 'N324';
GainBlock1 = xlsread(filename,sheet,x1Range);
x1Range = 'O324';
LossBlock1 = xlsread(filename,sheet,x1Range);
x1Range = 'AD324';
GainBlock2 = xlsread(filename,sheet,x1Range);
x1Range = 'AE324';
LossBlock2 = xlsread(filename,sheet,x1Range);
AnalyseProband = [GainBlock1, LossBlock1, GainBlock2, GainBlock2]
Now I would like to make a script that will analyze the first 20 excel files and tried this:
clear all
cd('F:/Wortpaare Analyse/Excel')
for VPNumber = 1:20 %for the 20 files
a = (['PAL_%d_Gain_Loss.xlsx']);
filename = sprintf(a, VPNumber) % specifies the name of the file
sheet = 1;
x1Range = 'N324';
(['GainBlock1_',VPNummer]) = xlsread(filename,sheet,x1Range);
....
end
The problem seems to be that I can only have one output argument. I would like to change the output argument in each loop, so it doesn't overwrite "GainBlock1" in every cycle.
In the end I would like to have these variables:
GainBlock1_1 (for the first excel sheet)
GainBlock1_2 (for the second excel sheet)
...
GainBlock1_20 (for the 20th excel sheet)
Is there a clever way to do that? I was able to write the first script fairly easily, but was unable to produce any significant progress in the second script. Any help is greatly appreciated.
Best,
Luca
This can be accomplished by either storing the data in an array or a cell. I believe an array will be sufficient for what you're trying to do. I've included a re-organized code sample below, broken out into functions to help make it easier to read and understand.
Basically, the first function handles the loop and controls where the data gets placed in the array, and the second function is your original script which accepts the VPNumber as an input.
What this should return is a 20x4 array, where the first index controls the sheet the data was pulled from and the second index controls whether it's [GainBlock1, LossBlock1, GainBlock2, LossBlock2]. i.e.- GainBlock 1 for sheet 5 would be AnalseProband(5,1), LossBlock2 for sheet 11 would be AnalyseProband(11,4).
function AnalyseProband = getAllProbands()
currentDir = pwd;
returnToOriginalDir = onCleanup(#()cd(currentDir));
cd('F:/Wortpaare Analyse/Excel')
numProbands = 20;
AnalyseProband = zeros(numProbands,4);
for n = 1:numProbands
AnalyseProband(n,:) = getBlockInfoFromXLS(n);
end
end
function AnalyseProband = getBlockInfoFromXLS(VPNumber)
a = 'PAL_%d_Gain_Loss.xlsx';
filename = sprintf(a, VPNumber); % specifies the name of the file
sheet = 1;
x1Range = 'N324';
GainBlock1 = xlsread(filename,sheet,x1Range);
x1Range = 'O324';
LossBlock1 = xlsread(filename,sheet,x1Range);
x1Range = 'AD324';
GainBlock2 = xlsread(filename,sheet,x1Range);
x1Range = 'AE324';
LossBlock2 = xlsread(filename,sheet,x1Range);
AnalyseProband = [GainBlock1, LossBlock1, GainBlock2, LossBlock2];
end
I tried to compare my template image ( image2 ) with image folders names as test* ( test1 , test 2 .... test n) to find correlation between my template image with images from that folder , then print result in that folder then go to next folder test2 .. till test n , thats mean the result of find correlation with each image in folder test1 its print as excel file named ( any name ) store in folder test1 and the content of that excel file as follow :
first row contain the names of images in folder test1 ,
second row contain the correlation result if 0 or 1 after that its jump to next folder test2 ...test3.... etc
the following code i tried long time
xls_sheet = 'Sheet1';
column_range = 'B'; % Initialisation of the column range
srcFolders = dir('D:\test*');
xls_filename = 'result.xls';
for folder = 1:length(srcFolders)
path = strcat('D:\',srcFolders(folder).name);
xlswrite('D:\srcFiles(i)\xls_filename',{srcFolders(folder).name},xls_sheet,folder_range); %Writing the name of the folder in the first row
sear = strcat(path, '\*.bmp');
srcFiles = dir(sear);
row_range = '2';
srcFolders = dir('D:\');
for folder = 1:length(srcFolders)
srcFolders(folder).fullname = strcat('image:\',srcFolders(folder).name);
end
xlswrite('D:\xlsFile', {srcFolders(:).fullname}, 'Sheet1','A2');
for i = 1 : length(srcFiles)
filename = strcat(path,'\',srcFiles(i).name);
Image1= imread(filename);
Image2 = imread('D:\act','jpeg');
x = corr2(Image1,Image2);
file_range = strcat(column_range, row_range);
if (x = 0)
xlswrite(xls_filename, {'0'}, xls_sheet, file_range ); %Writing '0' in the second row
else
xlswrite(xls_filename, {'1'}, xls_sheet, file_range ); %Writing '1' in the second row
end
end
row_range = char(row_range + 1); %Moving to the next row
column_range = char(column_range + 1); %Moving to the next column
end
i print names of files in first row , and
my questions how :
1- we can print excel file in each test* folders .
2- how can i repeat this process for all test* folders .
in the result i hope to get excel file in each and every folder in test1 , test 2 ... that contain 1 for corr=1 and 0 for others for all images in that folder.
I've got a folder which contains subfolders with text files. I want to read those file with the same order as they are in the subfolders. I've got a problem with that. I use the following matlab code:
outNames = {};
k=1;
feature = zeros(619,85);
fileN = cell(619,1);
for i=1:length(nameFolds)
dirList = dir(strcat(path, num2str(cell2mat(nameFolds(i,1)))));
names = {dirList.name};
outNames = {};
for j=1:numel(names)
name = names{j};
if ~isequal(name,'.') && ~isequal(name,'..')
[~,name] = fileparts(names{j});
outNames{end+1} = name;
fileName = strcat(path, num2str(cell2mat(nameFolds(i,1))), '\', name, '.descr' );
feature(k,:) = textread(fileName);
fileN{k} = [fileName num2str(k)];
k= k+1;
end
end
end
In one subfolder I've got the above text file names:
AnimalPrint_tiger_test_01.descr
AnimalPrint_tiger_test_02.descr
AnimalPrint_tiger_test_03.descr
AnimalPrint_tiger_test_04.descr
AnimalPrint_tiger_test_05.descr
AnimalPrint_tiger_test_06.descr
AnimalPrint_tiger_test_07.descr
AnimalPrint_tiger_test_08.descr
AnimalPrint_tiger_test_09.descr
AnimalPrint_tiger_test_10.descr
AnimalPrint_tiger_test_11.descr
AnimalPrint_tiger_test_12.descr
AnimalPrint_tiger_test_13.descr
AnimalPrint_tiger_test_14.descr
AnimalPrint_tiger_test_15.descr
AnimalPrint_zebra_test_1.descr
AnimalPrint_zebra_test_2.descr
AnimalPrint_zebra_test_3.descr
AnimalPrint_zebra_test_4.descr
AnimalPrint_zebra_test_5.descr
AnimalPrint_zebra_test_12.descr
But it seems that it reads first the AnimalPrint_zebra_test_12.descr and after the AnimalPrint_zebra_test_1.descr and the rest. Any idea why this happens?
dir sorts the files according to their names, for instance
test_1
test_12 % 1 followed by 2
test_2
test_3
You may want to build your own order with ['test_' num2str(variable) '.descr'] that concatenates test_ with an incrementing variable.