浏览代码

Merge branch 'no-qt3support' of dbv.inf-cv.uni-jena.de:nice/nice-core into clemens_noqt3_mb

Johannes Ruehle 11 年之前
父节点
当前提交
dc07fd25f8
共有 59 个文件被更改,包括 1513 次插入217 次删除
  1. 2 5
      CMakeLists.txt
  2. 38 0
      NOTES
  3. 7 2
      cmake/NiceModules.cmake
  4. 1 1
      core/CMakeLists.txt
  5. 28 0
      core/NOTES
  6. 1 1
      core/basics/numerictools.h
  7. 5 0
      core/basics/progs/testConfig.cpp
  8. 15 0
      core/ignore/OpaqueT.cpp
  9. 15 0
      core/ignore/OpaqueT.h
  10. 12 0
      core/ignore/OpaqueT.tcc
  11. 1 1
      core/image/BlockImageAccessT.tcc
  12. 8 0
      core/image/FilterT.h
  13. 40 0
      core/image/FilterT.tcc
  14. 1 1
      core/image/GHough.cpp
  15. 2 7
      core/image/GrayColorImageCommonImplementationT.h
  16. 10 0
      core/image/GrayColorImageCommonImplementationT.tcc
  17. 3 0
      core/image/ImageFile.cpp
  18. 1 1
      core/image/MultiChannelImage3DT.h
  19. 1 1
      core/image/MultiChannelImage3DT.tcc
  20. 6 0
      core/image/tests/TestImageFile.cpp
  21. 6 0
      core/image/tests/TestImageFile.h
  22. 1 1
      core/imagedisplay/ArrayPlot.cpp
  23. 4 5
      core/imagedisplay/CaptureDialog.cpp
  24. 43 109
      core/imagedisplay/CaptureWidget.cpp
  25. 7 12
      core/imagedisplay/CaptureWidget.h
  26. 3 3
      core/imagedisplay/DefaultMainWindow.cpp
  27. 18 28
      core/imagedisplay/ImageDisplay.cpp
  28. 2 3
      core/imagedisplay/ImageDisplay.h
  29. 8 10
      core/imagedisplay/ImageDisplayManagerWidget.cpp
  30. 5 9
      core/imagedisplay/ImageDisplayManagerWidget.h
  31. 12 4
      core/imagedisplay/QtFramework.cpp
  32. 6 6
      core/imagedisplay/SimpleSelector.cpp
  33. 3 3
      core/imagedisplay/SimpleSelector.h
  34. 6 1
      core/imagedisplay/progs/showImage.cpp
  35. 0 1
      core/matlabAccess/MatFileIO.h
  36. 31 0
      core/tutorial/TODO
  37. 59 0
      core/tutorial/doc/00_install.md
  38. 141 0
      core/tutorial/doc/01_imageio.md
  39. 153 0
      core/tutorial/doc/02_grayscale.md
  40. 126 0
      core/tutorial/doc/03_color.md
  41. 87 0
      core/tutorial/doc/04_filter.md
  42. 143 0
      core/tutorial/doc/05_vecmat.md
  43. 57 0
      core/tutorial/doc/06_algebra.md
  44. 38 0
      core/tutorial/doc/samples.md
  45. 45 0
      core/tutorial/progs/01_imageio.cpp
  46. 74 0
      core/tutorial/progs/02_grayscale.cpp
  47. 45 0
      core/tutorial/progs/03_color.cpp
  48. 53 0
      core/tutorial/progs/04_filter.cpp
  49. 125 0
      core/tutorial/progs/05_matio.cpp
  50. 二进制
      core/tutorial/samples/peppers_color.ppm
  51. 4 0
      core/tutorial/samples/peppers_gray.pgm
  52. 二进制
      core/tutorial/samples/simple.mat
  53. 二进制
      core/tutorial/screenshots/tut02_eq_hist_new.png
  54. 二进制
      core/tutorial/screenshots/tut02_eq_hist_org.png
  55. 二进制
      core/tutorial/screenshots/tut02_eq_new.png
  56. 二进制
      core/tutorial/screenshots/tut02_eq_org.png
  57. 6 2
      core/vector/VectorT.tcc
  58. 1 0
      core/vector/ippwrapper.tcc
  59. 4 0
      core/vector/progs/testCholeskySpeed.cpp

+ 2 - 5
CMakeLists.txt

@@ -1,5 +1,5 @@
 #cmake_minimum_required(VERSION 2.8.6) #version 2.8.6 at least required because of command set(CMAKE_AUTOMOC TRUE) for qt moc-ing (see below)
-cmake_minimum_required(VERSION 2.8.12) #version 2.8.12 at least required because of command  get_filename_component(__testname_dir ${__testname_abspath} DIRECTORY) (getting directory path of filename)
+cmake_minimum_required(VERSION 2.8.6)
 project (NICELibrary)
 
 include(CheckSymbolExists)
@@ -29,8 +29,6 @@ endif()
 
 set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR})
 
-set(NICE_BUILD_LIBS_STATIC_SHARED STATIC)
-
 set(NICE_SOURCEFILES_FIND_GLOBALLYRECURSIVE ON CACHE STRING "Scan a sublibraries directory for source files instead of using an explicit src file list")
 
 NICE_OPTION(WITH_BOOST "Build with Boost support" OFF)
@@ -132,10 +130,9 @@ endif()
 
 NICE_OPTION(WITH_QT "Build with Qt" ON)
 if(WITH_QT)
-  FIND_PACKAGE(Qt4)# COMPONENTS Qt3Support QtOpenGl)
+  FIND_PACKAGE(Qt4 REQUIRED)# COMPONENTS Qt3Support QtOpenGl)
   SET(QT_USE_QTOPENGL TRUE)
   SET(QT_USE_QTXML TRUE)
-  SET(QT_USE_QT3SUPPORT TRUE)
   if(QT_FOUND)
     message(STATUS "QTfound ${QT_QT3SUPPORT_INCLUDE_DIR}")
     set(CMAKE_AUTOMOC TRUE) #see doc: http://blogs.kde.org/2011/11/01/cool-new-stuff-cmake-286-automoc

+ 38 - 0
NOTES

@@ -0,0 +1,38 @@
+## Wichtigere Sachen
+*Für die generischen Klassen müssen wir uns etwas überlegen*. Die Implementationen müssen mit in die Header, aber wir können die Lib so "von außen" nicht benutzen, weil wir beim Kompilieren der Templates definitiv unser Buildsystem brauchen (die ganzen Makros, Libs...). Das macht eine Distribution von Binaries quasi unmöglich.
+
+```
+$ grep --include={*.h,*.tcc} -rnw ./ -e ".*def.*USELIB.*" | wc -l
+185
+
+```
+
+Daher mein Vorschlag:
+
+1. Wir schränken für jede betroffene Klasse die möglichen Instanzen ein und kompilieren alle davon explizit mit. Ein Beispiel habe ich in den Ordner "ignore" gepackt.
+Vorteile:
+	* Benutzer braucht nur noch die Header einzubinden und mit nice_core zu linken -> er muss nice_core nicht kompilieren, sondern kann einfach Binaries und Header installieren.
+	* Je nach Lizenzen können wir einige Libraries statisch reinlinken, dabei fallen die nicht benutzten Funktionen raus und die Benutzer muss nicht einmal die sos der Abhängigkeiten installieren.
+	* Wenn wir in der Implementierung eine weitere Abhängigkeit einbauen, machen wir dem Benutzer seinen Buildprozess nicht kaputt.
+Nachteile:
+	* Für Containertypen eher unbrauchbar.
+	* Speicher?
+
+## Buildsystem
+-- WITH_QT OFF verhindert nicht das Kompilieren von libimagedisplay, die hängt aber von Qt ab.
+?? NICE_USELIB_QT verwenden, um in ImageDisplay.h die QT-Header auszuschließen
+
+-- Das Verzeichnis von GLUT ist für Windows hardcoded, sollte eigentlich Umgebungsvariable nutzen. 
+?? Rausnehmen
+
+-- WITH... sind Voreinstellungen in CMakeLists
+?? In Abhängigkeit der gefundenen Libs setzen
+
+-- Die Abhängigkeiten werden in nice-core/CMakeLists.txt gesucht, aber in nice-core/core/CMakeLists.txt werden unabhängig davon die Ergebnisse der find_package()-Aufrufe benutzt.
+?? Wenn nice-core ohnehin nur aus "core" besteht, reicht vielleicht auch nur eine CMakeLists.txt. Dann können wir target_link_libraries aufrufen, nachdem wir eine Abhängigkeit gefunden haben. Alternativ: Wenn jedes Projekt seine eigenen Abhängigkeiten hat, dann kann auch jedes Projekt selbst danach suchen.
+
+## Aufräumen
+-- "Filter.h is obsolete" - hängt noch sehr viel davon ab?
+
+## Bugs
+-- Konstruktor von ImageT ruft string::substr mit falschen Parametern auf, wenn der Punkt im Dateinamen fehlt.

+ 7 - 2
cmake/NiceModules.cmake

@@ -121,13 +121,18 @@ macro(nice_get_source_files)
 endmacro()
 
 macro(nice_build_library)
-  ADD_LIBRARY("nice_${the_library}" ${NICE_BUILD_LIBS_STATIC_SHARED} ${nice_${the_library}_HDR} ${nice_${the_library}_SRC})
+  ADD_LIBRARY("nice_${the_library}" ${nice_${the_library}_HDR} ${nice_${the_library}_SRC})
   TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES})
   #TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES} ${Boost_LIBRARIES} ${OPENGL_LIBRARY} ${GLUT_LIBRARY} ${QT_LIBRARIES})
   SET_PROPERTY(TARGET "nice_${the_library}" PROPERTY FOLDER "library")
   INSTALL(TARGETS "nice_${the_library}" DESTINATION lib EXPORT "nice_${the_library}-exports")
   INSTALL(EXPORT "nice_${the_library}-exports" DESTINATION lib/exports)
 
+  install(DIRECTORY ./ DESTINATION "include/${the_library}"
+          FILES_MATCHING 
+          PATTERN "*.h"
+          PATTERN "*.tcc")
+
   configure_file( ../cmake/niceConfig.cmake.in "${PROJECT_BINARY_DIR}/lib/nice_${the_library}Config.cmake" )
 endmacro()
 
@@ -188,7 +193,7 @@ macro(nice_add_unittests)
     foreach(__testcpp ${nice_${the_library}_TESTFILES_SRC})
       get_filename_component(__testname ${__testcpp} NAME_WE )
       nice_get_real_path(__testname_abspath ${__testcpp})
-      get_filename_component(__testname_dir ${__testname_abspath} DIRECTORY)
+      get_filename_component(__testname_dir ${__testname_abspath} PATH)
 
       message(STATUS "unittest: ${__testname} ${__testcpp}")
       

+ 1 - 1
core/CMakeLists.txt

@@ -64,4 +64,4 @@ nice_add_unittests()
 #         install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT main)
 #       endif()
 #     endforeach()
-#   endif()
+#   endif()

+ 28 - 0
core/NOTES

