1 /** 2 * Copyright (c) 2011, The University of Southampton and the individual contributors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * * Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * * Neither the name of the University of Southampton nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.openimaj.image.model.patch; 31 32 import java.util.List; 33 34 import org.openimaj.image.FImage; 35 import org.openimaj.image.Image; 36 import org.openimaj.image.model.ImageClassificationModel; 37 import org.openimaj.util.pair.IndependentPair; 38 39 /** 40 * An {@link ImageClassificationModel} based on the idea of determining the 41 * probability of a class of a pixel given the local patch of pixels surrounding 42 * the pixel in question. A sliding window of a given size is moved across the 43 * image (with overlap), and the contents of the window are analysed to 44 * determine the probability belonging to the pixel at the centre of the window. 45 * 46 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 47 * 48 * @param <Q> 49 * Type of pixel 50 * @param <T> 51 * Type of {@link Image} 52 */ 53 public abstract class PatchClassificationModel<Q, T extends Image<Q, T>> implements ImageClassificationModel<T> { 54 private static final long serialVersionUID = 1L; 55 56 protected int patchHeight, patchWidth; 57 58 /** 59 * Construct with the given dimensions for the sampling patch. 60 * 61 * @param patchWidth 62 * the width of the sampling patch 63 * @param patchHeight 64 * the height of the sampling patch 65 */ 66 public PatchClassificationModel(int patchWidth, int patchHeight) { 67 this.patchHeight = patchHeight; 68 this.patchWidth = patchWidth; 69 } 70 71 /** 72 * Classify a patch, returning the probability of the central pixel 73 * belonging to the class. 74 * 75 * @param patch 76 * the patch. 77 * @return the probability of the central pixel belonging to the class. 78 */ 79 public abstract float classifyPatch(T patch); 80 81 @Override 82 public FImage classifyImage(T im) { 83 final FImage out = new FImage(im.getWidth(), im.getHeight()); 84 final T roi = im.newInstance(patchWidth, patchHeight); 85 86 final int hh = patchHeight / 2; 87 final int hw = patchWidth / 2; 88 89 for (int y = hh; y < im.getHeight() - (patchHeight - hh); y++) { 90 for (int x = hw; x < im.getWidth() - (patchWidth - hw); x++) { 91 im.extractROI(x - hw, y - hh, roi); 92 out.pixels[y][x] = this.classifyPatch(roi); 93 } 94 } 95 96 return out; 97 } 98 99 @Override 100 public abstract PatchClassificationModel<Q, T> clone(); 101 102 protected abstract T[] getArray(int length); 103 104 @Override 105 public boolean estimate(List<? extends IndependentPair<T, FImage>> data) { 106 final T[] samples = getArray(data.size()); 107 for (int i = 0; i < data.size(); i++) { 108 samples[i] = data.get(i).firstObject(); 109 } 110 learnModel(samples); 111 112 return true; 113 } 114 115 @Override 116 public int numItemsToEstimate() { 117 return 1; // need a minimum of 1 sample 118 } 119 120 @Override 121 public FImage predict(T data) { 122 return classifyImage(data); 123 } 124 }