6 Replies - 666 Views - Last Post: 28 March 2016 - 11:50 AM Rate Topic: -----

#1 mike73  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 250
  • View blog
  • Posts: 918
  • Joined: 24-April 10

Map of list of list of images improvements

Posted 23 March 2016 - 06:11 PM

Hi all.

I'm looking for some advice on how to structure my collection for storing some images. Basically, I have 2 types of images, letters (Storing images of A - Z) and numbers (Storing 0 - 9). And each letter or number will have, say, 3 variations (all will have the same number of variatons). Now currently I have it set up that I have 3 folders, each with one variation of A- Z and 0 - 9. So I go through each folder, and store the letters and then the numbers in their own list. I then store each group of 3 lists in another list (So the 3 lists of letters in 1 list, and the other 3 lists of numbers in a second list). Lastly, I add these 2 lists to a Map using "lettter" and "numbers" as their key. I hope the code below will make it clearer:
    private final static String[] dirs = {
    		"/image_set_1", 
    		"/image_set_2",
    		"/image_set_3"
	};
    
    private final static String[] letters = { 
			"A", "B", "C", "D", "E", "F", "G", "H", "I",
			"J", "K", "L", "M", "N", "O", "P", "Q", "R",
			"S", "T", "U", "V", "W", "X", "Y", "Z"
	};
	
    private final static String[] numbers = { 
			"0", "1", "2", "3", "4",
			"5", "6", "7", "8", "9"
	};
    
    public static Map<String, List<List<BufferedImage>>> loadTemplates() {
    	final Map<String, List<List<BufferedImage>>> templates = new HashMap<>();
    	final List<List<BufferedImage>> letterTemplateSets = new LinkedList<>();
    	final List<List<BufferedImage>> numberTemplateSets = new LinkedList<>();
    	
    	for(int x = 0; x < dirs.length; x++) {
    		String directory = dirs[x];
    		
    		// load letters
    		List<BufferedImage> letterList = new LinkedList<>();
    		for(int i = 0; i < letters.length; i++) {
    			String path = directory + "/" + letters[i] + ".jpg";
    			try {
					BufferedImage templateImage = ImageIO.read(ImageProcessor.class.getResource(path));
					letterList.add(templateImage);
				} catch (IOException e) {
					e.printStackTrace();
				}
    		}
    		letterTemplateSets.add(letterList);    		
    		
    		// load numbers
    		List<BufferedImage> numberList = new LinkedList<>();
    		for(int i = 0; i < numbers.length; i++) {
    			String path = directory + "/" + numbers[i] + ".jpg";
    			try {
					BufferedImage templateImage = ImageIO.read(ImageProcessor.class.getResource(path));
					numberList.add(templateImage);
				} catch (IOException e) {
					e.printStackTrace();
				}
    		}
    		numberTemplateSets.add(numberList);    		
    	}
    	
    	templates.put("letters", letterTemplateSets);
		templates.put("numbers", numberTemplateSets);
		return templates;
    }


So at this point, I have a map of 2 lists, either letters or numbers, and each of those will have 3 lists, 1 for each folder.

Now my questions are this:
1. Have I gone overboard with a Map of list of list of images, or is it ok?
2. Any suggestions on a cleaner or more efficient way?

Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: Map of list of list of images improvements

#2 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1575
  • View blog
  • Posts: 3,540
  • Joined: 05-April 11

Re: Map of list of list of images improvements

Posted 23 March 2016 - 07:32 PM

Depends what you are trying to do.
What are you using all these images for? Does it make sense to use a map for the images?

I would probably start by implementing a class to represent the series of images
Should make it clear to the developer that the images belong together, and are part of a series.
public class ImageTemplate {
    private String templateName;
    private List<BufferedImage> images;
    
    public ImageTemplate(String templateName, List<BufferedImage> images) {
        this.templateName = templateName;
        this.images = images;
    }
}


And a class to hold the templates loaded, divided into number- and letter templates
public class ImageTemplates {
    private List<ImageTemplate> letterTemplates;
    private List<ImageTemplate> numberTemplates;
    
    public ImageTemplates(List<ImageTemplate> letterTemplates, List<ImageTemplate> numberTemplates) {
        this.letterTemplates = letterTemplates;
        this.numberTemplates = numberTemplates;
    }
}