@@ -0,0 +1,28 @@
+## Wichtigere Sachen
+*Für die generischen Klassen müssen wir uns etwas überlegen*. Die Implementationen müssen mit in die Header, aber wir können die Lib so "von außen" nicht benutzen, weil wir beim Kompilieren der Templates die NICE_USELIB.. aus unserem Buildsystem brauchen und damit auch noch beim Benutzer Abhängigkeiten erzeugen, die vermeidbar wären.
+
+```
+$ grep --include={*.h,*.tcc} -rnw ./ -e ".*def.*USELIB.*" | wc -l
+185
+
+```
+In den meisten Fällen können wir wohl die Template-Funktion explizit instantiieren und in den Header nur noch "extern template..." angeben.
+
+## Buildsystem
+-- WITH_QT OFF verhindert nicht das Kompilieren von libimagedisplay, die hängt aber von Qt ab.
+?? NICE_USELIB_QT verwenden, um in ImageDisplay.h die QT-Header auszuschließen
+
+-- Das Verzeichnis von GLUT ist für Windows hardcoded, sollte eigentlich Umgebungsvariable nutzen. 
+?? Rausnehmen
+
+-- WITH... sind Voreinstellungen in CMakeLists
+?? In Abhängigkeit der gefundenen Libs setzen
+
+-- Die Abhängigkeiten werden in nice-core/CMakeLists.txt gesucht, aber in nice-core/core/CMakeLists.txt werden unabhängig davon die Ergebnisse der find_package()-Aufrufe benutzt.
+?? Wenn nice-core ohnehin nur aus "core" besteht, reicht vielleicht auch nur eine CMakeLists.txt. Dann können wir target_link_libraries aufrufen, nachdem wir eine Abhängigkeit gefunden haben. Alternativ: Wenn jedes Projekt seine eigenen Abhängigkeiten hat, dann kann auch jedes Projekt selbst danach suchen.
+
+## Aufräumen
+-- "Filter.h is obsolete" - hängt noch sehr viel davon ab?
+
+## Bugs
+-- Konstruktor von ImageT ruft string::substr mit falschen Parametern auf, wenn der Punkt im Dateinamen fehlt.

+ 1 - 1
core/basics/numerictools.h

@@ -446,7 +446,7 @@ std::string intToString(const int i);
  * @param length - resulting length of string including leading zeros
  * @return string
  */
-std::string intToString(const int i, const uint & length);
+std::string intToString(const int i, const unsigned int & length);
 
 /**
  * Convert a double into a string.

+ 5 - 0
core/basics/progs/testConfig.cpp

@@ -16,8 +16,13 @@ using namespace std;
 */
 int main (int argc, char **argv)
 {   
+
 #ifndef WIN32
+#ifndef __clang__
+#ifndef __llvm__ 
     std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 
     Config conf ( argc, argv );

+ 15 - 0
core/ignore/OpaqueT.cpp

@@ -0,0 +1,15 @@
+/*
+   Example files for explicit opaque templates
+*/
+
+#include <iostream>
+#include <string>
+
+#include "OpaqueT.h"
+#include "OpaqueT.tcc"
+
+namespace NICE {
+		// Explicit instances
+		template class OpaqueT<std::string>;
+		template class OpaqueT<int>;
+}

+ 15 - 0
core/ignore/OpaqueT.h

@@ -0,0 +1,15 @@
+/*
+   Example files for explicit opaque templates
+*/
+
+#ifndef IGNORE_OPAQUET_H_
+#define IGNORE_OPAQUET_H_
+
+namespace NICE {
+	template <class T> class OpaqueT {
+		public:
+			void CallMe(T arg);
+	};
+}
+
+#endif

+ 12 - 0
core/ignore/OpaqueT.tcc

@@ -0,0 +1,12 @@
+/*
+   Example files for explicit opaque templates
+*/
+
+#include "OpaqueT.h"
+
+namespace NICE {
+	// Implementations
+	template<class T>void OpaqueT<T>::CallMe(T arg) {
+		std::cout << arg;
+	}
+}

+ 1 - 1
core/image/BlockImageAccessT.tcc

@@ -32,7 +32,7 @@ void BlockImageAccessT<P>::set(const P& value) {
   for(int y=0; y<this->height(); ++y) {
     const P* end = this->getPixelPointerYEnd(y);
     const int inc = this->columnStepsize();
-    for (P* p = this->getPixelPointerY(y); p != end; p = (void*)p + inc) {
+    for (P* p = this->getPixelPointerY(y); p != end; p = p + inc) {
       *p = value;
     }
   }

+ 8 - 0
core/image/FilterT.h

@@ -68,6 +68,14 @@ class FilterT
     */
     static void filterY ( const ImageT<SrcType>& src, const VectorT<CalcType>& kernel, ImageT<DstType> &result, const int& anchor = -1 );
 
+    /**
+    * Filters (=convolves) Image \c src into the
+    * Image \c dst using filter (=convolution) kernel \c kernel.
+    * @copydoc filter()
+    */
+    static void filter ( const ImageT<SrcType>& src, const MatrixT<CalcType>& kernel, ImageT<DstType>& result,
+            const int& anchorx = -1, const int& anchory = -1 );
+
     /**
     * Compute horizontal part of the gradient of a Image \c src via Sobel into Image \c dst.
     * The resulting image \c dst is of the same size as \c src.

+ 40 - 0
core/image/FilterT.tcc

@@ -72,6 +72,46 @@ void FilterT<SrcType, CalcType, DstType>::filterY ( const ImageT<SrcType>& src,
   }
 }
 
+template<class SrcType, class CalcType, class DstType>
+void FilterT<SrcType, CalcType, DstType>::filter(const ImageT<SrcType>& src,
+		const MatrixT<CalcType>& kernel, ImageT<DstType>& result,
+		const int& anchorx, const int& anchory) {
+
+	if (result.width() != src.width() || result.height() != src.height()) {
+		result.resize(src.width(), src.height());
+	}
+
+	IppiPoint anchor;
+	anchor.x = (anchorx < 0) ? (kernel.cols() / 2) : anchorx;
+	anchor.y = (anchory < 0) ? (kernel.rows() / 2) : anchory;
+
+	unsigned int kernel_rows = kernel.rows() - 1;
+	unsigned int kernel_cols = kernel.cols() - 1;
+
+	int runs = 0;
+
+	for (unsigned int y = anchor.y; y < src.height() - (kernel_rows - anchor.y);
+			y++) {
+		for (unsigned int x = anchor.x; x < src.width() - (kernel_cols - anchor.x);
+				x++) {
+			CalcType sum = 0;
+
+			for (int j = -anchor.y; j <= ((int)kernel_rows - anchor.y); j++) {
+				for (int i = -anchor.x; i <= ((int)kernel_cols - anchor.x); i++) {
+					sum += static_cast<CalcType>(src(x + i, y + j))
+							* kernel(kernel_cols - (anchor.x + i),
+									kernel_rows - (anchor.y + j));
+				}
+			}
+
+			result(x, y) = static_cast<DstType>(sum);
+
+		}
+	}
+
+	return;
+}
+
 template<class SrcType, class CalcType, class DstType>
 void FilterT<SrcType, CalcType, DstType>::sobelX ( const NICE::ImageT<SrcType> &src, NICE::ImageT<DstType> &dst)
 {

+ 1 - 1
core/image/GHough.cpp

@@ -52,7 +52,7 @@ GHough& GHough::operator=(const GHough& ex)
 void GHough::initialize(IppiSize imageSize,IppiSize transformSize, NeighborType addMode)
 {
     this->imageSize = imageSize;
-    transformSize = transformSize;
+    this->transformSize = transformSize;
     this->addMode = addMode;
     
     //! Allocates memory for data

+ 2 - 7
core/image/GrayColorImageCommonImplementationT.h

@@ -178,10 +178,7 @@ public:
    * @note   If you want to explicitly select a file format,
    *         use read(ImageFile, const GrayColorImageCommonImplementation::MemoryLayout)
    */
-  inline void read(const std::string &filename /*,
-                   const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout = ippAlignment*/) {
-    read(ImageFile(filename)/*, _memoryLayout*/);
-  }
+  void read(const std::string &filename); 
 
   /**
   * Write this image to a file. See also documentation of \c ImageFile.
@@ -196,9 +193,7 @@ public:
    * @note If you want to explicitly select a file format,
    *       use write(ImageFile)
    */
-  inline void write(const std::string &filename) const {
-    write(ImageFile(filename));
-  }
+  inline void write(const std::string &filename) const; 
 
   /**
   * Read this image from a PPM or PGM file.

+ 10 - 0
core/image/GrayColorImageCommonImplementationT.tcc

@@ -195,4 +195,14 @@ void GrayColorImageCommonImplementationT<P>::writePXM(const char* pxmFileName) c
   }
 }
 
+template <class P>
+void GrayColorImageCommonImplementationT<P>::read(const std::string &filename) {
+    read(ImageFile(filename)/*, _memoryLayout*/);
+}
+
+template <class P>
+void GrayColorImageCommonImplementationT<P>::write(const std::string &filename) const {
+    write(ImageFile(filename));
+}
+
 } // namespace

+ 3 - 0
core/image/ImageFile.cpp

@@ -240,6 +240,9 @@ ImageFile::Format ImageFile::name2Format(const std::string &filename)
 	#endif
 
 		int pos=filename.find_last_of('.');
+		if(pos==std::string::npos)
+			return ImageFile::FormatUnknown;
+
 		magic=filename.substr(pos);
 		if(magic==".pgm" || magic==".PGM")
 				return ImageFile::PGM_RAW;

+ 1 - 1
core/image/MultiChannelImage3DT.h

@@ -127,7 +127,7 @@ public:
    * @param channel channel
    * @return P mean value of given volume
    **/
-  P getIntegralValue(int ulfx, int ulfy, int ulfz, int lrbx, int lrby, int lrbz, int channel);
+  P getIntegralValue(int ulfx, int ulfy, int ulfz, int lrbx, int lrby, int lrbz, int channel) const;
 
   /** convert to ice image */
   void convertToGrey( NICE::Image & img, int z, uint channel = 0, bool normalize = true ) const;

+ 1 - 1
core/image/MultiChannelImage3DT.tcc

@@ -680,7 +680,7 @@ void MultiChannelImage3DT<P>::calcVariance( uint srcchan, uint tarchan )
 }
 
 template<class P>
-P MultiChannelImage3DT<P>::getIntegralValue(int ulfx, int ulfy, int ulfz, int lrbx, int lrby, int lrbz, int channel)
+P MultiChannelImage3DT<P>::getIntegralValue(int ulfx, int ulfy, int ulfz, int lrbx, int lrby, int lrbz, int channel) const
 {
   ulfx = std::max(ulfx-1, -1);
   ulfx = std::min(ulfx, xsize-1);

+ 6 - 0
core/image/tests/TestImageFile.cpp

@@ -295,6 +295,12 @@ void TestImageFile::testJPG_IO()
     }
 }
 
+void TestImageFile::testInvalidFileName() {
+	ImageFile image_file;
+	ImageFile::Format fileformat = image_file.name2Format("nodothere");
+	CPPUNIT_ASSERT_EQUAL(fileformat,ImageFile::FormatUnknown);
+}
+
 #endif
 
 

