Hi-
I use a modified version of the BatchProcessFolders Macro to analyze all the images in a folder. In order to be as objective as possible, I would like to randomize the order that the images are processed (I have already blanked out the filename, so I cant cheat that way). Here is a snippet of the macro that call sends each file to processFile- function processFiles(dir) { list = getFileList(dir); for (i=0; i<list.length; i++) { if (endsWith(list[i], "/")) processFiles(""+dir+list[i]); else { showProgress(n++, count); path = dir+list[i]; processFile(path); } } } The array list then would contain the ordered list of files. Is there a way to randomize the order of these file in the array using the macro language? Thanks for the help, Mike |
Hi Mike,
One popular way is the Fisher Yates shuffle: http://en.wikipedia.org/wiki/Fisher-Yates_shuffle Here's a Friday afternoon macro for you! Cheers, Curtis //--------------------------- function shuffle(array) { n = array.length; // The number of items left to shuffle (loop invariant). while (n > 1) { k = randomInt(n); // 0 <= k < n. n--; // n is now the last pertinent index; temp = array[n]; // swap array[n] with array[k] (does nothing if k == n). array[n] = array[k]; array[k] = temp; } } // returns a random number, 0 <= k < n function randomInt(n) { return n * random(); } // a little test -- randomize a list of prime numbers primes = newArray(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97); shuffle(primes); for (i=0; i<primes.length; i++) print(primes[i]); //--------------------------- On Fri, Feb 27, 2009 at 3:28 PM, Mike Myerburg <[hidden email]> wrote: > Hi- > > I use a modified version of the BatchProcessFolders Macro to analyze all > the images in a folder. In order to be as objective as possible, I would > like to randomize the order that the images are processed (I have already > blanked out the filename, so I cant cheat that way). Here is a snippet of > the macro that call sends each file to processFile- > > function processFiles(dir) { > list = getFileList(dir); > for (i=0; i<list.length; i++) { > if (endsWith(list[i], "/")) > processFiles(""+dir+list[i]); > else { > showProgress(n++, count); > path = dir+list[i]; > processFile(path); > } > } > } > > The array list then would contain the ordered list of files. Is there a > way to randomize the order of these file in the array using the macro > language? > > Thanks for the help, Mike > |
In reply to this post by Mike Myerburg
Hi,
On Fri, 27 Feb 2009, Mike Myerburg wrote: > I use a modified version of the BatchProcessFolders Macro to analyze all > the images in a folder. In order to be as objective as possible, I > would like to randomize the order that the images are processed (I have > already blanked out the filename, so I cant cheat that way). Here is a > snippet of the macro that call sends each file to processFile- > > function processFiles(dir) { > list = getFileList(dir); > for (i=0; i<list.length; i++) { > if (endsWith(list[i], "/")) > processFiles(""+dir+list[i]); > else { > showProgress(n++, count); > path = dir+list[i]; > processFile(path); > } > } > } > > The array list then would contain the ordered list of files. Is there a > way to randomize the order of these file in the array using the macro > language? Maybe you want something like this (totally untested): function randomize(array) { for (i = 0; i < array.length - 1; i++) { j = i + floor(random() * (array.length - i)); if (i != j) { swap = array[j]; array[j] = array[i]; array[i] = swap; } } } The idea is to iterate over all indices (except the last one), pick a random index greater or equal to that index, and swap the respective list items. (You might need to fix the code to implement that idea; as I said, I did not test.) You would call the function directly after calling getFileList(): list = randomize(list); However, I see that you may have subdirectories; you will have to build a complete list of all files before randomizing in order to get an unbiased result. Ciao, Dscho |
In reply to this post by ctrueden
Hi,
On Fri, 27 Feb 2009, Curtis Rueden wrote: > //--------------------------- > function shuffle(array) { > n = array.length; // The number of items left to shuffle (loop > invariant). > while (n > 1) { > k = randomInt(n); // 0 <= k < n. > n--; // n is now the last pertinent index; Did you not mean to decrement n later in the loop? > temp = array[n]; // swap array[n] with array[k] (does nothing if k > == n). > array[n] = array[k]; > array[k] = temp; Like here? Ciao, Dscho |
Hi Johannes,
Did you not mean to decrement n later in the loop? > Well, I did steal it straight from the Wikipedia page, but I tested and it works as written. Intuitively, the n-- in in the right place because ImageJ macro arrays are 0-indexed, n starts at array.length, and the loop ends when n == 1. -Curtis On Fri, Feb 27, 2009 at 4:15 PM, Johannes Schindelin < [hidden email]> wrote: > Hi, > > On Fri, 27 Feb 2009, Curtis Rueden wrote: > > > //--------------------------- > > function shuffle(array) { > > n = array.length; // The number of items left to shuffle (loop > > invariant). > > while (n > 1) { > > k = randomInt(n); // 0 <= k < n. > > n--; // n is now the last pertinent index; > > Did you not mean to decrement n later in the loop? > > > temp = array[n]; // swap array[n] with array[k] (does nothing if > k > > == n). > > array[n] = array[k]; > > array[k] = temp; > > Like here? > > Ciao, > Dscho > |
In reply to this post by ctrueden
Awesome!
Worked perfectly. Thanks Curtis Rueden wrote: > Hi Mike, > > One popular way is the Fisher Yates shuffle: > http://en.wikipedia.org/wiki/Fisher-Yates_shuffle > > Here's a Friday afternoon macro for you! > > Cheers, > Curtis > > //--------------------------- > function shuffle(array) { > n = array.length; // The number of items left to shuffle (loop > invariant). > while (n > 1) { > k = randomInt(n); // 0 <= k < n. > n--; // n is now the last pertinent index; > temp = array[n]; // swap array[n] with array[k] (does nothing if k > == n). > array[n] = array[k]; > array[k] = temp; > } > } > > // returns a random number, 0 <= k < n > function randomInt(n) { > return n * random(); > } > > // a little test -- randomize a list of prime numbers > primes = newArray(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, > 53, 59, 61, 67, 71, 73, 79, 83, 89, 97); > shuffle(primes); > for (i=0; i<primes.length; i++) print(primes[i]); > //--------------------------- > > On Fri, Feb 27, 2009 at 3:28 PM, Mike Myerburg <[hidden email]> wrote: > >> Hi- >> >> I use a modified version of the BatchProcessFolders Macro to analyze all >> the images in a folder. In order to be as objective as possible, I would >> like to randomize the order that the images are processed (I have already >> blanked out the filename, so I cant cheat that way). Here is a snippet of >> the macro that call sends each file to processFile- >> >> function processFiles(dir) { >> list = getFileList(dir); >> for (i=0; i<list.length; i++) { >> if (endsWith(list[i], "/")) >> processFiles(""+dir+list[i]); >> else { >> showProgress(n++, count); >> path = dir+list[i]; >> processFile(path); >> } >> } >> } >> >> The array list then would contain the ordered list of files. Is there a >> way to randomize the order of these file in the array using the macro >> language? >> >> Thanks for the help, Mike >> > |
Free forum by Nabble | Edit this page |