001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.demos.sandbox.vlad;
031
032import java.io.File;
033import java.io.FileInputStream;
034import java.io.IOException;
035import java.io.OutputStream;
036import java.net.URI;
037import java.util.Collections;
038import java.util.Comparator;
039import java.util.List;
040
041import javax.ws.rs.GET;
042import javax.ws.rs.Path;
043import javax.ws.rs.Produces;
044import javax.ws.rs.QueryParam;
045import javax.ws.rs.WebApplicationException;
046import javax.ws.rs.core.StreamingOutput;
047import javax.ws.rs.core.UriBuilder;
048
049import org.glassfish.grizzly.http.server.HttpServer;
050import org.openimaj.image.indexing.vlad.VLADIndexerData;
051import org.openimaj.io.IOUtils;
052import org.openimaj.knn.pq.FloatADCNearestNeighbours;
053import org.openimaj.util.pair.IntObjectPair;
054
055import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
056import com.sun.jersey.api.core.ClassNamesResourceConfig;
057import com.sun.jersey.api.core.ResourceConfig;
058
059@Path("/search")
060public class ServerTest {
061        static FloatADCNearestNeighbours nn;
062        static List<IntObjectPair<float[]>> index;
063        static String imageFormat;
064        static int offset;
065
066        static {
067                try {
068                        System.out.println("init");
069
070                        // final VLADIndexer indexer = VLADIndexer.read(new
071                        // File("/Users/jsh2/vlad-indexer-ukbench-2x.dat"));
072                        // index = IOUtils.readFromFile(new
073                        // File("/Users/jsh2/Desktop/ukb.idx"));
074                        // imageFormat = "/Users/jsh2/Data/ukbench/full/ukbench%05d.jpg";
075                        // offset = 0;
076                        final VLADIndexerData indexer = VLADIndexerData
077                                        .read(new File("/Users/jsh2/vlad-indexer-mirflickr25k-1x.dat"));
078                        index = IOUtils.readFromFile(new File("/Users/jsh2/Desktop/mirflickr25k.idx"));
079                        imageFormat = "/Volumes/Raid/mirflickr/mirflickr/im%d.jpg";
080                        offset = 1;
081
082                        for (final IntObjectPair<float[]> p : index)
083                                if (p.second == null)
084                                        p.second = new float[128];
085
086                        Collections.sort(index, new Comparator<IntObjectPair<float[]>>() {
087                                @Override
088                                public int compare(IntObjectPair<float[]> o1, IntObjectPair<float[]> o2)
089                                {
090                                        return o1.first == o2.first ? 0 : o1.first < o2.first ? -1 : 1;
091                                }
092                        });
093
094                        final List<float[]> data = IntObjectPair.getSecond(index);
095                        nn = new FloatADCNearestNeighbours(indexer.getProductQuantiser(), data.toArray(new float[data.size()][]));
096                } catch (final Exception e) {
097                        e.printStackTrace();
098                }
099        }
100
101        @GET
102        @Produces("text/html")
103        public String search(@QueryParam("i") int i)
104        {
105                final int length = 100;
106                final int[][] argmins = new int[1][length];
107                final float[][] mins = new float[1][length];
108                nn.searchKNN(new float[][] { index.get(i).second }, length, argmins, mins);
109
110                final StringBuffer sb = new StringBuffer();
111                sb.append("<html><body>");
112                for (int j = 0; j < length; j++) {
113                        sb.append("<div style='float:left; width: 100'>");
114                        sb.append("<a href=\"/search?i=" + argmins[0][j] + "\">");
115                        sb.append("<img width=\"100\" src=\"" + String.format("/search/image?i=%d", argmins[0][j]) + "\"/>");
116                        sb.append("</a>");
117                        sb.append(mins[0][j]);
118                        sb.append("</div>");
119                }
120                sb.append("</body></html>");
121
122                return sb.toString();
123        }
124
125        @GET
126        @Produces("image/jpeg")
127        @Path("/image")
128        public StreamingOutput image(@QueryParam("i") final int i) {
129                return new StreamingOutput() {
130                        @Override
131                        public void write(OutputStream output) throws IOException, WebApplicationException {
132                                final String imagename = String.format(imageFormat, i + offset);
133                                final FileInputStream fis = new FileInputStream(new File(imagename));
134                                org.apache.commons.io.IOUtils.copy(fis, output);
135                                fis.close();
136                        }
137                };
138        }
139
140        private static URI getBaseURI() {
141                return UriBuilder.fromUri("http://localhost/").port(9998).build();
142        }
143
144        public static final URI BASE_URI = getBaseURI();
145
146        protected static HttpServer startServer() throws IOException {
147                System.out.println("Starting grizzly...");
148                final ResourceConfig rc = new ClassNamesResourceConfig(ServerTest.class);
149                return GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
150        }
151
152        public static void main(String[] args) throws IOException {
153                final HttpServer httpServer = startServer();
154                System.in.read();
155                httpServer.stop();
156        }
157}