+ 6 - 0
core/image/tests/TestImageFile.h

@@ -21,6 +21,7 @@ class TestImageFile : public CppUnit::TestFixture
 	CPPUNIT_TEST( testColorImage );
 	CPPUNIT_TEST( testGrayImage  );
 	CPPUNIT_TEST( testJPG_IO     );
+	CPPUNIT_TEST( testInvalidFileName );
 	CPPUNIT_TEST_SUITE_END();
 
    private:
@@ -51,6 +52,11 @@ class TestImageFile : public CppUnit::TestFixture
 	* Test JPEG Input and Output
 	*/
   	void testJPG_IO();
+
+  	/**
+  	* Test for correct detection of file names without appropriate endings
+  	*/
+  	void testInvalidFileName();
 };
 
 #endif // _TESTIMAGEFILE_IMAGE_H

+ 1 - 1
core/imagedisplay/ArrayPlot.cpp

@@ -28,7 +28,7 @@ ArrayPlot::ArrayPlot ( std::vector<double> probs,
                        QWidget* parent,
                        const char* name ,
                        Qt::WFlags flags )
-    : QGLWidget ( parent, name, NULL, flags ),
+    : QGLWidget ( parent, NULL, flags ),
     m_width ( width ),
     m_height ( height ),
     m_maxProb ( -std::numeric_limits<double>::infinity() ),

+ 4 - 5
core/imagedisplay/CaptureDialog.cpp

@@ -1,19 +1,18 @@
 #include "CaptureDialog.h"
 
 #include <qlayout.h>
