Skip to content
Browse files

finished serialization backend, optimized search to only sort the top…

… N hits instead of the full list
  • Loading branch information...
1 parent 2eb937d commit c38b6787e1f61dc34b5bf0a37b61a66d83920c6a Martin Dietze committed Apr 8, 2010
View
18 .gitignore
@@ -13,4 +13,22 @@ webapp/imageSearch.css
webapp/imageSearch.css~
webapp/imageSearch.wt
webapp/images/
+*/*~
+*~
+doc/hackerTalk/hackerTalk.aux
+doc/hackerTalk/hackerTalk.log
+doc/hackerTalk/hackerTalk.nav
+doc/hackerTalk/hackerTalk.out
+doc/hackerTalk/hackerTalk.pdf
+doc/hackerTalk/hackerTalk.snm
+doc/hackerTalk/hackerTalk.toc
+doc/hackerTalk/hackerTalkPrintVersion.pdf
+Debug/
+doc/hackerTalk/auto/
+importer/broken.jpg
+importer/dbBasedImporter
+importer/serializationBasedImporter
+webapp/imagesearch.log
+webapp/imagesearch.valgrind
+webapp/massif.out.19596
View
44 backend/BinaryScoreTableSerializer.cc
@@ -0,0 +1,44 @@
+#include "BinaryScoreTableSerializer.h"
+#include "PreSelectScoreTable.h"
+
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/serialization/export.hpp>
+#include <boost/serialization/vector.hpp>
+
+#include <stdexcept>
+
+using namespace ImageSearch;
+
+BOOST_CLASS_EXPORT_GUID (PreSelectScoreTable, "PreSelectScoreTable")
+
+BinaryScoreTableSerializer::BinaryScoreTableSerializer (void)
+{
+}
+
+BinaryScoreTableSerializer::~BinaryScoreTableSerializer (void)
+{
+}
+
+void
+BinaryScoreTableSerializer::doSave (const ScoreTable *scoreTable, const std::string &fileName)
+{
+ std::ofstream ofs (fileName.c_str (), std::ios::out | std::ios::binary);
+ boost::archive::binary_oarchive oa (ofs);
+ oa << scoreTable;
+}
+
+ScoreTable *
+BinaryScoreTableSerializer::doLoad (const std::string &fileName)
+{
+ ScoreTable *result;
+ std::ifstream ifs (fileName.c_str (), std::ios::in | std::ios::binary);
+ if (!ifs)
+ {
+ throw std::ios::failure ("error opening file " + fileName);
+ }
+ boost::archive::binary_iarchive ia (ifs);
+ ia >> result;
+ return result;
+}
+
View
19 backend/BinaryScoreTableSerializer.h
@@ -0,0 +1,19 @@
+#ifndef IMAGE_SEARCH_SCORE_TABLE_BINARY_SERIALIZER_H
+#define IMAGE_SEARCH_SCORE_TABLE_BINARY_SERIALIZER_H
+
+#include "ScoreTableSerializer.h"
+
+namespace ImageSearch
+{
+
+ class BinaryScoreTableSerializer : public ScoreTableSerializer {
+ public:
+ BinaryScoreTableSerializer (void);
+ virtual ~BinaryScoreTableSerializer (void);
+ virtual void doSave (const ScoreTable *scoreTable, const std::string &fileName);
+ virtual ScoreTable *doLoad (const std::string &fileName);
+ };
+
+};
+
+#endif // IMAGE_SEARCH_SCORE_TABLE_BINARY_SERIALIZER_H
View
2 backend/CMakeLists.txt
@@ -6,6 +6,8 @@ ADD_LIBRARY(Backend
DbBasedImageSearchBackend.cc
SerializationBasedImageSearchBackend.cc
ScoreTable.cc
+ BinaryScoreTableSerializer.cc
+ TextScoreTableSerializer.cc
PreSelectScoreTable.cc
postgresql/PostgresQl.cc
postgresql/PgSelect.cc
View
13 backend/DbBasedImageSearchBackend.cc
@@ -2,7 +2,7 @@
#include "PreSelectScoreTable.h"
#include "postgresql/PostgresQl.h"
#include "macros.h"
-#include "config.h"
+#include "../config.h"
#include <boost/thread/mutex.hpp>
@@ -21,7 +21,7 @@ DbBasedImageSearchBackend::DbBasedImageSearchBackend (const std::string &imageDb
if (m_imageDbPrefix.size () > 0)
{
- initScoreTable ();
+ p_initScoreTable ();
}
else
{
@@ -36,7 +36,7 @@ DbBasedImageSearchBackend::~DbBasedImageSearchBackend (void)
}
void
-DbBasedImageSearchBackend::initScoreTable (void)
+DbBasedImageSearchBackend::p_initScoreTable (void)
{
if (m_scoreTable == NULL)
{
@@ -52,7 +52,6 @@ DbBasedImageSearchBackend::initScoreTable (void)
std::cout << "loaded " << allImages.size ()
<< " images from the database." << std::endl;
- m_nDbImages = allImages.size ();
m_scoreTable = new PreSelectScoreTable (getDbImageRows (),
getDbImageCols (),
m_nKeptCoeffs);
@@ -74,7 +73,7 @@ DbBasedImageSearchBackend::initScoreTable (void)
std::string
DbBasedImageSearchBackend::getImageNameById (const unsigned long id)
{
- std::auto_ptr<DBImage> dbImage (getDbImageById (id));
+ std::auto_ptr<DBImage> dbImage (p_getDbImageById (id));
return dbImage->getFileName ();
}
@@ -85,13 +84,13 @@ DbBasedImageSearchBackend::saveDbImage (const DBImage &image)
}
ImageFeaturesList
-DbBasedImageSearchBackend::getAllDbImages (void)
+DbBasedImageSearchBackend::p_getAllDbImages (void)
{
return m_database->findAll ();
}
std::auto_ptr<DBImage>
-DbBasedImageSearchBackend::getDbImageById (int id)
+DbBasedImageSearchBackend::p_getDbImageById (int id)
{
return m_database->getById (id);
}
View
6 backend/DbBasedImageSearchBackend.h
@@ -25,9 +25,9 @@ namespace ImageSearch
virtual std::string getImageNameById (const unsigned long id);
private:
- void initScoreTable (void);
- std::auto_ptr<DBImage> getDbImageById (int id);
- ImageFeaturesList getAllDbImages (void);
+ void p_initScoreTable (void);
+ std::auto_ptr<DBImage> p_getDbImageById (int id);
+ ImageFeaturesList p_getAllDbImages (void);
Database *m_database;
};
View
1 backend/ImageScore.h
@@ -29,6 +29,7 @@ namespace ImageSearch
typedef std::vector<ImageScore> ImageScoreList;
typedef ImageScoreList::iterator ImageScoreIterator;
+ typedef ImageScoreList::const_iterator ImageScoreConstIterator;
};
View
86 backend/ImageSearchBackend.cc
@@ -1,7 +1,7 @@
#include "ImageSearchBackend.h"
#include "ImageScore.h"
#include "macros.h"
-#include "config.h"
+#include "../config.h"
#include <cxxutil/utils.h>
@@ -27,7 +27,6 @@
using namespace ImageSearch;
ScoreTable * ImageSearchBackend::m_scoreTable = NULL;
-unsigned long ImageSearchBackend::m_nDbImages = 0;
static std::string guessMimeType (const std::string &fileName);
@@ -148,7 +147,7 @@ ImageSearchBackend::getScoreTableInfoText(void) const
}
BLImage
-ImageSearchBackend::makeBlImage (const int id, const std::string &fileName,
+ImageSearchBackend::p_makeBlImage (const int id, const std::string &fileName,
const std::string &text)
{
std::string thumbNail = m_documentRoot + m_imageDbPrefix + "/thumb_"
@@ -165,21 +164,29 @@ ImageSearchBackend::performSearch (void)
m_searchResults.clear ();
if (isCurrentImageValid ())
{
- ImageScoreList result;
- for (int i = 0; i < m_nDbImages; ++i)
+ ImageScoreList result, sorted;
+ for (int i = 0; i < m_scoreTable->nImages (); ++i)
{
result.push_back (ImageScore (i));
}
- assert (result.size () == m_nDbImages);
+ assert (result.size () == m_scoreTable->nImages ());
std::auto_ptr<ColorImage> image (new ColorImage ());
image->read (m_currentTempFile.c_str ());
+
m_scoreTable->query (*image, result, false);
+
boost::timer timer;
- for (int i = 0; i < result.size () && i < m_maxResults; ++i)
+ p_sortScores (result, sorted);
+ int elapsed = (int)(timer.elapsed () * 1000);
+ std::cout << "sorting the query results took "
+ << elapsed << " milliseconds." << std::endl;
+
+ timer.restart ();
+ for (int i = 0; i < sorted.size () && i < m_maxResults; ++i)
{
- m_searchResults.push_back (getBlImage (result[i]));
+ m_searchResults.push_back (p_getBlImage (sorted[i]));
}
- int elapsed = (int)(timer.elapsed () * 1000);
+ elapsed = (int)(timer.elapsed () * 1000);
std::cout << "loading the images took "
<< elapsed << " milliseconds." << std::endl;
}
@@ -188,12 +195,12 @@ ImageSearchBackend::performSearch (void)
}
BLImage
-ImageSearchBackend::getBlImage (const ImageScore &score)
+ImageSearchBackend::p_getBlImage (const ImageScore &score)
{
std::string fileName = getImageNameById (score.getId ());
std::string text = "File: " + fileName
+ ", score: " + CxxUtil::dtoa (score.getScore ());
- return makeBlImage (score.getId (), fileName, text);
+ return p_makeBlImage (score.getId (), fileName, text);
}
bool
@@ -314,6 +321,63 @@ ImageSearchBackend::createImageFeatures (const std::string &path, int rows, int
}
+void
+ImageSearchBackend::p_sortScores (const ImageScoreList &scores, ImageScoreList &result)
+{
+ result.resize (m_maxResults);
+ ImageScoreConstIterator it = scores.begin ();
+ float worstScore = (*it).getScore ();
+ int worstPosition;
+ int lastPos = 0;
+
+ for (; it != scores.end (); ++it)
+ {
+
+ const ImageScore &score = *it;
+
+ if (lastPos < m_maxResults)
+ {
+
+ int pos = lastPos;
+ if (lastPos == 0 || score.getScore () > worstScore)
+ {
+ worstPosition = pos;
+ worstScore = result[worstPosition].getScore ();
+ }
+ result[pos] = score;
+ lastPos++;
+
+ }
+ else if (score.getScore () < worstScore)
+ {
+
+ result[worstPosition] = score;
+ for (int i = 0; i < m_maxResults; ++i)
+ {
+ if (result[i].getScore () > result[worstPosition].getScore ())
+ {
+ worstPosition = i;
+ }
+ }
+ worstScore = result[worstPosition].getScore ();
+
+ for (int i = 0; i < lastPos; ++i)
+ {
+ if (i != worstPosition && result[worstPosition].getScore () < result[i].getScore ())
+ {
+ std::cerr << "Error, " << result[worstPosition].getScore ()
+ << " is less than " << result[i].getScore () << " but it should not." << std::endl;
+ assert (0);
+ }
+ }
+
+ }
+
+ }
+
+ std::sort (result.begin (), result.end ());
+}
+
static void
fillFeatureVectors (const Image &img,
Features &posFeatures, Features &negFeatures)
View
10 backend/ImageSearchBackend.h
@@ -37,20 +37,20 @@ namespace ImageSearch
int getDbImageCols (void) const;
std::auto_ptr<ReadOnlyImage> createImageFeatures (const std::string &path,
int rows, int cols);
- int getNImages (void) const { return m_nDbImages; }
+ int nImages (void) const { return m_scoreTable->nImages (); }
protected:
virtual std::string getImageNameById (const unsigned long id) = 0;
static ScoreTable *m_scoreTable;
- static unsigned long m_nDbImages;
int m_nKeptCoeffs;
std::string m_documentRoot;
std::string m_imageDbPrefix;
private:
- BLImage makeBlImage (const int id, const std::string &fileName,
- const std::string &text);
- BLImage getBlImage (const ImageScore &score);
+ BLImage p_makeBlImage (const int id, const std::string &fileName,
+ const std::string &text);
+ BLImage p_getBlImage (const ImageScore &score);
+ void p_sortScores (const ImageScoreList &scores, ImageScoreList &result);
std::string m_currentTempFile;
int m_sizeY;
int m_sizeX;
View
40 backend/PreSelectScoreTable.cc
@@ -8,6 +8,7 @@ using namespace ImageSearch;
PreSelectScoreTable::PreSelectScoreTable (int rows, int cols, int nKeptCoeffs )
: ScoreTable (rows, cols, nKeptCoeffs)
{
+ m_nImages = 0;
int size = rows * cols;
std::cout << "resizing id-list-lists..." << std::endl;
m_positiveY.resize (size);
@@ -19,6 +20,11 @@ PreSelectScoreTable::PreSelectScoreTable (int rows, int cols, int nKeptCoeffs )
}
+PreSelectScoreTable::PreSelectScoreTable (void)
+ : ScoreTable (0, 0, 0)
+{
+}
+
PreSelectScoreTable::~PreSelectScoreTable (void)
{
}
@@ -39,11 +45,9 @@ PreSelectScoreTable::doLoadImages (const ImageFeaturesList &images)
<< usedSpace / 1024 << " kilobytes." << std::endl;
std::cout << "filling them..." << std::endl;
- unsigned long id = 0;
for (ImageFeaturesConstIterator it = images.begin (); it != images.end (); ++it)
{
- appendImage (id, **it);
- ++id;
+ appendImage (**it);
}
std::cout << "done." << std::endl;
int elapsed = (int)(timer.elapsed () * 1000);
@@ -53,20 +57,22 @@ PreSelectScoreTable::doLoadImages (const ImageFeaturesList &images)
}
void
-PreSelectScoreTable::doAppendImage (const unsigned long id, const ImageFeatures &image)
+PreSelectScoreTable::doAppendImage (const ImageFeatures &image)
{
- ScoreTable::doAppendImage (id, image);
-
- addImageFeatureVector (id, image.getFeaturesYPlus (), m_positiveY);
- addImageFeatureVector (id, image.getFeaturesYMinus (), m_negativeY);
- addImageFeatureVector (id, image.getFeaturesUPlus (), m_positiveU);
- addImageFeatureVector (id, image.getFeaturesUMinus (), m_negativeU);
- addImageFeatureVector (id, image.getFeaturesVPlus (), m_positiveV);
- addImageFeatureVector (id, image.getFeaturesVMinus (), m_negativeV);
+ const unsigned long id = m_nImages;
+
+ ScoreTable::doAppendImage (image);
+
+ p_addImageFeatureVector (id, image.getFeaturesYPlus (), m_positiveY);
+ p_addImageFeatureVector (id, image.getFeaturesYMinus (), m_negativeY);
+ p_addImageFeatureVector (id, image.getFeaturesUPlus (), m_positiveU);
+ p_addImageFeatureVector (id, image.getFeaturesUMinus (), m_negativeU);
+ p_addImageFeatureVector (id, image.getFeaturesVPlus (), m_positiveV);
+ p_addImageFeatureVector (id, image.getFeaturesVMinus (), m_negativeV);
}
void
-PreSelectScoreTable::addImageFeatureVector (int id, const Features &src,
+PreSelectScoreTable::p_addImageFeatureVector (int id, const Features &src,
IdListList &dest)
{
int size = m_rows * m_cols;
@@ -135,25 +141,25 @@ PreSelectScoreTable::p_query (ImageInformation &qY, ImageInformation &qU,
{
std::cerr << "score before Y: " << scores[9995].getScore() << " / " << scores[8337].getScore() << std::endl;
}
- querySingleColor (qY, scores, m_positiveY, m_negativeY, m_weightY, debug);
+ p_querySingleColor (qY, scores, m_positiveY, m_negativeY, m_weightY, debug);
if (debug)
{
std::cerr << "score before U: " << scores[9995].getScore() << " / " << scores[8337].getScore() << std::endl;
}
- querySingleColor (qU, scores, m_positiveU, m_negativeU, m_weightU, debug);
+ p_querySingleColor (qU, scores, m_positiveU, m_negativeU, m_weightU, debug);
if (debug)
{
std::cerr << "score before V: " << scores[9995].getScore() << " / " << scores[8337].getScore() << std::endl;
}
- querySingleColor (qV, scores, m_positiveV, m_negativeV, m_weightV, debug);
+ p_querySingleColor (qV, scores, m_positiveV, m_negativeV, m_weightV, debug);
if (debug)
{
std::cerr << "score after V: " << scores[9995].getScore() << " / " << scores[8337].getScore() << std::endl;
}
}
void
-PreSelectScoreTable::querySingleColor (ImageInformation &truncated,
+PreSelectScoreTable::p_querySingleColor (ImageInformation &truncated,
ImageScoreList &scores,
IdListList &positives,
IdListList &negatives,
View
34 backend/PreSelectScoreTable.h
@@ -2,6 +2,15 @@
#define IMAGE_SEARCH_PRESELECT_SCORE_TABLE_H
#include "ScoreTable.h"
+#include <boost/serialization/base_object.hpp>
+
+namespace boost
+{
+ namespace serialization
+ {
+ class access;
+ }
+}
namespace ImageSearch
{
@@ -12,8 +21,21 @@ namespace ImageSearch
virtual ~PreSelectScoreTable (void);
protected:
virtual void doLoadImages (const ImageFeaturesList &images);
- virtual void doAppendImage (const unsigned long id, const ImageFeatures &image);
+ virtual void doAppendImage (const ImageFeatures &image);
private:
+ PreSelectScoreTable (void);
+ friend class boost::serialization::access;
+ template<class Archive> void
+ serialize (Archive & ar, const unsigned int version)
+ {
+ ar & boost::serialization::base_object<ScoreTable>(*this);
+ ar & m_positiveY;
+ ar & m_negativeY;
+ ar & m_positiveU;
+ ar & m_negativeU;
+ ar & m_positiveV;
+ ar & m_negativeV;
+ }
typedef std::vector<int> IdList;
typedef IdList::iterator IdListIterator;
typedef std::vector<IdList> IdListList;
@@ -22,11 +44,11 @@ namespace ImageSearch
virtual void p_query (ImageInformation &qY, ImageInformation &qU,
ImageInformation &qV, ImageScoreList &scores,
bool debug = false);
- void addImageFeatureVector (int index, const Features &src,
- IdListList &dest);
- void querySingleColor (ImageInformation &truncated, ImageScoreList &scores,
- IdListList &positives, IdListList &negatives,
- const float weights[], bool debug = false);
+ void p_addImageFeatureVector (int index, const Features &src,
+ IdListList &dest);
+ void p_querySingleColor (ImageInformation &truncated, ImageScoreList &scores,
+ IdListList &positives, IdListList &negatives,
+ const float weights[], bool debug = false);
IdListList m_positiveY;
IdListList m_negativeY;
View
24 backend/ScoreTable.cc
@@ -1,4 +1,5 @@
#include "ScoreTable.h"
+#include "../config.h"
#include <WImage/ColorImage.hh>
#include <WTools/ImageComparison.hh>
@@ -14,10 +15,6 @@
using namespace ImageSearch;
-#define MAX_WEIGHT_IDX 5
-
-#define MY_WEIGHTS
-
#ifdef MY_WEIGHTS
//static const float gl_weights[][N_WEIGHTS] = {
@@ -74,8 +71,10 @@ ScoreTable::doLoadImages (const ImageFeaturesList &images)
}
void
-ScoreTable::doAppendImage (const unsigned long id, const ImageFeatures &image)
+ScoreTable::doAppendImage (const ImageFeatures &image)
{
+ const unsigned long id = m_nImages;
+
m_averageY.push_back (image.getAverageY ());
assert (floatEquals (m_averageY[id], image.getAverageY ()));
@@ -84,6 +83,9 @@ ScoreTable::doAppendImage (const unsigned long id, const ImageFeatures &image)
m_averageV.push_back (image.getAverageV ());
assert (floatEquals (m_averageV[id], image.getAverageV ()));
+
+ m_fileName.push_back (image.getFileName ());
+ assert (m_fileName[id] == image.getFileName ());
}
static bool
@@ -163,12 +165,6 @@ ScoreTable::query (const ColorImage &image, ImageScoreList &scores, bool debug)
elapsed = (int)(timer.elapsed () * 1000);
std::cout << "querying closest matches from all " << m_nImages
<< " images took " << elapsed << " milliseconds." << std::endl;
- timer.restart ();
-
- std::sort (scores.begin (), scores.end ());
- elapsed = (int)(timer.elapsed () * 1000);
- std::cout << "sorting the query results took "
- << elapsed << " milliseconds." << std::endl;
}
int
@@ -184,3 +180,9 @@ ScoreTable::getLevel (int i)
return m_lqcache[i];
}
+std::string
+ScoreTable::getImageNameById (const unsigned long id)
+{
+ assert (id < m_fileName.size ());
+ return m_fileName[id];
+}
View
35 backend/ScoreTable.h
@@ -13,6 +13,14 @@
class ColorImage;
class Image;
+namespace boost
+{
+ namespace serialization
+ {
+ class access;
+ }
+}
+
namespace ImageSearch
{
@@ -24,11 +32,27 @@ namespace ImageSearch
bool debug = false);
std::string getWeightsInfo () const;
void loadImages (const ImageFeaturesList &images) { doLoadImages (images); }
- void appendImage (const unsigned long id, const ImageFeatures &image) { doAppendImage (id, image); }
+ void appendImage (const ImageFeatures &image) { doAppendImage (image); ++m_nImages; }
+ virtual std::string getImageNameById (const unsigned long id);
+ inline int nImages (void) { return m_nImages; }
protected:
virtual void doLoadImages (const ImageFeaturesList &images);
- virtual void doAppendImage (const unsigned long id, const ImageFeatures &image);
+ virtual void doAppendImage (const ImageFeatures &image);
private:
+ friend class boost::serialization::access;
+ template<class Archive> void
+ serialize (Archive & ar, const unsigned int version)
+ {
+ ar & m_lqcache;
+ ar & m_nImages;
+ ar & m_rows;
+ ar & m_cols;
+ ar & m_nKeptCoeffs;
+ ar & m_averageY;
+ ar & m_averageU;
+ ar & m_averageV;
+ ar & m_fileName;
+ }
virtual void p_query (ImageInformation &qY, ImageInformation &qU,
ImageInformation &qV, ImageScoreList &scores,
bool debug = false) = 0;
@@ -42,12 +66,13 @@ namespace ImageSearch
std::vector<int> m_lqcache;
int m_nImages;
- const int m_rows;
- const int m_cols;
- const int m_nKeptCoeffs;
+ int m_rows;
+ int m_cols;
+ int m_nKeptCoeffs;
std::vector<float> m_averageY;
std::vector<float> m_averageU;
std::vector<float> m_averageV;
+ std::vector<std::string> m_fileName;
};
};
View
20 backend/ScoreTableSerializer.h
@@ -0,0 +1,20 @@
+#ifndef IMAGE_SEARCH_SCORE_TABLE_SERIALIZER_H
+#define IMAGE_SEARCH_SCORE_TABLE_SERIALIZER_H
+
+#include "ScoreTable.h"
+#include <iostream>
+
+namespace ImageSearch
+{
+
+ class ScoreTableSerializer {
+ public:
+ void save (const ScoreTable *scoreTable, const std::string &fileName) { std::cout << "saving to: " << fileName << std::endl; doSave (scoreTable, fileName); }
+ ScoreTable *load (const std::string &fileName) { doLoad (fileName); }
+ virtual void doSave (const ScoreTable *scoreTable, const std::string &fileName) = 0;
+ virtual ScoreTable *doLoad (const std::string &fileName) = 0;
+ };
+
+};
+
+#endif // IMAGE_SEARCH_SCORE_TABLE_SERIALIZER_H
View
74 backend/SerializationBasedImageSearchBackend.cc
@@ -1,37 +1,70 @@
#include "SerializationBasedImageSearchBackend.h"
#include "PreSelectScoreTable.h"
+#include "BinaryScoreTableSerializer.h"
+#include "TextScoreTableSerializer.h"
+#include "../config.h"
#include <boost/thread/mutex.hpp>
+#include <boost/timer.hpp>
+#include <fstream>
#include <iostream>
using namespace ImageSearch;
boost::mutex scoreTableMutex;
-SerializationBasedImageSearchBackend::SerializationBasedImageSearchBackend (const std::string &imageDbPrefix)
- : ImageSearchBackend (imageDbPrefix)
+static SERIALIZER_CLASS p_scoreTableSerialzer;
+
+SerializationBasedImageSearchBackend::SerializationBasedImageSearchBackend (const std::string &imageDbPrefix, const std::string &archiveFileName)
+ : ImageSearchBackend (imageDbPrefix), m_archiveFileName (archiveFileName)
+{
+ p_initScoreTable (LOAD);
+}
+
+SerializationBasedImageSearchBackend::SerializationBasedImageSearchBackend (const std::string &archiveFileName)
+ : ImageSearchBackend (""), m_archiveFileName (archiveFileName)
{
- initScoreTable ();
+ p_initScoreTable (EMPTY);
}
SerializationBasedImageSearchBackend::~SerializationBasedImageSearchBackend (void)
{
}
void
-SerializationBasedImageSearchBackend::initScoreTable (void)
+SerializationBasedImageSearchBackend::p_initScoreTable (const InitMode &initMode)
{
if (m_scoreTable == NULL)
{
boost::mutex::scoped_lock lock (scoreTableMutex);
if (m_scoreTable == NULL)
{
- std::cout << "Setting up Score Table" << std::endl;
- m_scoreTable = new PreSelectScoreTable (getDbImageRows (),
- getDbImageCols (),
- m_nKeptCoeffs);
- std::cout << "Done" << std::endl;
+ if (initMode == LOAD)
+ {
+ std::cout << "Loading Score Table from file " << m_archiveFileName << std::endl;
+ try
+ {
+ boost::timer timer;
+ m_scoreTable = p_scoreTableSerialzer.load (m_archiveFileName);
+ int elapsed = (int)(timer.elapsed () * 1000);
+ std::cout << "loading the images took "
+ << elapsed << " milliseconds." << std::endl;
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "exception caught: " << e.what () << std::endl;
+ exit (1);
+ }
+ }
+ else
+ {
+ std::cout << "Setting up empty Score Table" << std::endl;
+ m_scoreTable = new PreSelectScoreTable (getDbImageRows (),
+ getDbImageCols (),
+ m_nKeptCoeffs);
+ }
+ std::cout << "Loaded " << m_scoreTable->nImages () << " images, done" << std::endl;
}
else
{
@@ -46,20 +79,29 @@ SerializationBasedImageSearchBackend::initScoreTable (void)
}
void
-SerializationBasedImageSearchBackend::addImage (const unsigned long id,
- const std::string imageName,
+SerializationBasedImageSearchBackend::addImage (const std::string imageName,
const int rows, const int cols)
{
std::auto_ptr<ImageFeatures> image (createImageFeatures (imageName, rows, cols));
- m_scoreTable->appendImage (id, *image);
- ++m_nDbImages;
+ m_scoreTable->appendImage (*image);
}
+void
+SerializationBasedImageSearchBackend::save (void)
+{
+ try
+ {
+ p_scoreTableSerialzer.save (m_scoreTable, m_archiveFileName);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "exception caught: " << e.what () << std::endl;
+ exit (1);
+ }
+}
std::string
SerializationBasedImageSearchBackend::getImageNameById (const unsigned long id)
{
- //std::auto_ptr<DBImage> dbImage (getDbImageById (id));
- //return dbImage->getFileName ();
- return "foo";
+ return m_scoreTable->getImageNameById (id);
}
View
11 backend/SerializationBasedImageSearchBackend.h
@@ -11,16 +11,21 @@ namespace ImageSearch
class SerializationBasedImageSearchBackend : public ImageSearchBackend {
public:
- SerializationBasedImageSearchBackend (const std::string &imageDbPrefix);
+ SerializationBasedImageSearchBackend (const std::string &imageDbPrefix,
+ const std::string &archiveFileName);
+ SerializationBasedImageSearchBackend (const std::string &archiveFileName);
virtual ~SerializationBasedImageSearchBackend (void);
- void addImage (const unsigned long id, const std::string imageName,
+ void addImage (const std::string imageName,
const int rows, const int cols);
+ void save (void);
protected:
virtual std::string getImageNameById (const unsigned long id);
private:
- void initScoreTable (void);
+ typedef enum { EMPTY, LOAD } InitMode;
+ void p_initScoreTable (const InitMode &initMode);
+ std::string m_archiveFileName;
};
};
View
44 backend/TextScoreTableSerializer.cc
@@ -0,0 +1,44 @@
+#include "TextScoreTableSerializer.h"
+#include "PreSelectScoreTable.h"
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/serialization/export.hpp>
+#include <boost/serialization/vector.hpp>
+
+#include <stdexcept>
+
+using namespace ImageSearch;
+
+BOOST_CLASS_EXPORT_GUID (PreSelectScoreTable, "PreSelectScoreTable")
+
+TextScoreTableSerializer::TextScoreTableSerializer (void)
+{
+}
+
+TextScoreTableSerializer::~TextScoreTableSerializer (void)
+{
+}
+
+void
+TextScoreTableSerializer::doSave (const ScoreTable *scoreTable, const std::string &fileName)
+{
+ std::ofstream ofs (fileName.c_str ());
+ boost::archive::text_oarchive oa (ofs);
+ oa << scoreTable;
+}
+
+ScoreTable *
+TextScoreTableSerializer::doLoad (const std::string &fileName)
+{
+ ScoreTable *result;
+ std::ifstream ifs (fileName.c_str ());
+ if (!ifs)
+ {
+ throw std::ios::failure ("error opening file " + fileName);
+ }
+ boost::archive::text_iarchive ia (ifs);
+ ia >> result;
+ return result;
+}
+
View
19 backend/TextScoreTableSerializer.h
@@ -0,0 +1,19 @@
+#ifndef IMAGE_SEARCH_SCORE_TABLE_TEXT_SERIALIZER_H
+#define IMAGE_SEARCH_SCORE_TABLE_TEXT_SERIALIZER_H
+
+#include "ScoreTableSerializer.h"
+
+namespace ImageSearch
+{
+
+ class TextScoreTableSerializer : public ScoreTableSerializer {
+ public:
+ TextScoreTableSerializer (void);
+ virtual ~TextScoreTableSerializer (void);
+ virtual void doSave (const ScoreTable *scoreTable, const std::string &fileName);
+ virtual ScoreTable *doLoad (const std::string &fileName);
+ };
+
+};
+
+#endif // IMAGE_SEARCH_SCORE_TABLE_TEXT_SERIALIZER_H
View
13 backend/config.h → config.h
@@ -1,15 +1,24 @@
#ifndef IMAGE_SEARCH_CONFIG_H
#define IMAGE_SEARCH_CONFIG_H
+#define MAX_WEIGHT_IDX 5
+#define MY_WEIGHTS
+
+#define MAX_RESULTS 16
+
#define THUMB_ROWS 250
#define THUMB_COLS 250
+#define DB_PREFIX "/images/shirts"
+//#define DB_FILE "../imagedb.txt"
+//#define SERIALIZER_CLASS TextScoreTableSerializer
+#define DB_FILE "../imagedb.bin"
+#define SERIALIZER_CLASS BinaryScoreTableSerializer
+
#define DB_IMAGE_COLS 128
#define DB_IMAGE_ROWS 128
#define KEPT_COEFFS 40
-#define MAX_RESULTS 40
-
#define DB_NAME "images"
#define TABLE_NAME "images"
View
1 importer/CMakeLists.txt
@@ -32,4 +32,5 @@ TARGET_LINK_LIBRARIES(serializationBasedImporter
CxxUtil
pqxx
boost_thread-mt
+ boost_serialization-mt
)
View
31 importer/serializationBasedMain.cc
@@ -1,4 +1,5 @@
#include "SerializationBasedImageSearchBackend.h"
+#include "../config.h"
#include <string>
#include <stdexcept>
@@ -9,33 +10,45 @@ using namespace ImageSearch;
int
main(int argc, char **argv)
{
- std::cout << "importer start" << std::endl;
- SerializationBasedImageSearchBackend backend ("");
+ std::cout << "importer start, dumping to " << DB_FILE << std::endl;
+ SerializationBasedImageSearchBackend backend (DB_FILE);
const int rows = backend.getDbImageRows ();
const int cols = backend.getDbImageCols ();
int rc = 0;
std::string imageName;
- int id = 0;
+ int i = 0;
while (!std::cin.eof ())
{
std::getline (std::cin, imageName);
if (imageName.size () > 0)
{
- std::cout << "processing image: \"" << imageName
- << "\"..." << std::endl;
+ if (i > 0)
+ {
+ std::cout << ", ";
+ }
+ std::cout << "processing image: \"" << imageName << "\"";
try
{
- backend.addImage (id, imageName, rows, cols);
- ++id;
+ backend.addImage (imageName, rows, cols);
+ ++i;
}
catch (const std::exception &e)
{
- std::cerr << "exception caught: " << e.what () << std::endl;
+ std::cerr << imageName << ": exception caught: " << e.what () << std::endl;
rc++;
}
}
}
- std::cout << "importer successfully finished, indexed " << backend.getNImages () << " images." << std::endl;
+ std::cout << "saving..." << std::endl;
+ try
+ {
+ backend.save ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "exception caught: " << e.what () << std::endl;
+ }
+ std::cout << "importer successfully finished, indexed " << backend.nImages () << " images." << std::endl;
return rc;
}
View
1 webapp/CMakeLists.txt
@@ -24,4 +24,5 @@ TARGET_LINK_LIBRARIES(imageSearch.wt
wtext
pqxx
boost_thread-mt
+ boost_serialization-mt
)
View
59 webapp/ImageSearch.cc
@@ -1,8 +1,9 @@
#include "ImageSearch.h"
#include "Div.h"
#include "SearchResult.h"
+#include "../config.h"
-#include <DbBasedImageSearchBackend.h>
+#include <SerializationBasedImageSearchBackend.h>
#include <Wt/WBreak>
#include <Wt/WText>
@@ -18,23 +19,21 @@
#include <iostream>
#include <fstream>
-#define MAX_RESULTS 16
-
using namespace ImageSearch;
ImageSearchApplication::ImageSearchApplication (const Wt::WEnvironment& env)
: Wt::WApplication (env)
{
- m_backend = new DbBasedImageSearchBackend ("/images/dehdabehs");
+ m_backend = new SerializationBasedImageSearchBackend (DB_PREFIX, DB_FILE);
setTitle ("Image Search");
- setupTopSection ();
+ p_setupTopSection ();
- setupInputs ();
+ p_setupInputs ();
- setupSearchResults();
+ p_setupSearchResults();
useStyleSheet ("imageSearch.css");
@@ -46,7 +45,7 @@ ImageSearchApplication::ImageSearchApplication (const Wt::WEnvironment& env)
try
{
imageId = CxxUtil::atoi (image[0]);
- searchByImageId (imageId);
+ p_searchByImageId (imageId);
}
catch (const std::exception e)
{
@@ -57,7 +56,7 @@ ImageSearchApplication::ImageSearchApplication (const Wt::WEnvironment& env)
}
void
-ImageSearchApplication::setupTopSection (void)
+ImageSearchApplication::p_setupTopSection (void)
{
Div *atTop = new Div ("atTop", "atTop", root ());
@@ -73,7 +72,7 @@ ImageSearchApplication::setupTopSection (void)
}
void
-ImageSearchApplication::setupInputs (void)
+ImageSearchApplication::p_setupInputs (void)
{
Div *topContent = new Div ("topContent", "topContent", root ());
Div *descriptionDiv = new Div ("searchInputLine", topContent);
@@ -89,18 +88,18 @@ ImageSearchApplication::setupInputs (void)
Div *clearDiv = new Div ("clear", topContent);
m_fileUpload->uploaded().connect
- (SLOT (this, ImageSearchApplication::searchByUpload));
+ (SLOT (this, ImageSearchApplication::p_searchByUpload));
m_fileUpload->changed().connect
- (SLOT (this, ImageSearchApplication::enableSearchButton));
+ (SLOT (this, ImageSearchApplication::p_enableSearchButton));
m_fileUpload->fileTooLarge().connect
- (SLOT (this, ImageSearchApplication::fileTooLarge));
+ (SLOT (this, ImageSearchApplication::p_fileTooLarge));
m_searchButton->clicked().connect
- (SLOT (this, ImageSearchApplication::uploadFile));
+ (SLOT (this, ImageSearchApplication::p_uploadFile));
}
void
-ImageSearchApplication::setupSearchResults (void)
+ImageSearchApplication::p_setupSearchResults (void)
{
Div *resultSection = new Div ("resultSection", "resultSection", root ());
Div *resultTextDiv = new Div ("resultText", "resultText", resultSection);
@@ -119,7 +118,7 @@ ImageSearchApplication::setupSearchResults (void)
}
void
-ImageSearchApplication::updateSearchResults (void)
+ImageSearchApplication::p_updateSearchResults (void)
{
BlImageConstIterator resIt = m_backend->performSearch ();
int i = 0;
@@ -150,63 +149,63 @@ ImageSearchApplication::~ImageSearchApplication (void)
}
void
-ImageSearchApplication::uploadFile (void)
+ImageSearchApplication::p_uploadFile (void)
{
m_searchButton->disable ();
m_fileUpload->upload ();
}
void
-ImageSearchApplication::searchByUpload (void)
+ImageSearchApplication::p_searchByUpload (void)
{
std::string fileName
= m_backend->setImage (m_fileUpload->spoolFileName (),
m_fileUpload->clientFileName().toUTF8 ());
- afterSearch (fileName);
+ p_afterSearch (fileName);
}
void
-ImageSearchApplication::searchByImageId (const unsigned long imageId)
+ImageSearchApplication::p_searchByImageId (const unsigned long imageId)
{
std::string fileName = m_backend->setImage (imageId);
- afterSearch (fileName);
+ p_afterSearch (fileName);
}
void
-ImageSearchApplication::afterSearch (const std::string &fileName)
+ImageSearchApplication::p_afterSearch (const std::string &fileName)
{
if (m_backend->isCurrentImageValid ())
{
m_resultText->setStyleClass ("title");
m_resultText->setText ("Search Results:");
- showCurrentSearch (fileName);
+ p_showCurrentSearch (fileName);
}
else
{
m_resultText->setStyleClass ("error");
m_resultText->setText ("Invalid file.");
- hideCurrentSearch ();
+ p_hideCurrentSearch ();
}
- updateSearchResults ();
+ p_updateSearchResults ();
}
void
-ImageSearchApplication::fileTooLarge (void)
+ImageSearchApplication::p_fileTooLarge (void)
{
m_resultText->setStyleClass ("error");
m_resultText->setText ("Image file too large.");
- hideCurrentSearch ();
+ p_hideCurrentSearch ();
}
void
-ImageSearchApplication::enableSearchButton (void)
+ImageSearchApplication::p_enableSearchButton (void)
{
if (!m_searchButton->isEnabled ())
{
@@ -215,7 +214,7 @@ ImageSearchApplication::enableSearchButton (void)
}
void
-ImageSearchApplication::showCurrentSearch (const std::string &fileName)
+ImageSearchApplication::p_showCurrentSearch (const std::string &fileName)
{
std::string mimeType = m_backend->guessMimeType ();
std::string thumbName = ImageSearchBackend::thumbName (fileName);
@@ -227,7 +226,7 @@ ImageSearchApplication::showCurrentSearch (const std::string &fileName)
}
void
-ImageSearchApplication::hideCurrentSearch (void)
+ImageSearchApplication::p_hideCurrentSearch (void)
{
m_currentSelection->hide ();
}
View
24 webapp/ImageSearch.h
@@ -36,18 +36,18 @@ namespace ImageSearch
std::vector<SearchResult*> m_searchResults;
std::auto_ptr<Wt::WResource> m_currentSearchResource;
- void uploadFile (void);
- void afterSearch (const std::string &fileName);
- void searchByUpload (void);
- void searchByImageId (const unsigned long imageId);
- void fileTooLarge (void);
- void enableSearchButton (void);
- void showCurrentSearch (const std::string &fileName);
- void hideCurrentSearch (void);
- void setupTopSection (void);
- void setupInputs (void);
- void setupSearchResults (void);
- void updateSearchResults (void);
+ void p_uploadFile (void);
+ void p_afterSearch (const std::string &fileName);
+ void p_searchByUpload (void);
+ void p_searchByImageId (const unsigned long imageId);
+ void p_fileTooLarge (void);
+ void p_enableSearchButton (void);
+ void p_showCurrentSearch (const std::string &fileName);
+ void p_hideCurrentSearch (void);
+ void p_setupTopSection (void);
+ void p_setupInputs (void);
+ void p_setupSearchResults (void);
+ void p_updateSearchResults (void);
};
};

0 comments on commit c38b678

Please sign in to comment.
Something went wrong with that request. Please try again.