You then end up with a pretty clean template loader, because it doesn't need to keep track of the list inside of lists ^^
Also it probably shouldn't be handling the IOException's that might be raised.
public static ImageTemplates loadTemplates(String directory) throws IOException {
    List<ImageTemplate> letterTemplates = new ArrayList<>();
    List<ImageTemplate> numberTemplates = new ArrayList<>();
    
    for (int i = 0; i < letters.length; i++) {
        letterTemplates.add(loadImageTemplate(letters[i]));
    }
    
    for (int i = 0; i < numbers.length; i++) {
        numberTemplates.add(loadImageTemplate(numbers[i]));
    }
    
    return new ImageTemplates(letterTemplates, numberTemplates);
}

private static ImageTemplate loadImageTemplate(String templateName) throws IOException {
    final List<BufferedImage> images = new ArrayList<>(3);
    
    for (String dir : dirs) {
        Path path = Paths.get(directory, templateName, ".jpg"); 
        BufferedImage image = ImageIO.read(ImageProcessor.class.getResource(path.toFile()));
        images.add(image);
    }
    
    return new ImageTemplate(templateName, images);
}



Ah, I made a mistake with the getResource and path.toFile() ^^
Was This Post Helpful? 1
  • +
  • -

#3 mike73  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 250
  • View blog
  • Posts: 918
  • Joined: 24-April 10

Re: Map of list of list of images improvements

Posted 25 March 2016 - 06:35 PM

Thanks for the reply, I'm liking the template loader idea.

I'll be using them for template matching to do charactar recognition, so ill just be cycling through each bunch of letters or numbers. I will know beforehand if a character will be a letter or number, so that's why I want that split (no point matching letter if number is expected). So easy access to each template(through a loop) is the only requirement really. The code will run on android eventually, but at most ill have a couple hundred small images, so shouldn't be an issue.

EDIT:
I noticed in this code, you pass in the directory but never use it, i'm assuming you intended to pass it the the loadImageTemplates method right?
public static ImageTemplates loadTemplates(String directory) throws IOException {
    	List<ImageTemplate> letterTemplates = new ArrayList<>();
    	List<ImageTemplate> numberTemplates = new ArrayList<>();
        
        for (int i = 0; i < letters.length; i++) {
            letterTemplates.add(loadImageTemplates(letters[i]));
        }
        
        for (int i = 0; i < numbers.length; i++) {
            numberTemplates.add(loadImageTemplates(numbers[i]));
        }
        
        return new ImageTemplates(letterTemplates, numberTemplates);
    }

This post has been edited by mike73: 25 March 2016 - 07:39 PM

Was This Post Helpful? 0
  • +
  • -

#4 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1575
  • View blog
  • Posts: 3,540
  • Joined: 05-April 11

Re: Map of list of list of images improvements

Posted 26 March 2016 - 06:25 AM

Yes I think that was the idea ^^
Was This Post Helpful? 0
  • +
  • -

#5 mike73  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 250
  • View blog
  • Posts: 918
  • Joined: 24-April 10

Re: Map of list of list of images improvements

Posted 26 March 2016 - 11:43 AM

Great, I have that working like a charm now, many thanks!

I have another question if you don't mind?
Would you keep it as the 2 seprate classes, ImageTemplate and ImageTemplates, or is there anything to be said for something like:
public class TemplateLoader {
		
	private TemplateLoader() {}
	
	public static ImageTemplates loadTemplates(String directory) throws IOException {
    	
    }

    private static ImageTemplate loadImageTemplates(String directory, String templateName) throws IOException {
       
    }
    
    private static class ImageTemplates {

    }

    private static class ImageTemplate {

    }
}


Basically have 1 class that uses them, and make them unavailable outside of this class?

This post has been edited by mike73: 26 March 2016 - 11:44 AM

Was This Post Helpful? 0
  • +
  • -

#6 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1575
  • View blog
  • Posts: 3,540
  • Joined: 05-April 11

Re: Map of list of list of images improvements

Posted 26 March 2016 - 05:11 PM

Your example doesn't make much sense, since the inner classes are private, but you're trying to expose them in your public methods.
I don't see what you accomplish by keeping them as inner classes?
Was This Post Helpful? 0
  • +
  • -

#7 mike73  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 250
  • View blog
  • Posts: 918
  • Joined: 24-April 10

Re: Map of list of list of images improvements

Posted 28 March 2016 - 11:50 AM

Well the idea was to be similar to say the java LinkedList class. It uses a private static Node class to hold the data and prev/next pointers. The idea there is that the user doesn't care about how the list actually stores it's data. I was thinking similar here, All I want from this class is some representation of all of my images. So should ImageTemplate or ImageTemplates be publicly available, or are these considered the inner workings of my TemplateLoader... Maybe this is going too secretive.

Basically I asked myself, would I ever want to create an ImageTemplate or ImageTemplates object somewhere else?

This post has been edited by mike73: 28 March 2016 - 11:51 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1