-//Added by qt3to4:
-#include <Q3VBoxLayout>
+#include <QVBoxLayout>
 
 namespace NICE {
 
 CaptureDialog::CaptureDialog(QWidget* parent, const char* name, 
                              bool modal, Qt::WFlags fl)
-    : QDialog( parent, name, modal, fl ) {
+    : QDialog( parent, fl ) {
   if (name == NULL) {
-    setName("CaptureDialog");
+    setWindowTitle("CaptureDialog");
   }
   
-  Q3VBoxLayout* layout = new Q3VBoxLayout( this, 11, 6, "layout"); 
+  QVBoxLayout* layout = new QVBoxLayout( this ); 
   
   m_capture = new CaptureWidget(this);
   m_capture->showCancelButton();

+ 43 - 109
core/imagedisplay/CaptureWidget.cpp

@@ -2,115 +2,63 @@
 
 #include <qvariant.h>
 #include <qpushbutton.h>
-#include <q3buttongroup.h>
 #include <qradiobutton.h>
 #include <qcheckbox.h>
 #include <qlabel.h>
 #include <qlineedit.h>
 #include <qlayout.h>
 #include <qtooltip.h>
-#include <q3whatsthis.h>
 #include <qcombobox.h>
-//Added by qt3to4:
-#include <Q3HBoxLayout>
-#include <Q3VBoxLayout>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QFileDialog>
 
 namespace NICE {
 
 CaptureWidget::CaptureWidget(QWidget* parent, const char* name, Qt::WFlags fl)
-        : QWidget(parent, name, fl) {
-    if (name == NULL) {
-      setName("CaptureWidget");
-    }
-    //setSizeGripEnabled( TRUE );
-    CaptureWidgetLayout = new Q3VBoxLayout( this, 11, 6, "CaptureWidgetLayout");
+        : QWidget(parent, fl) {
+    CaptureWidgetLayout = new QVBoxLayout( this );
 
-    layout15 = new Q3HBoxLayout( 0, 0, 6, "layout15");
+    layout15 = new QHBoxLayout( );
 
-    textLabel1 = new QLabel( this, "textLabel1" );
+    textLabel1 = new QLabel( this );
     layout15->addWidget( textLabel1 );
 
-    editFormat = new QComboBox( true, this, "editFormat" );
-    editFormat->insertItem("ppm");
-    editFormat->insertItem("pgm");
-    editFormat->insertItem("png");
-    editFormat->insertItem("jpg");
-    QToolTip::add(editFormat,
-                  "Format specified by filename extension (without dot)");
+    editFormat = new QComboBox( this );
+    editFormat->addItem("ppm");
+    editFormat->addItem("pgm");
+    editFormat->addItem("png");
+    editFormat->addItem("jpg");
+    editFormat->setToolTip("Format specified by filename extension (without dot)");
     layout15->addWidget( editFormat );
 
-    checkBuffered = new QCheckBox( this, "checkBuffered" );
-    QToolTip::add(checkBuffered,
-                  "Buffer images in memory and write after capturing (stop)");
+    checkBuffered = new QCheckBox( this );
+    checkBuffered->setToolTip( "Buffer images in memory and write after capturing (stop)");
     layout15->addWidget( checkBuffered );
 
-    buttonStart = new QPushButton( this, "buttonStart" );
+    buttonStart = new QPushButton( this );
     layout15->addWidget( buttonStart );
 
-    buttonStop = new QPushButton( this, "buttonStop" );
+    buttonStop = new QPushButton( this );
     buttonStop->setEnabled( FALSE );
     layout15->addWidget( buttonStop );
 
-    buttonCancel = new QPushButton( this, "buttonCancel" );
+    buttonCancel = new QPushButton( this );
     buttonCancel->setAutoDefault( TRUE );
     buttonCancel->hide();
     layout15->addWidget( buttonCancel );
-    //spacer5 = new QSpacerItem( 20, 44, QSizePolicy::Minimum, QSizePolicy::Expanding );
-    //layout15->addItem( spacer5 );
-
-
-
-//     layout15 = new QHBoxLayout( 0, 0, 6, "layout15");
-//
-//     boxFormat = new QButtonGroup( this, "boxFormat" );
-//     //boxFormat->setInsideMargin(0);
-//     //boxFormat->setInsideSpacing(2);
-//
-//     radioPPM = new QRadioButton( boxFormat, "radioPPM" );
-//     radioPPM->setGeometry( QRect( 11, 26, 267, 25 ) );
-//     radioPPM->setChecked( TRUE );
-//
-//     radioJPG = new QRadioButton( boxFormat, "radioJPG" );
-//     radioJPG->setGeometry( QRect( 11, 119, 267, 25 ) );
-//
-//     radioPGM = new QRadioButton( boxFormat, "radioPGM" );
-//     radioPGM->setGeometry( QRect( 11, 57, 267, 25 ) );
-//
-//     radioPNG = new QRadioButton( boxFormat, "radioPNG" );
-//     radioPNG->setGeometry( QRect( 11, 88, 267, 25 ) );
-//     layout15->addWidget( boxFormat );
-//
-//     layout14 = new QVBoxLayout( 0, 0, 6, "layout14");
-//
-//     buttonStart = new QPushButton( this, "buttonStart" );
-//     layout14->addWidget( buttonStart );
-//
-//     buttonStop = new QPushButton( this, "buttonStop" );
-//     buttonStop->setEnabled( FALSE );
-//     layout14->addWidget( buttonStop );
-//
-//     buttonCancel = new QPushButton( this, "buttonCancel" );
-//     buttonCancel->setAutoDefault( TRUE );
-//     buttonCancel->hide();
-//     layout14->addWidget( buttonCancel );
-//     spacer5 = new QSpacerItem( 20, 44, QSizePolicy::Minimum, QSizePolicy::Expanding );
-//     layout14->addItem( spacer5 );
-//
-//     checkBuffered = new QCheckBox( this, "checkBuffered" );
-//     layout14->addWidget( checkBuffered );
-//     layout15->addLayout( layout14 );
-
+    
     CaptureWidgetLayout->addLayout( layout15 );
 
-    layout11 = new Q3HBoxLayout( 0, 0, 6, "layout11");
+    layout11 = new QHBoxLayout();
 
-    textLabel2 = new QLabel( this, "textLabel2" );
+    textLabel2 = new QLabel( this );
     layout11->addWidget( textLabel2 );
 
-    editDirectory = new QLineEdit( this, "editDirectory" );
+    editDirectory = new QLineEdit( this );
     layout11->addWidget( editDirectory );
 
-    buttonBrowse = new QPushButton( this, "buttonBrowse" );
+    buttonBrowse = new QPushButton( this );
     layout11->addWidget( buttonBrowse );
     CaptureWidgetLayout->addLayout( layout11 );
 
@@ -124,11 +72,7 @@ CaptureWidget::CaptureWidget(QWidget* parent, const char* name, Qt::WFlags fl)
 
     languageChange();
     resize( QSize(542, 253).expandedTo(minimumSizeHint()) );
-//     clearWState( WState_Polished ); // Qt4
 
-    // signals and slots connections
-//     connect(buttonCancel, SIGNAL(clicked()),
-//             this, SLOT(buttonCancelClicked()));
     connect(buttonCancel, SIGNAL(clicked()),
             this, SIGNAL(cancelled()));
     connect(buttonBrowse, SIGNAL(clicked()),
@@ -157,35 +101,31 @@ CaptureWidget::~CaptureWidget()
  */
 void CaptureWidget::languageChange()
 {
-    setCaption( tr( "Capture Image Sequence" ) );
-//     boxFormat->setTitle( tr( "Image file format" ) );
-//     radioPPM->setText( tr( "PPM" ) );
-//     radioJPG->setText( tr( "JPEG" ) );
-//     radioPGM->setText( tr( "PGM (gray)" ) );
-//     radioPNG->setText( tr( "PNG" ) );
+    setWindowTitle( tr( "Capture Image Sequence" ) );
     buttonStart->setText( tr( "Start" ) );
     buttonStop->setText( tr( "Stop" ) );
     buttonCancel->setText( tr( "&Cancel" ) );
-    buttonCancel->setAccel( QKeySequence( QString::null ) );
+    buttonCancel->setShortcut( QKeySequence( QString::null ) );
     checkBuffered->setText( tr( "Buffer" ) );
     textLabel1->setText( tr( "Format" ) );
     textLabel2->setText( tr( "Directory" ) );
     buttonBrowse->setText( tr( "..." ) );
 }
 
-#include <q3filedialog.h>
-
 void CaptureWidget::buttonBrowseClicked()
 {
-  Q3FileDialog dialog("",
-                     "",
-                     this,
-                     "Save to directory dialog");
-  dialog.setCaption("Choose an output directory");
-  dialog.setMode(Q3FileDialog::AnyFile); // QFileDialog::DirectoryOnly
+/*
+  QFileDialog dialog( this );
+  dialog.setWindowTitle("Choose an output directory");
+  dialog.setMode(QFileDialog::AnyFile); 
   if (dialog.exec() == QDialog::Accepted) {
     editDirectory->setText(dialog.selectedFile());
   }
+*/
+  QString directory = QFileDialog::getExistingDirectory(this);
+  if(!directory.isNull()) {
+    editDirectory->setText(directory);
+  }
 }
 
 void CaptureWidget::buttonStartClicked()
@@ -215,13 +155,12 @@ void CaptureWidget::enableGUI(bool enable)
   editDirectory->setEnabled(value);
   buttonBrowse->setEnabled(value);
   checkBuffered->setEnabled(value);
-//   boxFormat->setEnabled(value);
   buttonStop->setEnabled(!value);
 }
 
 std::string CaptureWidget::directoryName()
 {
-  return std::string(editDirectory->text().local8Bit());
+  return std::string(editDirectory->text().toLocal8Bit());
 }
 
 bool CaptureWidget::isBuffered() {
@@ -231,18 +170,7 @@ bool CaptureWidget::isBuffered() {
 
 std::string CaptureWidget::extensionName()
 {
-//   if (radioPPM->isChecked()) {
-//     return ".ppm";
-//   } else if (radioPGM->isChecked()) {
-//     return ".pgm";
-//   } else if (radioPNG->isChecked()) {
-//     return ".png";
-//   } else if (radioJPG->isChecked()) {
-//     return ".jpg";
-//   } else {
-//     return ".ppm";
-//   }
-  return "." + std::string(editFormat->currentText().local8Bit());
+  return "." + std::string(editFormat->currentText().toLocal8Bit());
 }
 
 bool CaptureWidget::isCapturing() {
@@ -254,7 +182,13 @@ void CaptureWidget::setDirectoryName(const std::string& dir) {
 }
 
 void CaptureWidget::setExtensionName(const std::string& ext) {
-  editFormat->setCurrentText(ext.c_str());
+  std::string extension_end = ext.substr(1);
+  int extension_index = editFormat->findText(extension_end.c_str());
+  if(extension_index > 0) {
+    editFormat->addItem(extension_end.c_str());
+  } 
+
+  editFormat->setCurrentIndex(extension_index);
 }
 
 void CaptureWidget::setBuffered(bool buffer) {

+ 7 - 12
core/imagedisplay/CaptureWidget.h

@@ -3,19 +3,14 @@
 
 #include <qvariant.h>
 #include <qdialog.h>
-#include <q3filedialog.h>
-//Added by qt3to4:
-#include <Q3VBoxLayout>
-#include <Q3GridLayout>
-#include <Q3HBoxLayout>
+#include <QFileDialog>
 #include <QLabel>
 #include <memory>
 
-class Q3VBoxLayout;
-class Q3HBoxLayout;
-class Q3GridLayout;
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
 class QSpacerItem;
-class Q3ButtonGroup;
 class QRadioButton;
 class QPushButton;
 class QCheckBox;
@@ -53,11 +48,11 @@ public slots:
   virtual void buttonStopClicked();
 
 protected:
-  Q3VBoxLayout* CaptureWidgetLayout;
-  Q3HBoxLayout* layout15;
+  QVBoxLayout* CaptureWidgetLayout;
+  QHBoxLayout* layout15;
 //   QVBoxLayout* layout14;
   QSpacerItem* spacer5;
-  Q3HBoxLayout* layout11;
+  QHBoxLayout* layout11;
 
 //   QButtonGroup* boxFormat;
 //   QRadioButton* radioPPM;

+ 3 - 3
core/imagedisplay/DefaultMainWindow.cpp

@@ -13,14 +13,14 @@
 namespace NICE {
 
 DefaultMainWindow::DefaultMainWindow(const char* title) : QWidget(NULL, NULL) {
-  setCaption(title);
+  setWindowTitle(title);
 
   // create a timer waking us regularly
   timer.reset(new QTimer(this));
   timer->connect(timer.get(), SIGNAL(timeout()),
                  this, SLOT(timerSlot()));
   timerIntervalMS = 0;
-  timer->start(timerIntervalMS, false);
+  timer->start(timerIntervalMS);
 
   //ImageDisplayManagerWidget* manager =
       //new ImageDisplayManagerWidget(this, "image manager");
@@ -43,7 +43,7 @@ void DefaultMainWindow::timerSlot() {
     timer->stop();
   } else if (nextSleepMS != timerIntervalMS) {
     timerIntervalMS = nextSleepMS;
-    timer->start(timerIntervalMS, false);
+    timer->start(timerIntervalMS);
   }
 }
 

+ 18 - 28
core/imagedisplay/ImageDisplay.cpp

@@ -10,15 +10,14 @@
 #include <GL/glut.h>
 #endif
 #include <qcursor.h>
-#include <q3filedialog.h>
+#include <QFileDialog>
 #include <qapplication.h>
 #include <qpushbutton.h>
 #include <qlineedit.h>
-#include <q3buttongroup.h>
 #include <qcheckbox.h>
-//Added by qt3to4:
 #include <QContextMenuEvent>
 #include <QMouseEvent>
+#include <QMenu>
 
 #include <core/basics/Exception.h>
 #include <core/basics/FileName.h>
@@ -33,7 +32,7 @@
 namespace NICE {
 
 ImageDisplay::ImageDisplay ( QWidget* parent, const char* name, Qt::WFlags flags )
-    : QGLWidget ( parent, name, NULL, flags ),
+    : QGLWidget ( parent, NULL, flags ),
     image ( NULL ),
     colorImageBuffer ( NULL ),
     grayImageBuffer ( NULL ),
@@ -386,30 +385,23 @@ void ImageDisplay::makeDrop ( int x, int y ) {
 
 void ImageDisplay::contextMenuEvent ( QContextMenuEvent* event ) {
 
-  Q3PopupMenu* popupMenu = new Q3PopupMenu ( this );
+  QMenu* popupMenu = new QMenu ( this );
 
-  //   CHECK_PTR(popupMenu); // Qt4
-  //popupMenu->insertTearOffHandle();
   addExtraMenuItems ( popupMenu );
 
-  int saveID = popupMenu->insertItem ( "&Save image", this, SLOT ( menuSave() ) );
-  popupMenu->setAccel ( Qt::CTRL + Qt::Key_S, saveID );
+  popupMenu->addAction("&Save Image", this, SLOT ( menuSave() ), Qt::CTRL + Qt::Key_S);
+  popupMenu->addAction("&Restore aspect ratio", this, SLOT ( menuAspectRatio ), Qt::CTRL + Qt::Key_A);
 
-  int aspectID = popupMenu->insertItem ( "&Restore aspect ratio",
-                                         this, SLOT ( menuAspectRatio() ) );
-  popupMenu->setAccel ( Qt::CTRL + Qt::Key_A, aspectID );
-
-  popupMenu->insertSeparator();
-  popupMenu->insertItem ( "Start &capturing image sequence",
-                          this, SLOT ( menuStartCapture() ) );
-  popupMenu->insertItem ( "Sto&p capturing", this, SLOT ( menuStopCapture() ) );
+  popupMenu->addSeparator();
 
+  popupMenu->addAction ( "Start &capturing image sequence", this, SLOT ( menuStartCapture() ) );
+  popupMenu->addAction ( "Sto&p capturing", this, SLOT ( menuStopCapture() ) );
 
   popupMenu->exec ( QCursor::pos() );
   delete popupMenu;
 }
 
-void ImageDisplay::addExtraMenuItems ( Q3PopupMenu *popupMenu )
+void ImageDisplay::addExtraMenuItems ( QMenu *popupMenu )
 {
 }
 
@@ -420,17 +412,15 @@ void ImageDisplay::menuAspectRatio() {
 }
 
 void ImageDisplay::menuSave() {
-  QString s = Q3FileDialog::getSaveFileName (
-                "",
-                "Images (*.ppm *.pgm *.png *.jpg)",
-                this,
-                "Save file dialog",
-                "Choose a filename" );
-  if ( s.local8Bit().size() == 0 ) {
+  QString s = QFileDialog::getSaveFileName(this,
+		"Save file dialog",
+		"",
+		"Images (*.ppm, *.pgm, *.png, *.jpg)");
+  if ( s.isNull() ) {
     return;
   }
 
-  NICE::FileName filename ( s.local8Bit() );
+  NICE::FileName filename ( s.toLocal8Bit() );
   const std::string ext = filename.extractExtension().str();
   const bool extensionOk
   = ( ext == std::string ( ".ppm" ) || ext == std::string ( ".pgm" )
@@ -448,7 +438,7 @@ void ImageDisplay::menuSave() {
 void ImageDisplay::menuStartCapture() {
   if ( dialog.get() == NULL ) {
     dialog.reset ( new CaptureDialog ( this, "Capture Dialog" ) );
-    dialog->setCaption ( "Capture: " + captionBuffer );
+    dialog->setWindowTitle ( "Capture: " + captionBuffer );
     connect ( ( QObject* ) dialog->capture(), SIGNAL ( started() ),
               this, SLOT ( dialogStartCapture() ) );
     connect ( ( QObject* ) dialog->capture(), SIGNAL ( stopped() ),
@@ -485,7 +475,7 @@ void ImageDisplay::doSetCaption() {
   s << std::fixed << captionBuffer.toAscii().constData()
   << " (FPS: " << frameRateCounter.getFrameRate() << ")";
   //std::cerr << "ImageDisplay::doSetCaption(): " << s.str() << std::endl;
-  QWidget::setCaption ( s.str().c_str() );
+  QWidget::setWindowTitle ( s.str().c_str() );
 }
 
 

+ 2 - 3
core/imagedisplay/ImageDisplay.h

@@ -8,11 +8,10 @@
 
 #include <qgl.h>
 #include <qevent.h>
-#include <q3popupmenu.h>
-//Added by qt3to4:
 #include <QMouseEvent>
 #include <QContextMenuEvent>
 #include <QGLWidget>
+#include <QMenu>
 
 #include <vector>
 
@@ -258,7 +257,7 @@ protected:
    * called by contextMenuEvent(), use this to include additional
    * menu items
    */
-  virtual void addExtraMenuItems ( Q3PopupMenu *popupMenu );
+  virtual void addExtraMenuItems ( QMenu *popupMenu );
 
   //! receive mouse events
   virtual void mousePressEvent(QMouseEvent* event);

+ 8 - 10
core/imagedisplay/ImageDisplayManagerWidget.cpp

@@ -4,28 +4,26 @@
 #include <qpushbutton.h>
 #include <qlayout.h>
 #include <qtooltip.h>
-#include <q3whatsthis.h>
+
 //Added by qt3to4:
-#include <Q3VBoxLayout>
+#include <QVBoxLayout>
 
 /*
  *  Constructs a ImageDisplayManagerWidget as a child of 'parent', with the
  *  name 'name' and widget flags set to 'f'.
  */
 ImageDisplayManagerWidget::ImageDisplayManagerWidget( QWidget* parent, const char* name, Qt::WFlags fl )
-    : QWidget( parent, name, fl )
+    : QWidget( parent, fl )
 {
-    if ( !name )
-  setName( "ImageDisplayManagerWidget" );
-    ImageDisplayManagerWidgetLayout = new Q3VBoxLayout( this, 11, 6, "ImageDisplayManagerWidgetLayout");
+    ImageDisplayManagerWidgetLayout = new QVBoxLayout( this );
 
-    buttonShowAll = new QPushButton( this, "buttonShowAll" );
+    buttonShowAll = new QPushButton( this );
     ImageDisplayManagerWidgetLayout->addWidget( buttonShowAll );
 
-    buttonHideAll = new QPushButton( this, "buttonHideAll" );
+    buttonHideAll = new QPushButton( this );
     ImageDisplayManagerWidgetLayout->addWidget( buttonHideAll );
 
-    buttonDeleteAll = new QPushButton( this, "buttonDeleteAll" );
+    buttonDeleteAll = new QPushButton( this );
     ImageDisplayManagerWidgetLayout->addWidget( buttonDeleteAll );
     languageChange();
     resize( QSize(205, 133).expandedTo(minimumSizeHint()) );
@@ -51,7 +49,7 @@ ImageDisplayManagerWidget::~ImageDisplayManagerWidget()
  */
 void ImageDisplayManagerWidget::languageChange()
 {
-    setCaption( tr( "Image displays" ) );
+    setWindowTitle( tr( "Image displays" ) );
     buttonShowAll->setText( tr( "Show all images" ) );
     buttonHideAll->setText( tr( "Hide all images" ) );
     buttonDeleteAll->setText( tr( "Release (!) all images" ) );

+ 5 - 9
core/imagedisplay/ImageDisplayManagerWidget.h

@@ -3,14 +3,10 @@
 
 #include <qvariant.h>
 #include <qwidget.h>
-//Added by qt3to4:
-#include <Q3GridLayout>
-#include <Q3HBoxLayout>
-#include <Q3VBoxLayout>
-
-class Q3VBoxLayout;
-class Q3HBoxLayout;
-class Q3GridLayout;
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+
 class QSpacerItem;
 class QPushButton;
 
@@ -32,7 +28,7 @@ public slots:
     virtual void buttonDeleteAll_clicked();
 
 protected:
-    Q3VBoxLayout* ImageDisplayManagerWidgetLayout;
+    QVBoxLayout* ImageDisplayManagerWidgetLayout;
 
 protected slots:
     virtual void languageChange();

+ 12 - 4
core/imagedisplay/QtFramework.cpp

@@ -28,7 +28,11 @@ QtFramework::QtFramework()
 #endif
 
 #ifndef WIN32
-  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#ifndef __clang__
+#ifndef __llvm__ 
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 }
 
@@ -40,7 +44,11 @@ QtFramework::QtFramework(int& argc, char** argv)
 #endif
 
 #ifndef WIN32
-  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#ifndef __clang__
+#ifndef __llvm__ 
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 }
 
@@ -86,8 +94,8 @@ int QtFramework::nonstaticExec(QWidget* _mainWindow, bool showMainWindow) {
 }
 
 int QtFramework::doExec(bool showMainWindow) {
-  //application->setMainWidget(mainWindow.get());
-  application->setMainWidget(mainWindow);
+  mainWindow->setAttribute(Qt::WA_QuitOnClose, true);
+
   if (showMainWindow) {
     mainWindow->show();
   }

+ 6 - 6
core/imagedisplay/SimpleSelector.cpp

@@ -39,27 +39,27 @@ void SimpleSelector::rectSelect(float left, float top, float right, float bottom
     updateGL();
 }
   
-void SimpleSelector::addExtraMenuItems ( Q3PopupMenu *popupMenu )
+void SimpleSelector::addExtraMenuItems ( QMenu *popupMenu )
 {
     colorMenuMap.clear();
     for ( int color = 1 ; color <= m_maxColors ; color++ )
     {
 		string caption = "Color/Class " + itostr(color);
-		int id = popupMenu->insertItem ( QString(caption.c_str()), this, SLOT(dummy()) );
-		colorMenuMap.insert ( pair<int, int> ( id, color ) );
+		QAction* action = popupMenu->addAction ( QString(caption.c_str()), this, SLOT(dummy()) );
+		colorMenuMap.insert ( pair<QAction*, int> ( action, color ) );
     }
 
     connect (popupMenu, SIGNAL(activated(int)), this, SLOT(menuActivated(int)));
-    popupMenu->insertSeparator();
+    popupMenu->addSeparator();
 }
   
 void SimpleSelector::dummy(void)
 {
 }
 
-void SimpleSelector::menuActivated ( int id ) 
+void SimpleSelector::menuActivated (QAction* action) 
 {
-    map<int, int>::const_iterator i = colorMenuMap.find(id);
+    map<QAction*, int>::const_iterator i = colorMenuMap.find(action);
     if ( i != colorMenuMap.end()  ) 
 		setCurrentColor(i->second);
 }

+ 3 - 3
core/imagedisplay/SimpleSelector.h

@@ -65,7 +65,7 @@ protected:
    * called by contextMenuEvent(), use this to include additional
    * menu items
    */
-  void addExtraMenuItems ( Q3PopupMenu *popupMenu );
+  void addExtraMenuItems ( QMenu *popupMenu );
 
   //! set current marker color
   void setCurrentColor ( int color );
@@ -81,7 +81,7 @@ private slots:
   void rectSelect(float left, float top, float right, float bottom);
 
   //! slot needed for the context menu
-  void menuActivated ( int id );
+  void menuActivated ( QAction* action );
 
   //! dummy slot for menu item insertion
   void dummy(void);
@@ -106,7 +106,7 @@ private:
   std::vector<int> m_rectanglesColor;
 
   //! this map maps menu item ids to colors
-  std::map<int, int> colorMenuMap;
+  std::map<QAction*, int> colorMenuMap;
 
 };
 

+ 6 - 1
core/imagedisplay/progs/showImage.cpp

@@ -18,8 +18,13 @@ using namespace std;
 */
 int main ( int argc, char **argv )
 {
+
 #ifndef WIN32
-  std::set_terminate ( __gnu_cxx::__verbose_terminate_handler );
+#ifndef __clang__
+#ifndef __llvm__ 
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 
   for ( int i = 1 ; i < argc ; i++ )

+ 0 - 1
core/matlabAccess/MatFileIO.h

@@ -25,7 +25,6 @@
 #else //#ifdef NICE_USELIB_MATIO
 
 #include <matio.h>
-#include <matio_private.h>
 
 #ifndef sparse_t
 #define sparse_t mat_sparse_t

+ 31 - 0
core/tutorial/TODO

@@ -0,0 +1,31 @@
+# Tutorials TODO
+
+## General
+- Add "tutorial 0", a cheat sheet-like overview of NICE?
+
+## Tutorial 1 - Basic Image I/O Operations
+- Complete list of file formats vs. dependencies
+- Write down what parts of NICE support certain ImageT<> instances
+- Add recommendations on what pixel formats to use because of this
+
+## Tutorial 2 - Grayscale Image Operations
+- Add overview of different gray value transforms
+- Expand section about Image operator overloads
+- Add section on histogram specifications
+
+## Tutorial 3 - Color Image Operations
+- Section about differences and similarities between ImageT<> and ColorImageT<>
+- Section about conversion between color spaces
+
+## Tutorial 4 - Filters
+- Section about mean filters
+- Section about separable linear filters
+- Section about gaussian filters
+- Section about gradient images
+
+# Proposals for tutorials > 4
+- Drawing
+- Gauss pyramids? (Requires IPP)
+- Hough transform? (Lots of questions...)
+- Linear algebra examples?
+

+ 59 - 0
core/tutorial/doc/00_install.md

@@ -0,0 +1,59 @@
+# Tutorial 00 - Building and installing NICE-core
+
+## Dependencies
+
+### Linux
+The following libraries and programs are required in order to build NICE-core.
+
+ - Command line developer tools 
+ - CMake 2.8.6 or later
+ - Qt 4.x
+ - OpenGL
+ - GLUT 2.x
+
+### Mac OS X
+Newer version of Mac OS X ship with clang as the default compiler.
+NICE depends on some libraries that are available from _homebrew_,
+so you need to install it from [brew.sh](http://brew.sh) first.
+
+You also need to install Qt 4.8.5 for Mac.
+If you have Mac OS X 10.9, you also have to remove lines 330-332 from
+_qtglobal.h_:
+
+```c++
+#  if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_8)
+#    warning "This version of Mac OS X is unsupported"
+#  endif
+```
+
+And finally FreeGLUT (using _homebrew_):
+
+```bash
+$ brew install freeglut
+```
+
+## Preparing the file system
+Make a new working directory and clone the repository from GitHub:
+
+```bash
+$ mkdir nice
+$ cd nice
+$ git clone https://github.com/cvjena/nice-core.git
+```
+
+NICE needs to be built out-of-tree (in a separate directory next
+to __nice-core__):
+
+```bash
+$ cd nice
+$ mkdir build
+$ cd build
+```
+
+## Building NICE-core
+Navigate to the __build__ directory and build NICE-core like this:
+
+```bash
+$ cmake ../nice-core
+$ make
+```

+ 141 - 0
core/tutorial/doc/01_imageio.md

@@ -0,0 +1,141 @@
+# Tutorial 01 - Basic Image I/O Operations
+
+In this first tutorial you will learn how to read and write image files and how images are represented in NICE.
+
+## Prerequisites
+If you need support for a specific image file format other than PGM/PPM, you have to compile nice-core yourself and add the necessary libraries and CMake flags.
+
+The sample code for this tutorial does not have any dependencies other than nice-core. You can find it in the tutorial/progs subfolder.
+
+## Images in memory
+NICE provides a common generic interface for grayscale and multi-channel
+images.
+The corresponding classes are _ImageT_ and _ColorImageT_, both subclasses of
+_GrayColorImageCommonImplementationT_ which contains the most basic image
+access methods.
+Those are used by many of the other modules.
+You can find typical use cases in the next tutorials.
+
+Note that NICE does not have generic implementations of every function.
+We recommend using 8-bit images for most applications and also
+provide a shorthand typedef called _Image_.
+
+## Image files
+In NICE, instances of _ImageT_ or _ColorImageT_ do not have to exist on disk. Files are different, completely independent objects. The _ImageFile_ class serves as a pointer to a file in the file system.
+
+An instance of _ImageFile_ can be read from or written to, but it does not modify the file in any way unless you call those methods.
+
+Constructing an _ImageFile_ is simple:
+
+```c++
+ImageFile file("path/to/file.pgm");
+```
+
+This does not touch the file at all and it doesn't need to exist. If it does exist, you can read the image file into memory like this:
+
+```c++
+Image image_in_memory;
+file.reader(&image_in_memory);
+```
+
+After making our changes to the image (in memory), we can write them to the file:
+
+```c++
+file.writer(&image_in_memory);
+```
+
+## Header information
+Sometimes it can be useful to access metadata without reading the whole image into memory. _ImageFile_ provides the __getHeader__ method for this. It reads the file and returns an instance of _Header_ with the fields __width__, __height__, __bitdepth__, __channel__.
+
+## Formats
+Note that _ImageFile_ attemtps to determine the file format by looking at the file name. You can override this behaviour by providing the __type__ parameter using the _Format_ enumeration.
+
+Supported file formats include PGM/PPM out of the box and those provided by libpng, libjpeg and libimagemagick++.
+
+The sample images do not need any additional libraries.
+
+# Sample code
+There is a complete sample program for every tutorial in this series.
+These samples are built along with NICE and can be found in the
+__core__ output directory.
+
+The sample program for this tutorial reads a file from disk to memory,
+displays metadata from the file header and writes the image to another
+file.
+
+You can find PXM sample images to use with the sample code
+in the __tutorial__ folder.
+
+## Includes
+We start of the sample program by including the necessary header files.
+The first few tutorials explain the usage of classes in the __image__
+subdirectory.
+
+Header files are usually named after the classes they declare.
+We need the _ImageT_ and _ImageFile_ classes, so our sample code
+starts like this:
+
+```c++
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+```
+
+## File names
+We then get the file names from the command line.
+NICE will automatically determine the file type from its ending.
+This works for reads and writes, so you can use this sample program
+as a simple converter between image formats.
+
+This next part simply checks if the user specified both source and
+destination file.
+If there are enough arguments, they are stored in a _string_.
+ 
+```c++
+// Check if enough parameters were supplied
+if (argc < 3) {
+	std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+	return -1;
+}	
+
+// These are our file names
+std::string input_path(argv[1]);
+std::string output_path(argv[2]);
+```
+
+## Image metadata
+_ImageFile_ can read the header information without reading the whole image
+into memory.
+We use the __getHeader__ method to obtain a _Header_ instance.
+The fields are written to the standard output.
+
+```c++
+// Read file header and display header information
+NICE::ImageFile source_file(input_path);
+NICE::ImageFile::Header source_header = source_file.getHeader();
+
+std::cout << "Source image dimensions: " << source_header.width << " x " << source_header.height;
+std::cout << " (" << source_header.channel << " channels, " << source_header.bitdepth << " bpp)\n";
+```
+
+## Reading and writing the image
+To read the image, we create an empty instance of _ColorImage_ hand it over
+to the file's __reader__ method.
+
+Writing the image to disk is just as easy: contruct an _ImageFile_ with the
+destination path and call the __writer__ method.
+
+```c++
+// Read image into memory
+NICE::ColorImage source_image;
+source_file.reader(&source_image);
+
+// Write image to disk
+NICE::ImageFile dest_image(output_path);
+dest_image.writer(&source_image);
+return 0;
+```
+
+Remember that _ImageFile_ objects are just containers for a file's location
+and only open the file when you call methods that require reading or writing.

+ 153 - 0
core/tutorial/doc/02_grayscale.md

@@ -0,0 +1,153 @@
+# Tutorial 02 - Grayscale Image Operations
+
+After reading your image from a file into memory, you may want to optimize its histogram using gray value transforms. This tutorial will tech you the basics.
+
+## Pattern for gray value transforms
+You can use the following pattern for your gray value transforms.
+
+```c++
+template <class P> void MyTransform(NICE::ImageT<P>& image)
+{
+	for(int x = 0; x < image.width(); x++) {
+		for(int y=0; y < image.height(); y++) {
+			P pixel = image.getPixelQuick(x, y);
+			// Insert transform here	
+			image.setPixelQuick(x, y, pixel);
+		}
+	}
+}
+```
+
+Note that the get/setPixelQuick Methods don't perform boundary checks!
+
+### Optimization
+If you have access to Intel IPP, you can use the overloaded operators provided in ImageOperators.h.
+
+Another easy way to improve performance is adding a "parallel for" OpenMP compilation hint.
+
+## Gamma transforms
+Gamma transforms are a little more complicated, because gray values are not always in the [0,1] range.
+For example, the _Image_ and _GrayImage16s_ use the full positive range of their data types while the _FloatImage_ class can handle arbitrary ranges.
+
+You can use the __max()__ and __min()__ methods on your image to find its specific range. 
+
+## Histogram
+NICE provides a _Histogram_ class for 8-bit grayscale and color images (_Image_ and _ColorImage_).
+To calculate an image's histogram, use the constructor:
+
+``` c++
+NICE::Histogram histogram(image, 0, 256);
+```
+
+# Sample code
+This sample program attempts to equalize an image's histogram by deriving a
+gray value transform from the cumulative histogram.
+
+Take this ![sample image](screenshots/tut02_eq_org.png):
+the ![histogram](screenshots/tut02_eq_hist_org.png) shows that it doesn't make
+use of the whole range of gray values.
+After running the sample program, the image should look like
+![this](screenshot/tut02_eq_new.png).
+We can see in its ![histogram](screenshot/tut02_eq_hist_new.png) that is uses
+the complete range now.
+
+## Includes and file names
+Just like the previous sample, the program needs input and output file names.
+It also uses the _ImageT_ and _ImageFile_ classes, but needs the relevant
+headers for _Histogram_ and _VectorT_ as well.
+
+```c++
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Histogram.h>
+#include <core/vector/VectorT.h>
+```
+
+The command line is then checked and stored like in the first sample. Most
+sample programs will use this pattern.
+
+```c++
+// Check if enough parameters were supplied
+if (argc < 3) {
+	std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+	return -1;
+}
+
+// These are our file names
+std::string input_path(argv[1]);
+std::string output_path(argv[2]);
+```
+
+## Calculating the histogram
+We read the image file specified as a command line argument using _ImageFile_
+like we learned in the first tutorial. This time we don't use _ColorImage_,
+because the sample program describes a gray value transform.
+
+When constructing a _Histogram_, we need to specify the range of gray values
+in our image. 8-bit images have values ranging from 0 to 255, but while the
+histogram includes the lower boundary as a bin, it does not include the upper
+boundary because it uses the difference between the boundarys to calculate the
+number of bins. This is why the sample program uses the values 0 and 256.
+
+The cumulative functions doesn't return another _Histogram_, but an _IntVector_.
+
+```c++
+// Read image into memory
+NICE::ImageFile source_file(input_path);
+NICE::Image image;
+source_file.reader(&image);
+
+// Calculate cumulative histogram
+NICE::Histogram histogram(image, 0, 256);
+NICE::IntVector* cumulative_histogram = histogram.cumulative();
+```
+
+## The transform
+In theory, if we use the cumulative histogram as a mapping for our gray value
+transform, the resulting image has a perfectly uniform histogram. We can prove
+this for images that are continuously differentiable functions of real numbers.
+This is not the case for digital images:
+suppose an image is filled with a single color.
+There is no gray value transform that can turn this image into one with a
+uniform distribution of gray values.
+
+We also need to scale the cumulative histogram down to our 8-bit range.
+The largest value will match the total number of pixels in the source image,
+so we use that to calculate a scaling factor.
+
+```c++
+double factor = 255.0/(double)(image.width()*image.height());
+
+// Transform using our pattern
+for(int x = 0; x < image.width(); x++) {
+	for(int y=0; y < image.height(); y++) {
+		// This is the old gray value
+		Ipp8u pixel = image.getPixelQuick(x, y);
+
+		// We use it as and index into the cumulative histogram to
+		// computer the new one. This has to be scaled appropriately
+		// using our precomputed factor.
+		double new_pixel_f =
+				((double)cumulative_histogram->get(pixel))*factor;
+
+		// The pixel format is 8-bit integer, so we have to convert
+		// the result
+		Ipp8u new_pixel = static_cast<Ipp8u>(new_pixel_f + 0.5);
+
+		// ..and save it
+		image.setPixelQuick(x, y, new_pixel);
+
+	}
+}
+```
+
+We can now write the changed image back to disk. We use a new file to preserve
+the original.
+
+```c++
+NICE::ImageFile dest_image(output_path);
+dest_image.writer(&image);
+return 0;
+```

+ 126 - 0
core/tutorial/doc/03_color.md

@@ -0,0 +1,126 @@
+# Tutorial 03 - Color Image Operations
+
+## Architecture
+As mentioned in tutorial 01, color images in memory are represented by instances of
+_ColorImageT<>_.
+
+## File input/output
+Because _ImageT<>_ and _ColorImageT<>_ are both subclasses of 
+_GrayColorImageCommonImplementationT<>_, you can use the __reader__ and __writer__ methods
+as explained in tutorial 01.
+
+Note that using a file format that doesn't match the number of channels used by your image
+results in undefined behavior.
+
+## Read/write operations
+For pixel access, the __setPixelQuick__ methods accepts either a matching instance of
+_ColorT<>_ (_Color_ for 8-bit images) or three pixel values:
+
+```c++
+// Using Color
+color_image.setPixelQuick(4, 3, NICE::Color(0, 255, 0));
+
+// Using separate parameters
+color_image.setPixelQuick(4, 3, 0, 255, 0);
+```
+
+To read a pixel, use __getPixelQuick__ with the additional _channel_ parameter:
+
+```c++
+r = color_image.getPixelQuick(4, 3, 0);
+g = color_image.getPixelQuick(4, 3, 1);
+b = color_image.getPixelQuick(4, 3, 2);
+```
+
+## Conversion between color spaces
+NICE can convert between the three-channel color spaces YUV, HSV and RGB.
+The following methods are available:
+
+- __rgbToHSV__
+- __hsvToRGB__
+- __rgbToYUV__
+- __yuvToRGB__
+
+These methods allocate a new _ColorImageT<>_ (you can specify your own if you want to) and
+return a pointer to it:
+
+```c++
+// Use the return value
+NICE::ColorImage my_rgb_image = NICE::hsvToRGB(my_hsv_image);
+
+// Specify your own!
+NICE::ColorImage my_yuv_image(my_hsv_image.width(), my_hsv_image.height());
+NICE::rgbToYUV(my_rgb_image, my_yuv_image);
+```
+
+### Pseudocolors
+While not strictly a conversion, you can enhance a gray image with pseudocolors using the
+built-in function _imageToPseudoColor_. This is a very helpful visualization technique
+if your gray values represent something other than intensity (e.g depth or temperature):
+
+```c++
+// Allocate color image of appropriate dimensions
+NICE::ColorImage color_image(image.width(), image.height());
+
+// Convert to pseudocolor image
+NICE::imageToPseudoColor(image, color_image);
+```
+
+# Sample code
+The sample program for this chapter follows the input-transform-output pattern
+of the previous examples. Because conversions between color spaces are
+very easy to do with NICE-core, but also very hard to visualize, we will
+show you how to work with _ColorImageT<>_ by coloring a grayscale input
+using pseudocolors.
+
+## Includes and file names
+You can find the pseudocolor and conversion functions in __Convert.h_.
+_ColorImageT<>_ has its own header file.
+
+```c++
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ColorImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Convert.h>
+```
+
+We also need to check the command line for arguments and store them
+if there are enough:
+
+```c++
+// Check if enough parameters were supplied
+if (argc < 3) {
+	std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+	return -1;
+}
+
+// These are our file names
+std::string input_path(argv[1]);
+std::string output_path(argv[2]);
+```
+
+## Pseudocolors
+The next step is reading the file into an _Image_ and calling the
+_imageToPseudoColor_ method to perform the colorization. This methods needs
+a destination _ColorImage_ of similar dimensions.
+
+```c++
+// Read image into memory
+NICE::ImageFile source_file(input_path);
+NICE::Image image;
+source_file.reader(&image);
+
+// Calculate pseudocolors
+NICE::ColorImage pseudo_image(image.width(), image.height());
+NICE::imageToPseudoColor(image, pseudo_image);
+```
+
+After this is done, we write __pseudo_image__ to disk so we can look at it:
+
+```c++
+NICE::ImageFile dest_image(output_path);
+dest_image.writer(&pseudo_image);
+return 0;
+```

+ 87 - 0
core/tutorial/doc/04_filter.md

@@ -0,0 +1,87 @@
+# Tutorial 04 - Filters
+Linear filters play an important role in image processing.
+They are used for dealing with noise and in many computer vision applications.
+NICE provides generic implementations of several common filter types and
+supports custom kernels.
+
+## Data types
+The class _FilterT<>_ contains static methods for every filter type supported
+by NICE.
+You can specify different data types for your source and destination images and
+also
+for the calculations used during convolution.
+
+We recommend sticking to 8-bit-per-channel images (using the Image typedef as
+recommended throughout this tutorial series) and using _double_ values for
+the filter calculations.
+
+In this case you can use the _Filter_ typedef.
+
+## Source and destination image
+Most filter methods expect a destination image to write their results to.
+This image should have the same dimensions as the source image, otherwise
+it will be resized or an exception will be thrown.
+
+You should always construct a destination image like this:
+
+```c++
+// [...]
+NICE::Image image;
+// [...]
+NICE::Image result(image.width(), image.height());
+```
+
+## Filter types
+This section will give you an overview of the different kinds of filter NICE
+supports.
+
+### Mean filter
+A very simple filter for noise reduction is the mean filter.
+NICE implements this filter two times: for small and for large kernels.
+
+For most applications, the small implementation will suffice:
+
+```c++
+const unsigned int size = 3;
+NICE::Filter::filterMean(image, size, result);
+```
+
+The __size__ parameter describes the radius of the neighborhood
+(not including the center)
+used as a filter kernel. For size = 3, you get a 7x7 mean filter.
+
+### Sobel filter
+For some detection algorithms, you need gradient images.
+To compute the first derivative of your image in X and Y directions,
+use the following methods:
+
+```c++
+NICE::Filter::sobelX(image,gradientImageX);
+NICE::Filter::sobelY(image,gradientImageY);
+```
+
+
+### Using your own filter kernel
+Some applications require a specific filter kernel.
+You can supply an instance of _MatrixT<>_ with your values.
+
+The template argument should match the type used for calculations in
+_FilterT_.
+If you use the _Filter_ typedef, you can use the _Matrix_ typedef as well.
+
+You can then apply the filter like this:
+
+```c++
+NICE::Filter::filter(image, kernel, result);
+```
+
+If your filter kernel is separable, you can get better performance by applying
+two one-dimensional convolutions.
+Instead of _MatrixT<>_, you supply two _VectorT<>_ instances.
+As with _Matrix_, there's a typedef _Vector_ for _VectorT<double>_.
+
+You need to call two methods in this case:
+
+```c++
+NICE::Filter::filterX(image, kernel, result);
+NICE::Filter::filterY(image, kernel, result);

+ 143 - 0
core/tutorial/doc/05_vecmat.md

@@ -0,0 +1,143 @@
+# Tutorial 05 - Vectors and Matrices
+## Vectors
+NICE provides the generic _VectorT<>_ class for vector data storage and
+calculations.
+It supports the same, large number of operations for all data types.
+
+There are deep and shallow copy functions for LinAl interoperability.
+
+### Construction
+While _VectorT<>_ provides a default constructor, it is only if you want
+to avoid pointers as member variables.
+
+_VectorT<>_ needs to know the number of elements because resizing a vector is
+extremely inefficient. You can also initialize the elements if you want to:
+
+```c++
+// This line creates an empty vector
+VectorT<double> empty_vector();
+
+// This line creates a three-dimensional vector
+// The elements are not initialized
+VectorT<double> threed_vector(3);
+
+// This line creates a two-dimensional vector
+// We initialize the elements to the value 25.3
+VectorT<double> twod_vector(3, 25.3);
+```
+
+
+### Operators
+For easy and expressive calculations, _VectorT<>_ defines the following
+classes of operators:
+
+* Unary operators:
+    - Unchecked read or reference access to element ([])
+    - Checked read or reference access to element (())
+
+* Binary operators:
+    - Vector addition and subtraction (+,-)
+    - Scalar multiplication (\*)
+
+* Combined assignment operators:
+    - Vector addition and subtraction (+=,-=)
+    - Vector multiplication and division (\*=,/=)
+    - Scalar addition and subtraction (+=,-=)
+    - Scalar multiplication and division (\*=,/=)
+
+### Methods
+In addition to basic algebra, _VectorT<>_ supports more complex operations.
+These include:
+
+* Calculating the scalar product of two _VectorT<>_: __scalarProduct__
+* Determining various statistics: __Sum__, __Mean__, __Median__, __StdDev__,
+  __Min__, __Max__
+* Additional information on these statistics: __MaxIndex__, __MinIndex__
+* Mean in non-euclidean vector spaces: __CircularMean__
+* Several norms: __normInf__, __normL1__, __normL2__
+* ...and normalization routines: __normalizeInf__, __normalizeL1__, __normalizeL2__
+* Basic sorting functions: __sortAscend__, __sortDescend__
+
+## Matrices
+Just like vectors, matrices have a generic representation in NICE.
+The class is called _MatrixT<>_ and is not related to _VectorT<>_ in that it
+is not a construct like _VectorT<VectorT<>>_.
+
+### Construction
+_MatrixT<>_ has a large number of constructors for different use cases.
+The default constructor creates a _MatrixT<>_ of dimensions 0x0 and should
+only be used for RAII purposes because resizing a _MatrixT<>_ is a very
+inefficient operation.
+
+```c++
+// Construction and expansion
+NICE::MatrixT<double> empty_matrix();
+empty_matrix.resize(5,4);
+```
+
+Instead, you can specifiy the dimensions and an optional default element.
+When no default element is given to the constructor, the matrix will not
+be initialized contains unpredictable data.
+
+```c++
+// 4x5 matrix - no initialization
+NICE::MatrixT<double> undefined_matrix(4,5);
+
+// 5x6 matrix - default element: 1
+NICE::MatrixT<double> simple_matrix(5,6,1);
+```
+
+### Data access
+_MatrixT<>_ provides different methods for read and write access to fit as
+many applications as possible.
+See the following snippet for important use cases:
+
+```c++
+// This is our matrix
+NICE::MatrixT<double> matrix(3,3);
+
+// At this point, the elements are unknown, so let's set them all to zero.
+matrix.set(0);
+
+// Now, create a vector
+NICE::VectorT<double> vector(3);
+vector[0]=1, vector[1]=2, vector[2]=3;
+
+// We can use this vector with the setRow method
+matrix.setRow(0, vector);
+
+// Set the center element to 5
+matrix(1,1)=5;
+
+// How can we set a column using a VectorT?
+matrix.getColumnRef(2)=vector;
+```
+
+### Operators
+_MatrixT<>_ exports basic calculations and methods as operators:
+
+* Unary operators:
+    - Unchecked read or reference access to element (())
+
+* Binary operators:
+    - Matrix addition and subtraction (+,-)
+    - Matrix-scalar multiplication (\*)
+    - Matrix-vector multiplication (\*)
+    - Matrix multiplication (\*)
+
+* Combined assignment operators:
+    - Matrix addition and subtraction (+=,-=)
+    - Matrix multiplication and division - element-wise (\*=,/=)
+    - Scalar addition and subtraction (+=,-=)
+    - Scalar multiplication and division (\*=,/=)
+
+### Methods
+More advanced calculations are available as member functions:
+
+* Set the matrix to a multiple of the identity matrix or
+  add to the existing matrix: __setIdentity__, __addIdentity__
+* Add a vector's elements as a diagonal matrix: __addDiagonal__
+* Calculate the tensor product of two vectors and store it
+  or add it to the matrix: __tensorProduct__, __addTensorProduct__
+* Store the result of a matrix multiplication: __multiply__
+* Check if a floating point matrix contains a NaN element: __containsNaN__

+ 57 - 0
core/tutorial/doc/06_algebra.md

@@ -0,0 +1,57 @@
+# Tutorial 06 - Linear Algebra
+
+## Singular value decomposition
+_Note: Currently, calculating the SVD of a matrix requires LinAL_
+
+Use the _SVD_ class for fast singular value decomposition.
+The calculation is performed at initialization and the resulting
+matrices are available from getter functions.
+
+Calculating the SVD is a very straightforward task.
+See this short example on how to use the SVD class:
+
+```c++
+// Create a matrix
+NICE::MatrixT<double> my_matrix(3,3,0);
+my_matrix.addIdentity(1);
+my_matrix(0,2) = 5;
+my_matrix(1,0) = 3;
+
+// Calculate the SVD
+NICE::SVD svd(my_matrix);
+
+// Store the results
+NICE::MatrixT<double> result_vt = svd.getVt();
+NICE::MatrixT<double> result_u = svd.getU();
+
+// This returns the singular values in a diagonal matrix
+// This diagonal matrix is allocated only if you call this function.
+NICE::MatrixT<double> result_s_matrix = svd.getS();
+
+// This returns the singular values as a vector. Use this function for
+// increased efficiency
+NICE::VectorT<double> result_s_vector = svd.getSingularValues();
+```
+
+## Eigenvalues
+_Note: Currently, calculating the eigenvalues of a matrix requires IPP._
+
+Calculating the eigenvalues of a matrix is as simple as single function call.
+The __eigenvalues__ function takes a _MatrixT<>_ and returns a _VectorT<>_ 
+that contains the eigenvalues. It allocates a _VectorT<>_ of matching dimensions
+on the heap.
+This behavior can be overridden be specifying a pointer as the second parameter.
+
+```c++
+// Create a matrix
+NICE::MatrixT<double> matrix(3,3,0);
+matrix.addIdentity(4);
+matrix(0,1) = -2;
+
+// Calculate the eigenvalues
+NICE::VectorT<double> eigenvals = NICE::eigenvalues(matrix);
+
+// ..or use your own vector
+NICE::VectorT<double> my_own_vector(3);
+NICE::eigenvalues(matrix, my_own_vector);
+```

+ 38 - 0
core/tutorial/doc/samples.md

@@ -0,0 +1,38 @@
+# Sample code
+Some tutorials come with sample code for a more hands-on learning experience.
+The following sample programs are available:
+
+| Tutorial | Sample Program |
+| -: | - |
+| 01 | Simple program that reads a file and writes the image to another|
+| 02 | Program that optimizes the contrast of a grayscale image|
+| 03 | Program that colorizes a grayscale image using pseudocolors|
+| 04 | Program that applies a motion blur effect to an image using a linear filter|
+| 05 | Program that loads a Matlab file to showcase algebra functions|
+
+# Sample images for sample code
+NICE-core supports PPM and PGM images out of the box without any additional
+dependencies.
+
+See the __samples__ folder for sample images that work with the sample code
+from the tutorials.
+
+## Grayscale sample images
+The grayscale samples are 8-bit PGM files.
+You can use them with the following sample programs:
+
+* Tutorial 02
+* Tutorial 03
+* Tutorial 04
+
+## Color sample images
+The color samples are 8-bit-per-channel PPM images.
+They work with the sample code from these tutorials:
+
+* Tutorial 01
+
+# Other samples
+We also include some Matlab files for use with the following samples:
+
+* Tutorial 05
+* Tutorial 06

+ 45 - 0
core/tutorial/progs/01_imageio.cpp

@@ -0,0 +1,45 @@
+/*
+ * Tutorial 01 - Basic Image I/O Operations
+ * Sample Implementation
+ *
+ * @file 01_imageio.cpp
+ * @brief Sample implementation for tutorial 01
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+		return -1;
+	}	
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string output_path(argv[2]);
+
+	// Read file header and display header information
+	NICE::ImageFile source_file(input_path);
+	NICE::ImageFile::Header source_header = source_file.getHeader();
+
+	std::cout << "Source image dimensions: " << source_header.width << " x " << source_header.height;
+	std::cout << " (" << source_header.channel << " channels, " << source_header.bitdepth << " bpp)\n";
+
+	// Read image into memory
+	NICE::ColorImage source_image;
+	source_file.reader(&source_image);
+
+	// Write image to disk
+	NICE::ImageFile dest_image(output_path);
+	dest_image.writer(&source_image);
+	return 0;
+}

+ 74 - 0
core/tutorial/progs/02_grayscale.cpp

@@ -0,0 +1,74 @@
+/*
+ * Tutorial 02 - Grayscale Image Operations
+ * Sample Implementation
+ *
+ * @file 02_grayscale.cpp
+ * @brief Sample implementation for tutorial 02
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Histogram.h>
+#include <core/vector/VectorT.h>
+
+/*
+ * Entry point
+ */
+
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+		return -1;
+	}
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string output_path(argv[2]);
+
+	// Read image into memory
+	NICE::ImageFile source_file(input_path);
+	NICE::Image image;
+	source_file.reader(&image);
+
+	// Calculate cumulative histogram
+	NICE::Histogram histogram(image, 0, 256);
+	NICE::IntVector* cumulative_histogram = histogram.cumulative();
+
+	// The largest value in the cumulative histogram is the total pixel count
+	// of the source image. We need to scale this down to 255 to match the pixel
+	// format of the image.
+	double factor = 255.0/(double)(image.width()*image.height());
+
+	// Transform using our pattern
+	for(int x = 0; x < image.width(); x++) {
+		for(int y=0; y < image.height(); y++) {
+			// This is the old gray value
+			Ipp8u pixel = image.getPixelQuick(x, y);
+
+			// We use it as and index into the cumulative histogram to
+			// computer the new one. This has to be scaled appropriately
+			// using our precomputed factor.
+			double new_pixel_f =
+					((double)cumulative_histogram->get(pixel))*factor;
+
+			// The pixel format is 8-bit integer, so we have to convert
+			// the result
+			Ipp8u new_pixel = static_cast<Ipp8u>(new_pixel_f + 0.5);
+
+			// ..and save it
+			image.setPixelQuick(x, y, new_pixel);
+
+		}
+	}
+
+
+	// Write image to disk
+	NICE::ImageFile dest_image(output_path);
+	dest_image.writer(&image);
+	return 0;
+}

+ 45 - 0
core/tutorial/progs/03_color.cpp

@@ -0,0 +1,45 @@
+/*
+ * Tutorial 03 - Color Image Operations
+ * Sample Implementation
+ *
+ * @file 03_color.cpp
+ * @brief Sample implementation for tutorial 03
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+ 
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ColorImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Convert.h>
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+		return -1;
+	}
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string output_path(argv[2]);
+
+	// Read image into memory
+	NICE::ImageFile source_file(input_path);
+	NICE::Image image;
+	source_file.reader(&image);
+
+	// Calculate pseudocolors
+	NICE::ColorImage pseudo_image(image.width(), image.height());
+	NICE::imageToPseudoColor(image, pseudo_image);
+
+	// Write image to disk
+	NICE::ImageFile dest_image(output_path);
+	dest_image.writer(&pseudo_image);
+	return 0;
+}

+ 53 - 0
core/tutorial/progs/04_filter.cpp

@@ -0,0 +1,53 @@
+/*
+ * Tutorial 04 - Filters
+ * Sample Implementation
+ *
+ * @file 04_filter.cpp
+ * @brief Sample implementation for tutorial 04
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/vector/MatrixT.h>
+#include <core/image/FilterT.h>
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+		if (argc < 3) {
+			std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+			return -1;
+		}
+
+		// These are our file names
+		std::string input_path(argv[1]);
+		std::string output_path(argv[2]);
+
+		// Read file header and display header information
+		NICE::ImageFile source_file(input_path);
+
+		// Read image into memory
+		NICE::Image image;
+		source_file.reader(&image);
+
+		// Allocate memory for result image
+		NICE::Image result(image.width(), image.height());
+
+		// Put together a simple convolution kernel for our motion blur effect
+		NICE::Matrix kernel(10,10);
+		kernel.set(0);
+		kernel.addIdentity(0.1);
+
+		// Filter the image
+		NICE::Filter::filter(image, kernel, result);
+
+		// Write image to disk
+		NICE::ImageFile dest_image(output_path);
+		dest_image.writer(&result);
+		return 0;
+}

+ 125 - 0
core/tutorial/progs/05_matio.cpp

@@ -0,0 +1,125 @@
+/*
+ * Tutorials 05/06 - Matlab I/O and Linear Algebra
+ * Sample Implementation
+ *
+ * @file 05_matio.cpp
+ * @brief Sample implementation for tutorials 05/06
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <exception>
+#include <core/image/ImageT.h>
+#include <core/vector/MatrixT.h>
+#include <core/vector/VectorT.h>
+#include <core/vector/Eigen.h>
+#include <core/vector/SVD.h>
+#include <core/image/FilterT.h>
+
+#ifdef NICE_USELIB_MATIO
+#include <core/matlabAccess/MatFileIO.h>
+
+template<typename T> void printMatrix(NICE::MatrixT<T> matrix);
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <matlab file> <matrix name>\n";
+		return -1;
+	}
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string matrix_name(argv[2]);
+
+	NICE::MatFileIO matlab_file(input_path, MAT_ACC_RDONLY);
+	
+	// Show the number of variables in the file
+	int vars_in_file = matlab_file.getNumberOfVariables();
+	std::cout << vars_in_file << " Variables in " << input_path << "\n";
+
+	// Load the matrix
+	std::cout << "Loading matrix \"" << matrix_name << "\"...\n";
+
+	// Check if the variable is a matrix
+	matvar_t* matrix_variable = matlab_file.getVariableViaName(matrix_name);
+	if(matrix_variable->rank != 2) {
+		std::cout << "Variable is not a matrix. Rank: " << matrix_variable->rank << ".\n";
+		return -1;
+	}
+
+	// Read the dimensions
+	int cols = matrix_variable->dims[1];
+	int rows = matrix_variable->dims[0];
+	std::cout << "Dimensions: " << cols << " x " << rows << "\n";
+
+	// Read the matrix into a vector of vectors
+	std::vector< std::vector<double> > matrix_vecvec(rows, std::vector<double>(cols));
+	matlab_file.getFeatureMatrixViaName(matrix_vecvec, matrix_name);
+
+	// Now, we want a NICE matrix
+	NICE::MatrixT<double> matrix(rows, cols);
+	for(int i = 0; i < rows; i++) {
+		for(int j = 0; j < cols; j++) {
+			matrix(i,j) = matrix_vecvec[i][j];
+		}
+	}
+
+	// Print the NICE matrix
+	printMatrix(matrix);
+
+	// Check if eigenvalues exist
+	if(rows != cols) {
+		std::cout << "Matrix is not square, cannot calculate eigenvalues!\n";
+		return -1;
+	}
+
+	// Calculate eigenvalues
+	try {
+		NICE::VectorT<double>* matrix_eigenvalues = NICE::eigenvalues(matrix);
+	} catch (std::exception& e) {
+		std::cout << "Exception occured during eigenvalue calculation, "
+			<< "is IPP installed?\n";
+	}
+
+#ifdef NICE_USELIB_LINAL
+	// Calculate singular value decomposition
+	NICE::SVD matrix_svd(matrix);
+
+	std::cout << "Vt:\n";
+	printMatrix(matrix_svd.getVt());
+
+	std::cout << "U:\n";
+	printMatrix(matrix_svd.getU());
+
+	std::cout << "S:\n";
+	printMatrix(matrix_svd.getS());
+#else
+	std::cout << "LinAL is not installed, SVD calculation is not possible!\n";
+#endif
+	return 0;
+
+}
+
+template<typename T> void printMatrix(NICE::MatrixT<T> matrix) {
+	for(int i = 0; i < matrix.rows(); i++) {
+		for(int j = 0; j < matrix.cols(); j++) {
+			std::cout << matrix(i,j) << "\t";
+		}
+		std::cout << "\n";
+	}
+}
+#else
+
+/*
+ * Replacement entry point
+ */
+int main(int argc, char** argv) {
+	std::cout << "This sample needs MATIO to work!\n";
+}
+#endif

二进制
core/tutorial/samples/peppers_color.ppm


文件差异内容过多而无法显示
+ 4 - 0
core/tutorial/samples/peppers_gray.pgm


二进制
core/tutorial/samples/simple.mat


二进制
core/tutorial/screenshots/tut02_eq_hist_new.png


二进制
core/tutorial/screenshots/tut02_eq_hist_org.png


二进制
core/tutorial/screenshots/tut02_eq_new.png


二进制
core/tutorial/screenshots/tut02_eq_org.png


+ 6 - 2
core/vector/VectorT.tcc

@@ -756,10 +756,14 @@ void VectorT<ElementType>::sortDescend(VectorT<int> & permutation) {
   permutation.resize(this->size());
 
   int idxSelf ( 0 );
-  for (VectorT<ElementType>::const_iterator itSelf = (*this).begin(); itSelf != (*this).end(); itSelf++, idxSelf++)
+  for (typename VectorT<ElementType>::const_iterator itSelf = (*this).begin(); 
+       itSelf != (*this).end(); 
+       itSelf++, idxSelf++)
   {
     int idxOrig ( 0 );
-    for ( VectorT<ElementType>::const_iterator itOrig = tmp_cp.begin(); itOrig != tmp_cp.end(); itOrig++, idxOrig++)
+    for (typename VectorT<ElementType>::const_iterator itOrig = tmp_cp.begin(); 
+         itOrig != tmp_cp.end(); 
+         itOrig++, idxOrig++)
     {
       if ( *itOrig == *itSelf )
       {

+ 1 - 0
core/vector/ippwrapper.tcc

@@ -4,6 +4,7 @@
 #include <numeric>
 #include <cmath>
 #include <functional>
+#include <cstdlib>
 
 template<class P>
 inline IppStatus ippsCopy( const P* pSrc, P* pDst, int len ) {

+ 4 - 0
core/vector/progs/testCholeskySpeed.cpp

@@ -38,7 +38,11 @@ double getInvError ( const Matrix & A, const Matrix & Ainv )
 int main (int argc, char **argv)
 {   
 #ifndef WIN32
+#ifndef __clang__
+#ifndef __llvm__ 
     std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 
     int size = 500;

部分文件因为文件数量过多而无法显示