├── .gitattributes
├── .gitignore
├── CMakeLists.txt
├── COPYING
├── README.md
├── Texturize.props
├── _config.yml
├── adapters
└── Texturize.Adapters.Tapkee
│ ├── CMakeLists.txt
│ ├── include
│ └── Adapters
│ │ └── tapkee.hpp
│ └── src
│ ├── DescriptorExtractor.cpp
│ ├── DistanceMetrics.cpp
│ ├── PairwiseDistanceExtractor.cpp
│ ├── adapters.tapkee.cpp
│ ├── dllmain.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── apps
├── Texturize.AppearanceSpace
│ ├── CMakeLists.txt
│ ├── Texturize.AppearanceSpace.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── Texturize.Distance
│ ├── CMakeLists.txt
│ ├── Texturize.Distance.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── Texturize.FilterMR8
│ ├── CMakeLists.txt
│ ├── Texturize.FilterMR8.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── Texturize.GuidanceRefine
│ ├── CMakeLists.txt
│ ├── Texturize.GuidanceRefine.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── Texturize.KMeans
│ ├── CMakeLists.txt
│ ├── Texturize.KMeans.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── Texturize.ProgressionMap
│ ├── CMakeLists.txt
│ ├── Texturize.ProgressionMap.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── Texturize.Sandbox
│ ├── CMakeLists.txt
│ ├── Texturize.Sandbox.cpp
│ ├── gaussianpdf.h
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── Texturize.Synthesize
│ ├── CMakeLists.txt
│ ├── Texturize.Synthesize.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
└── Texturize.UVMap
│ ├── CMakeLists.txt
│ ├── Texturize.UVMap.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── cmake.ps1
├── cmake
├── DefineApp.cmake
├── GetPackageInfo.cmake
├── TexturizeSettings.cmake
└── TexturizeVersion.cmake
├── docs
├── Coherence.svg
├── DefaultConvergence.svg
├── ImprovedConvergence.svg
├── PCA.svg
├── examples
│ ├── .vscode
│ │ └── settings.json
│ ├── AppearanceSpace.cpp
│ ├── BlurFilter.cpp
│ ├── ColorSearchSpace.cpp
│ ├── EventDispatcher.cpp
│ ├── FeatureGuidance.cpp
│ ├── FilterFunction.cpp
│ ├── NaiveSamplingSynthesizer.cpp
│ ├── ProgressCallback.cpp
│ ├── PyramidSynthesizer.cpp
│ ├── SampleConstruction.cpp
│ ├── SampleMapping.cpp
│ ├── SamplePixelAccess.cpp
│ └── TrivialSearchIndex.cpp
├── getting-started-build.dox
├── getting-started-sandbox.dox
├── getting-started.dox
├── html
│ ├── Coherence.svg
│ ├── DefaultConvergence.svg
│ ├── ImprovedConvergence.svg
│ ├── _blur_filter_8cpp-example.html
│ ├── _color_search_space_8cpp-example.html
│ ├── _naive_sampling_synthesizer_8cpp-example.html
│ ├── _trivial_search_index_8cpp-example.html
│ ├── annotated.html
│ ├── chunks_8cpp-example.html
│ ├── class_h5_1_1_abstract_ds.html
│ ├── class_h5_1_1_array_type.html
│ ├── class_h5_1_1_atom_type.html
│ ├── class_h5_1_1_attribute.html
│ ├── class_h5_1_1_common_f_g.html
│ ├── class_h5_1_1_comp_type.html
│ ├── class_h5_1_1_d_set_acc_prop_list.html
│ ├── class_h5_1_1_d_set_creat_prop_list.html
│ ├── class_h5_1_1_d_set_mem_xfer_prop_list.html
│ ├── class_h5_1_1_data_set.html
│ ├── class_h5_1_1_data_space.html
│ ├── class_h5_1_1_data_type.html
│ ├── class_h5_1_1_enum_type.html
│ ├── class_h5_1_1_exception.html
│ ├── class_h5_1_1_file_acc_prop_list.html
│ ├── class_h5_1_1_file_creat_prop_list.html
│ ├── class_h5_1_1_float_type.html
│ ├── class_h5_1_1_group.html
│ ├── class_h5_1_1_h5_file.html
│ ├── class_h5_1_1_h5_library.html
│ ├── class_h5_1_1_h5_location.html
│ ├── class_h5_1_1_h5_object.html
│ ├── class_h5_1_1_id_component.html
│ ├── class_h5_1_1_int_type.html
│ ├── class_h5_1_1_link_acc_prop_list.html
│ ├── class_h5_1_1_link_creat_prop_list.html
│ ├── class_h5_1_1_obj_creat_prop_list.html
│ ├── class_h5_1_1_pred_type.html
│ ├── class_h5_1_1_prop_list.html
│ ├── class_h5_1_1_str_type.html
│ ├── class_h5_1_1_var_len_type.html
│ ├── class_texturize_1_1_appearance_space.html
│ ├── class_texturize_1_1_appearance_space_asset.html
│ ├── class_texturize_1_1_asset_persistence.html
│ ├── class_texturize_1_1_coherent_index.html
│ ├── class_texturize_1_1_coordinate_hash.html
│ ├── class_texturize_1_1_default_codec.html
│ ├── class_texturize_1_1_descriptor_extractor.html
│ ├── class_texturize_1_1_dynamic_threshold_filter.html
│ ├── class_texturize_1_1_edge_detector.html
│ ├── class_texturize_1_1_event_dispatcher.html
│ ├── class_texturize_1_1_exception.html
│ ├── class_texturize_1_1_feature_distance_filter.html
│ ├── class_texturize_1_1_feature_extractor.html
│ ├── class_texturize_1_1_feature_matching_index.html
│ ├── class_texturize_1_1_file_storage_wrapper.html
│ ├── class_texturize_1_1_filter_cascade.html
│ ├── class_texturize_1_1_function_filter.html
│ ├── class_texturize_1_1_grayscale_filter.html
│ ├── class_texturize_1_1_hdf5_file_storage.html
│ ├── class_texturize_1_1_i_file_storage.html
│ ├── class_texturize_1_1_i_filter.html
│ ├── class_texturize_1_1_i_sample_codec.html
│ ├── class_texturize_1_1_i_search_index.html
│ ├── class_texturize_1_1_i_search_space.html
│ ├── class_texturize_1_1_i_synthesizer.html
│ ├── class_texturize_1_1_normalization_filter.html
│ ├── class_texturize_1_1_open_cv_file_storage.html
│ ├── class_texturize_1_1_parallel_pyramid_synthesizer.html
│ ├── class_texturize_1_1_pyramid_synthesis_settings.html
│ ├── class_texturize_1_1_pyramid_synthesizer.html
│ ├── class_texturize_1_1_pyramid_synthesizer_state.html
│ ├── class_texturize_1_1_random_walk_index.html
│ ├── class_texturize_1_1_sample.html
│ ├── class_texturize_1_1_sample__.html
│ ├── class_texturize_1_1_sample_persistence.html
│ ├── class_texturize_1_1_sample_persistence__.html
│ ├── class_texturize_1_1_search_index.html
│ ├── class_texturize_1_1_storage_factory.html
│ ├── class_texturize_1_1_structured_edge_detector.html
│ ├── class_texturize_1_1_synthesis_settings.html
│ ├── class_texturize_1_1_synthesizer_base.html
│ ├── class_texturize_1_1_synthesizer_state.html
│ ├── classcv2_1_1_h5_utils.html
│ ├── compound_8cpp-example.html
│ ├── create_8cpp-example.html
│ ├── deprecated.html
│ ├── extend_ds_8cpp-example.html
│ ├── files.html
│ ├── getting-started-build.html
│ ├── getting-started-sandbox.html
│ ├── getting-started.html
│ ├── group__analysis.html
│ ├── group__codecs.html
│ ├── group__synthesis.html
│ ├── h5group_8cpp-example.html
│ ├── index.html
│ ├── m-texturize+doxygen.compiled.css
│ ├── modules.html
│ ├── namespace_texturize.html
│ ├── namespaces.html
│ ├── pages.html
│ ├── pca.svg
│ ├── readdata_8cpp-example.html
│ ├── search.js
│ ├── searchdata.js
│ ├── struct_texturize_1_1are__base__of.html
│ ├── struct_texturize_1_1are__base__of_3_01_base_00_01_t_01_4.html
│ ├── tutorial-filter.html
│ ├── tutorial-search-index.html
│ ├── tutorial-search-space.html
│ ├── tutorial-synthesizer.html
│ ├── tutorial.html
│ └── writedata_8cpp-example.html
├── images
│ ├── Coherence.svg
│ ├── DefaultConvergence.svg
│ ├── ImprovedConvergence.svg
│ └── PCA.svg
├── index.html
├── m-texturize+doxygen.compiled.css
├── texturize-mcss.cfg
├── texturize.cfg
├── tutorial-filter.dox
├── tutorial-search-index.dox
├── tutorial-search-space.dox
├── tutorial-synthesizer.dox
└── tutorial.dox
├── libs
├── Texturize.Analysis
│ ├── CMakeLists.txt
│ ├── Texturize.Analysis.props
│ ├── include
│ │ ├── analysis.hpp
│ │ ├── log2.h
│ │ └── sample.hpp
│ └── src
│ │ ├── AppearanceSpace.cpp
│ │ ├── DynamicThresholdFilter.cpp
│ │ ├── FeatureDistanceFilter.cpp
│ │ ├── FeatureExtractor.cpp
│ │ ├── FilterBank.cpp
│ │ ├── FilterCascade.cpp
│ │ ├── GaussianBlurFilter.cpp
│ │ ├── GrayscaleFilter.cpp
│ │ ├── HistogramExtractionFilter.cpp
│ │ ├── HistogramMatchingFilter.cpp
│ │ ├── ImagePyramid.cpp
│ │ ├── KMeansClusterFilter.cpp
│ │ ├── NormalizationFilter.cpp
│ │ ├── PerlinNoise.cpp
│ │ ├── PerlinNoise.h
│ │ ├── PerlinNoise2D.cpp
│ │ ├── Sample.cpp
│ │ ├── StructuredEdgeDetector.cpp
│ │ ├── analysis.cpp
│ │ ├── dllmain.cpp
│ │ ├── stdafx.cpp
│ │ ├── stdafx.h
│ │ └── targetver.h
├── Texturize.Codecs.EXR
│ ├── CMakeLists.txt
│ ├── Texturize.Codecs.EXR.props
│ ├── include
│ │ └── Codecs
│ │ │ └── exr.hpp
│ └── src
│ │ ├── ExrCodec.cpp
│ │ ├── Stream.hpp
│ │ ├── codecs.exr.cpp
│ │ ├── dllmain.cpp
│ │ ├── stdafx.cpp
│ │ ├── stdafx.h
│ │ └── targetver.h
├── Texturize.Codecs
│ ├── CMakeLists.txt
│ ├── Texturize.Codecs.props
│ ├── include
│ │ ├── codecs.hpp
│ │ └── filestorage.hpp
│ └── src
│ │ ├── AppearanceSpaceAsset.cpp
│ │ ├── DefaultCodec.cpp
│ │ ├── FileStorage.cpp
│ │ ├── FileStorageWrapper.cpp
│ │ ├── FunctionalAssetPersistence.cpp
│ │ ├── SamplePersistence.cpp
│ │ ├── StorageFactory.cpp
│ │ ├── codecs.cpp
│ │ ├── dllmain.cpp
│ │ ├── stdafx.cpp
│ │ ├── stdafx.h
│ │ └── targetver.h
├── Texturize.Core
│ ├── CMakeLists.txt
│ ├── MSG00409.bin
│ ├── Texturize.Core.props
│ ├── errors.h
│ ├── errors.rc
│ ├── include
│ │ ├── .gitignore
│ │ ├── error.hpp
│ │ ├── errors.mc
│ │ ├── events.hpp
│ │ ├── texturize.hpp
│ │ ├── traits.hpp
│ │ └── version.hpp.template
│ └── src
│ │ ├── dllmain.cpp
│ │ ├── exception.cpp
│ │ ├── stdafx.cpp
│ │ ├── stdafx.h
│ │ └── targetver.h
└── Texturize.Sampling
│ ├── CMakeLists.txt
│ ├── Texturize.Sampling.props
│ ├── include
│ └── sampling.hpp
│ └── src
│ ├── CoherentIndex.cpp
│ ├── CoordinateHash.cpp
│ ├── DescriptorExtractor.cpp
│ ├── FlannIndex.cpp
│ ├── PyramidSynthesizer.cpp
│ ├── RandomWalkIndex.cpp
│ ├── SearchIndex.cpp
│ ├── SynthesisSettings.cpp
│ ├── SynthesizerBase.cpp
│ ├── SynthesizerState.cpp
│ ├── dllmain.cpp
│ ├── sampling.cpp
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── targetver.h
├── models
├── License.txt
└── forest
│ ├── modelFinal.mat
│ ├── modelFinal.yml
│ └── modelFinal.yml.gz
└── modules
├── FindOpenEXR.cmake
├── FindTapkee.cmake
└── zlib
├── CMakeLists.txt
├── ChangeLog
├── FAQ
├── INDEX
├── Makefile
├── Makefile.in
├── README
├── adler32.c
├── compress.c
├── configure
├── crc32.c
├── crc32.h
├── deflate.c
├── deflate.h
├── gzclose.c
├── gzguts.h
├── gzlib.c
├── gzread.c
├── gzwrite.c
├── infback.c
├── inffast.c
├── inffast.h
├── inffixed.h
├── inflate.c
├── inflate.h
├── inftrees.c
├── inftrees.h
├── make_vms.com
├── treebuild.xml
├── trees.c
├── trees.h
├── uncompr.c
├── win32
├── DLL_FAQ.txt
├── Makefile.bor
├── Makefile.gcc
├── Makefile.msc
├── README-WIN32.txt
├── VisualC.txt
├── zlib.def
└── zlib1.rc
├── zconf.h.cmakein
├── zconf.h.in
├── zconf.h.included
├── zlib.3
├── zlib.3.pdf
├── zlib.h
├── zlib.map
├── zlib.pc.cmakein
├── zlib.pc.in
├── zlib2ansi
├── zutil.c
└── zutil.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # "modules" contains 3rd party libraries; "models" contains static files, that are not supposed to be scanned.
2 | modules/* linguist-vendored
3 | models/* linguist-vendored
4 |
5 | # "docs" contains the documentation.
6 | docs/* linguist-documentation
7 |
8 | # Special file types.
9 | *.h linguist-language=cpp
10 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Carsten Rudolph
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Texturize: A framework for example-based Texture Synthesis
2 |
3 | [Texturize](https://www.github.com/Aschratt/Texturize) is a framework, that has been created alongside my [master's thesis](https://github.com/Aschratt/Texturize-Thesis). Most of the researchers in the field of texture synthesis do either not provide any implementation samples or have abandoned their sources, so that they are no longer accessible. My motivation was to create a framework, that can be used as a starting point to implement different algorithms and make them comparable, without requiring to re-implement common principles. It provides a unified infrastructure, that allows to customize and mix various aspects of different synthesis algorithms. It follows a modular design that allows to build new modules or customize existing ones. Typical tasks of example-based texture synthesis have been carefully studied and generalized in order to construct a common workflow. That way, I was able to create a prototype synthesizer, that is capable of synthesizing materials for Physically Based Rendering (PBR) from low-resolution exemplars.
4 |
5 | The framework must not be confused with the [GIMP PlugIn of the same name](https://github.com/lmanul/gimp-texturize).
6 |
7 | ## What's it all about?
8 |
9 | In general, texture synthesis is a problem field, that researches algorithms, that can create images which are used to add detail to geometric surfaces in computer graphics. Those images are called *textures* and if they are not created by humans, they are called *synthetic textures*. There are two major areas in texture synthesis:
10 |
11 | - Procedural synthesizers are algorithms that form new textures from mathematical models.
12 | - Non-Parametric synthesizers take existing texture *exemplars* and aim to create new, visually similar textures with higher resolution.
13 |
14 | *Texturize* is a framework for non-parametric synthesizers. Those algorithms have applications in many different computer graphics problems. They are used in image editing (e.g. to fill "holes" or transfer style), video editing and others. When creating this framework, I focused on re-mixing existing textures, i.e. synthesizing new images, that look visually similar to the exemplar, but do not feature heavy repetitions. This can, for example, be used to cover geometric surfaces without visible tiling artifacts.
15 |
16 | If you want a more detailed introduction into texture synthesis, consider taking a look int my [thesis](https://github.com/Aschratt/Texturize-Thesis).
17 |
18 | ## Getting started
19 |
20 | Building a synthesizer is a process that involves multiple steps. For convenience, they are described in the [getting started guide](https://aschratt.github.io/Texturize/html/getting-started.html). A reference implementation, called *Sandbox*, is also provided. You can learn more about it in the [sandbox guide](https://aschratt.github.io/Texturize/html/getting-started-sandbox.html).
21 |
22 | ## Custom framework builds
23 |
24 | In case you want to include the framework into other applications, or require different versions of its dependencies, a custom build might be required. Please refer to [the building guide](https://aschratt.github.io/Texturize/html/getting-started-build.html) for more information.
25 |
26 | ## License
27 |
28 | The project is currently licensed under the MIT license. Please refer to the [COPYING](https://github.com/Aschratt/Texturize/blob/master/COPYING) file for more information.
--------------------------------------------------------------------------------
/Texturize.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))
6 |
7 |
8 | $(TexturizePath)\lib\$(Configuration)\;$(LibraryPath)
9 | $(TexturizePath)\include\;$(IncludePath)
10 |
11 |
12 |
13 | Texturize.Sampling.lib;Texturize.Analysis.lib;Texturize.Core.lib;Texturize.Codecs.lib;Texturize.Codecs.EXR.lib;%(AdditionalDependencies)
14 |
15 |
16 | xcopy /y /d "$(TexturizePath)\bin\$(Configuration)\*.dll" "$(OutDir)"
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-architect
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/include/Adapters/tapkee.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Disable C++17 compatibility warnings.
4 | #pragma warning( disable: 4267 4244 4996 )
5 | // Disable warnings about discarded nodiscard-return values.
6 | #pragma warning( disable: 4834 )
7 |
8 | #include
9 | #include
10 |
11 | // Single precision is enough for now.
12 | #define TAPKEE_CUSTOM_INTERNAL_NUMTYPE float
13 |
14 | #include
15 |
16 | #include
17 |
18 | namespace Texturize {
19 | namespace Tapkee {
20 |
21 | /// \defgroup tapkee Tapkee Adapter
22 | /// Contains different dimensionality reductors implemented in Tapkee.
23 | /// @{
24 |
25 | class TEXTURIZE_API PCADescriptorExtractor :
26 | public DescriptorExtractor {
27 | // IDescriptorExtractor
28 | public:
29 | cv::Mat calculateNeighborhoodDescriptors(const Sample& exemplar) const override;
30 | cv::Mat calculateNeighborhoodDescriptors(const Sample& exemplar, const cv::Mat& uv) const override;
31 | };
32 |
33 | class TEXTURIZE_API SNEDescriptorExtractor :
34 | public DescriptorExtractor {
35 | // IDescriptorExtractor
36 | public:
37 | cv::Mat calculateNeighborhoodDescriptors(const Sample& exemplar) const override;
38 | cv::Mat calculateNeighborhoodDescriptors(const Sample& exemplar, const cv::Mat& uv) const override;
39 | };
40 |
41 | class TEXTURIZE_API IDistanceMetric {
42 | public:
43 | // TODO: cost is actually optional.
44 | virtual float calculateDistance(const cv::Mat& lhs, const cv::Mat& rhs, const cv::Mat& cost) const = 0;
45 | };
46 |
47 | class TEXTURIZE_API EuclideanDistanceMetric :
48 | public IDistanceMetric {
49 | public:
50 | float calculateDistance(const cv::Mat& lhs, const cv::Mat& rhs, const cv::Mat& cost) const override;
51 | };
52 |
53 | class TEXTURIZE_API EarthMoversDistanceMetric :
54 | public IDistanceMetric {
55 | public:
56 | float calculateDistance(const cv::Mat& lhs, const cv::Mat& rhs, const cv::Mat& cost) const override;
57 | };
58 |
59 | class TEXTURIZE_API PairwiseDistanceExtractor {
60 | private:
61 | std::unique_ptr _distanceMetric;
62 |
63 | public:
64 | PairwiseDistanceExtractor() = delete;
65 | PairwiseDistanceExtractor(std::unique_ptr distanceMetric);
66 | virtual ~PairwiseDistanceExtractor() = default;
67 |
68 | public:
69 | cv::Mat computeDistances(const cv::Mat& sample) const;
70 | cv::Mat computeDistances(const std::vector& samples) const;
71 | tapkee::DenseSymmetricMatrix computeDistances(const cv::Mat& sample, std::vector& indices) const;
72 | tapkee::DenseSymmetricMatrix computeDistances(const std::vector& sample, std::vector& indices) const;
73 | };
74 |
75 | /// @}
76 | }
77 | }
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/DescriptorExtractor.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | using namespace Texturize;
11 |
12 | ///////////////////////////////////////////////////////////////////////////////////////////////////
13 | ///// PCA descriptor extractor implementation /////
14 | ///////////////////////////////////////////////////////////////////////////////////////////////////
15 |
16 | cv::Mat Tapkee::PCADescriptorExtractor::calculateNeighborhoodDescriptors(const Sample& exemplar) const
17 | {
18 | // Create a UV-Map for the sample.
19 | cv::Mat uv = this->createContinuousUvMap(exemplar);
20 |
21 | // Calculate the descriptors.
22 | return this->calculateNeighborhoodDescriptors(exemplar, uv);
23 | }
24 |
25 | cv::Mat Tapkee::PCADescriptorExtractor::calculateNeighborhoodDescriptors(const Sample& exemplar, const cv::Mat& uv) const
26 | {
27 | // Get the pixel neighborhoods and a buffer to store the projected pixels to.
28 | cv::Mat projected, neighborhoods = this->getPixelNeighborhoods(exemplar, uv);
29 |
30 | // Convert into an Eigen matrix.
31 | tapkee::DenseMatrix eigenNeighbors, embeddedResult;
32 | cv::cv2eigen(neighborhoods, eigenNeighbors);
33 |
34 | // Apply PCA.
35 | tapkee::ParametersSet parameters = tapkee::kwargs[
36 | tapkee::method = tapkee::PCA,
37 | tapkee::target_dimension = exemplar.channels()
38 | ];
39 |
40 | tapkee::TapkeeOutput result = tapkee::initialize()
41 | .withParameters(parameters)
42 | .embedUsing(eigenNeighbors);
43 |
44 | // Convert it back.
45 | cv::eigen2cv(result.embedding, projected);
46 |
47 | // Return the projected neighborhoods.
48 | TEXTURIZE_ASSERT(projected.cols == exemplar.channels());
49 |
50 | return projected;
51 | }
52 |
53 | ///////////////////////////////////////////////////////////////////////////////////////////////////
54 | ///// t-SNE descriptor extractor implementation /////
55 | ///////////////////////////////////////////////////////////////////////////////////////////////////
56 |
57 | cv::Mat Tapkee::SNEDescriptorExtractor::calculateNeighborhoodDescriptors(const Sample& exemplar) const
58 | {
59 | // Create a UV-Map for the sample.
60 | cv::Mat uv = this->createContinuousUvMap(exemplar);
61 |
62 | // Calculate the descriptors.
63 | return this->calculateNeighborhoodDescriptors(exemplar, uv);
64 | }
65 |
66 | cv::Mat Tapkee::SNEDescriptorExtractor::calculateNeighborhoodDescriptors(const Sample& exemplar, const cv::Mat& uv) const
67 | {
68 | // Get the pixel neighborhoods and a buffer to store the projected pixels to.
69 | cv::Mat projected, neighborhoods = this->getPixelNeighborhoods(exemplar, uv);
70 |
71 | // Convert into an Eigen matrix.
72 | tapkee::DenseMatrix eigenNeighbors;
73 | cv::cv2eigen(neighborhoods, eigenNeighbors);
74 |
75 | // Apply PCA.
76 | tapkee::ParametersSet parameters = tapkee::kwargs[
77 | tapkee::method = tapkee::tDistributedStochasticNeighborEmbedding,
78 | tapkee::target_dimension = exemplar.channels()
79 | ];
80 |
81 | tapkee::TapkeeOutput result = tapkee::initialize()
82 | .withParameters(parameters)
83 | .embedUsing(eigenNeighbors);
84 |
85 | // Convert it back.
86 | cv::eigen2cv(result.embedding, projected);
87 |
88 | // Return the projected neighborhoods.
89 | TEXTURIZE_ASSERT(projected.cols == exemplar.channels());
90 |
91 | return projected;
92 | }
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/DistanceMetrics.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 | using namespace Texturize::Tapkee;
7 |
8 | ///////////////////////////////////////////////////////////////////////////////////////////////////
9 | ///// Distance metric implementations. /////
10 | ///////////////////////////////////////////////////////////////////////////////////////////////////
11 |
12 | float EuclideanDistanceMetric::calculateDistance(const cv::Mat& lhs, const cv::Mat& rhs, const cv::Mat& cost) const
13 | {
14 | return static_cast(cv::norm(lhs, rhs, cv::NORM_L2));
15 | }
16 |
17 | float EarthMoversDistanceMetric::calculateDistance(const cv::Mat& lhs, const cv::Mat& rhs, const cv::Mat& cost) const
18 | {
19 | TEXTURIZE_ASSERT(lhs.channels() == 1 && rhs.channels() == 1); // Only single-channel descriptors are allowed.
20 | TEXTURIZE_ASSERT((lhs.cols == 1 || lhs.rows == 1) && (rhs.cols == 1 || rhs.rows == 1)); // The descriptors should be one-dimensional.
21 | TEXTURIZE_ASSERT(lhs.type() == CV_32F && rhs.type() == CV_32F); // Descriptors require types to be single-precision floatings point values.
22 |
23 | cv::Mat l = lhs.cols == 1 ? lhs.t() : lhs;
24 | cv::Mat r = rhs.cols == 1 ? rhs.t() : rhs;
25 |
26 | cv::Mat binIndices(1, lhs.cols, CV_32F);
27 |
28 | for (int bin(0); bin < lhs.cols; ++bin)
29 | binIndices.at(0, bin) = static_cast(bin);
30 |
31 | l.push_back(binIndices);
32 | r.push_back(binIndices);
33 |
34 | return static_cast(cv::EMD(l.t(), r.t(), cv::DIST_L2, cost));
35 | }
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/PairwiseDistanceExtractor.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | using namespace Texturize;
11 | using namespace Texturize::Tapkee;
12 |
13 | ///////////////////////////////////////////////////////////////////////////////////////////////////
14 | ///// Pairwise distance extractor. /////
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 |
17 | PairwiseDistanceExtractor::PairwiseDistanceExtractor(std::unique_ptr distanceMetric) :
18 | _distanceMetric(std::move(distanceMetric))
19 | {
20 | }
21 |
22 | cv::Mat PairwiseDistanceExtractor::computeDistances(const cv::Mat& sample) const
23 | {
24 | std::vector samples{ sample };
25 | return this->computeDistances(samples);
26 | }
27 |
28 | cv::Mat PairwiseDistanceExtractor::computeDistances(const std::vector& samples) const
29 | {
30 | TEXTURIZE_ASSERT(!samples.empty()); // The sample set must not be empty.
31 | size_t numFeatures = samples.front().rows;
32 |
33 | for each (const auto& sample in samples) {
34 | TEXTURIZE_ASSERT(sample.rows == numFeatures); // Each sample requires to contain the same number of feature descriptors.
35 | }
36 |
37 | // Create the distance matrix.
38 | cv::Mat distances = cv::Mat::zeros(numFeatures, numFeatures, CV_32FC1);
39 |
40 | for each (const auto& sample in samples) {
41 | // Calculate cost matrix for the current descriptor set.
42 | cv::Mat cost = cv::Mat::zeros(sample.cols, sample.cols, CV_32FC1);
43 |
44 | for (int x(0); x < static_cast(sample.channels()); ++x)
45 | for (int y(0); y < static_cast(sample.channels()); ++y)
46 | cost.at(x, y) = static_cast(abs(x - y));
47 |
48 | // Compute the distance matrix as a symmetric matrix of pairwise distances.
49 | // NOTE: The diagonal represents the distances between a feature with itself, thus it always reduces to 0.
50 | // TODO: This could run in parallel.
51 | tbb::parallel_for(tbb::blocked_range(0, numFeatures), [&numFeatures, &distances, &cost, &sample, this] (const tbb::blocked_range& range) {
52 | for (int x = range.begin(); x != range.end(); ++x) {
53 | const int _x{ x };
54 |
55 | tbb::parallel_for(tbb::blocked_range(_x + 1, numFeatures), [&distances, &_x, &cost, &sample, this] (const tbb::blocked_range& range) {
56 | for (int y = range.begin(); y != range.end(); ++y) {
57 | float distance = _distanceMetric->calculateDistance(sample.row(_x), sample.row(y), cost);
58 | distances.at(_x, y) += distance;
59 | distances.at(y, _x) += distance;
60 | }
61 | });
62 | }
63 | });
64 | }
65 |
66 | // Return the distances.
67 | return distances;
68 | }
69 |
70 | tapkee::DenseSymmetricMatrix PairwiseDistanceExtractor::computeDistances(const cv::Mat& sample, std::vector& indices) const
71 | {
72 | std::vector samples{ sample };
73 | return this->computeDistances(samples, indices);
74 | }
75 |
76 | tapkee::DenseSymmetricMatrix PairwiseDistanceExtractor::computeDistances(const std::vector& samples, std::vector& indices) const
77 | {
78 | // Compute the distances.
79 | cv::Mat distances = this->computeDistances(samples);
80 |
81 | TEXTURIZE_ASSERT(distances.rows == distances.cols); // The distance matrix is a symmetrical, diagonal matrix.
82 |
83 | // Convert to tapkee::DenseSymmetricMatrix.
84 | tapkee::DenseSymmetricMatrix eigenDistances(distances.rows, distances.cols);
85 | cv::cv2eigen(distances, eigenDistances);
86 |
87 | // Indices are linear.
88 | indices.resize(distances.rows);
89 |
90 | for (tapkee::IndexType idx(0); idx < indices.size(); ++idx)
91 | indices[idx] = idx;
92 |
93 | return eigenDistances;
94 | }
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/adapters.tapkee.cpp:
--------------------------------------------------------------------------------
1 | #include
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/dllmain.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
4 | {
5 | switch (reason)
6 | {
7 | case DLL_PROCESS_ATTACH:
8 | case DLL_THREAD_ATTACH:
9 | case DLL_THREAD_DETACH:
10 | case DLL_PROCESS_DETACH:
11 | break;
12 | }
13 | return TRUE;
14 | }
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #define WIN32_LEAN_AND_MEAN
6 |
7 | #include
8 | #include
9 | #include
--------------------------------------------------------------------------------
/adapters/Texturize.Adapters.Tapkee/src/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.AppearanceSpace/Texturize.AppearanceSpace.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | using namespace Texturize;
14 |
15 | // Command line parameter meta data.
16 | // NOTE: It's important to use spaces instead of tabstops here!
17 | const char* parameters =
18 | {
19 | "{h help usage ? | | Displays this help message.}"
20 | "{input in | | The name of an image file or a list of image files (seperated by \";\") that should be transformed into appearance space.}"
21 | "{result r | | The name of the image file, the result is stored to.}"
22 | "{dimensionality td | 8 | Resulting dimensionality of the result sample.}"
23 | };
24 |
25 | // Persistence providers.
26 | DefaultPersistence _persistence;
27 |
28 | template
29 | void calculateRetainedVariance(const cv::Mat& eigenValues, std::vector& variancePerDim) {
30 | TEXTURIZE_ASSERT(eigenValues.type() == cv::DataType::type);
31 | TEXTURIZE_ASSERT_DBG(variancePerDim.empty());
32 |
33 | // Create a matrix, containing the sum of eigen values.
34 | cv::Mat g = cv::Mat::zeros(eigenValues.size(), eigenValues.type());
35 |
36 | for (int i(0); i < g.rows; ++i)
37 | for (int j(0); j <= i; ++j)
38 | g.at(i, 0) += eigenValues.at(j, 0);
39 |
40 | // For each eigen value, compute the retained variance.
41 | variancePerDim.resize(eigenValues.rows);
42 |
43 | for (int v(0); v < eigenValues.rows; ++v)
44 | variancePerDim[v] = g.at(v, 0) / g.at(g.rows - 1, 0);
45 | }
46 |
47 | int main(int argc, const char** argv) {
48 | // Parse the command line.
49 | cv::CommandLineParser parser(argc, argv, parameters);
50 | parser.about(cv::format("Texturize %d.%d -- Appearance Space Transform", TEXTURIZE_VER_MAJOR, TEXTURIZE_VER_MINOR));
51 |
52 | if (parser.has("help") || argc == 1)
53 | {
54 | parser.printMessage();
55 | return 0;
56 | }
57 |
58 | if (!parser.check())
59 | {
60 | parser.printErrors();
61 | return EXIT_FAILURE;
62 | }
63 |
64 | // Register EXR codec.
65 | _persistence.registerCodec("txr", std::make_unique());
66 |
67 | // Print parameters.
68 | std::string inputFileNames = parser.get("input");
69 | std::string resultFileName = parser.get("result");
70 | size_t dimensionality = parser.get("dimensionality");
71 |
72 | // Get the individual input file names.
73 | std::vector inputFiles;
74 | std::istringstream tokens(inputFileNames);
75 | std::string token;
76 |
77 | while (std::getline(tokens, token, ';'))
78 | {
79 | if (token.empty())
80 | continue;
81 |
82 | inputFiles.push_back(token);
83 | }
84 |
85 | for (size_t file(0); file < inputFiles.size(); ++file)
86 | std::cout << "Input [" << file + 1 << "/" << inputFiles.size() << "]: " << inputFiles[file] << std::endl;
87 |
88 | std::cout << "Output: " << resultFileName << std::endl << std::endl;
89 |
90 | // Load all input samples into one sample.
91 | std::vector inputSamples;
92 |
93 | for each (auto& fileName in inputFiles)
94 | {
95 | Sample sample;
96 | _persistence.loadSample(fileName, sample);
97 | inputSamples.push_back(sample);
98 | }
99 |
100 | Sample material = Sample::mergeSamples(std::initializer_list(inputSamples.data(), inputSamples.data() + inputSamples.size()));
101 |
102 | // The "exemplar" now contains all descriptive channels that are used to calculate the appearance space.
103 | std::unique_ptr dscr;
104 | std::cout << "Computing appearance space descriptors...";
105 | auto start = std::chrono::high_resolution_clock::now();
106 | AppearanceSpace::calculate(material, dscr, dimensionality);
107 | auto end = std::chrono::high_resolution_clock::now();
108 | std::cout << " Done! (" << std::chrono::duration_cast(end - start).count() << "ms)" << std::endl;
109 |
110 | // Save the asset.
111 | AppearanceSpaceAsset asset;
112 | std::shared_ptr descriptor{ std::move(dscr) };
113 | asset.write(resultFileName, descriptor);
114 |
115 | // Print some statistics.
116 | // NOTE: Only works on CV_32F currently.
117 | std::shared_ptr projector;
118 | descriptor->getProjector(projector);
119 |
120 | std::vector variances;
121 | ::calculateRetainedVariance(projector->eigenvalues, variances);
122 |
123 | std::cout << "Retained variances in " << variances.size() << " dimensions:" << std::endl;
124 |
125 | for (std::vector::size_type s(0); s < variances.size(); ++s)
126 | std::cout << s << ": " << variances[s] << std::endl;
127 | }
--------------------------------------------------------------------------------
/apps/Texturize.AppearanceSpace/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.AppearanceSpace/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.AppearanceSpace/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.Distance/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.Distance/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.Distance/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.FilterMR8/Texturize.FilterMR8.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | using namespace Texturize;
14 |
15 | // Command line parameter meta data.
16 | // NOTE: It's important to use spaces instead of tabstops here!
17 | const char* parameters =
18 | {
19 | "{h help usage ? | | Displays this help message.}"
20 | "{input in | | The name of an image (RGB or grey) file that should be filtered.}"
21 | "{result r | | The name of the image file, the result is stored to.}"
22 | "{ksize k kernel | 7 | The size of the filter kernel window (must be odd).}"
23 | };
24 |
25 | // Persistence providers.
26 | DefaultPersistence _persistence;
27 |
28 | int main(int argc, const char** argv) {
29 | // Parse the command line.
30 | cv::CommandLineParser parser(argc, argv, parameters);
31 | parser.about(cv::format("Texturize %d.%d -- MR8 Filter Bank", TEXTURIZE_VER_MAJOR, TEXTURIZE_VER_MINOR));
32 |
33 | if (parser.has("help") || argc == 1)
34 | {
35 | parser.printMessage();
36 | return 0;
37 | }
38 |
39 | if (!parser.check())
40 | {
41 | parser.printErrors();
42 | return EXIT_FAILURE;
43 | }
44 |
45 | // Register EXR codec.
46 | _persistence.registerCodec("txr", std::make_unique());
47 |
48 | // Print parameters.
49 | std::string inputFileName = parser.get("input");
50 | std::string resultFileName = parser.get("result");
51 | int ksize = parser.get("ksize");
52 |
53 | std::cout << "Input: " << inputFileName << std::endl <<
54 | "Output: " << resultFileName << std::endl <<
55 | "Kernel: " << ksize << "*" << ksize << " Pixels" << std::endl <<
56 | std::endl;
57 |
58 | // Load the input sample.
59 | Sample sample;
60 | _persistence.loadSample(inputFileName, sample);
61 |
62 | // In case the sample is colored, convert it to greyscale.
63 | if (sample.channels() == 3 || sample.channels() == 4)
64 | {
65 | cv::Mat greyscale;
66 | cv::cvtColor((cv::Mat)sample, greyscale, cv::COLOR_RGB2GRAY);
67 | sample = Sample(greyscale);
68 | }
69 | else if (sample.channels() != 1)
70 | {
71 | std::cout << "The input sample has " << sample.channels() << " channels and cannot be converted to greyscale. Please convert the sample manually or provide an RGB color image instead." << std::endl;
72 | return EXIT_FAILURE;
73 | }
74 |
75 | // Create a filter bank instance.
76 | MaxResponseFilterBank filterBank(ksize);
77 |
78 | // Filter the sample.
79 | std::cout << "Executing... ";
80 | Sample result;
81 | auto start = std::chrono::high_resolution_clock::now();
82 | filterBank.apply(result, sample);
83 | auto end = std::chrono::high_resolution_clock::now();
84 | std::cout << " Done! (" << std::chrono::duration_cast(end - start).count() << "ms)" << std::endl;
85 |
86 | // Store the sample.
87 | _persistence.saveSample(resultFileName, result);
88 | }
--------------------------------------------------------------------------------
/apps/Texturize.FilterMR8/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.FilterMR8/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.FilterMR8/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.GuidanceRefine/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.GuidanceRefine/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.GuidanceRefine/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.KMeans/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ###################################################################################################
2 | ##### #####
3 | ##### Clusters an n-dimensional sample using k means clustering. #####
4 | ##### #####
5 | ###################################################################################################
6 |
7 | CMAKE_MINIMUM_REQUIRED(VERSION 3.12 FATAL_ERROR)
8 | SET(PROJECT_NAME Texturize.KMeans)
9 | PROJECT(${PROJECT_NAME} CXX)
10 | SET(CONFIG_NAME ${PROJECT_NAME}Config)
11 |
12 | MESSAGE(STATUS "---------------------------------------------------------------------------------------------------")
13 | MESSAGE(STATUS "")
14 | MESSAGE(STATUS "Setting up project: ${PROJECT_NAME}...")
15 |
16 | # Set compiler flags
17 | IF(MSVC)
18 | # Switch from Multi-Thread (/MT) to Multi-Thread Debug (/MTd) for debug builds.
19 | #SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
20 | #SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
21 |
22 | # NOTE: While the above should be correct for executables, there will be heap corruption errors
23 | # in debug mode, so we leave this on /MD(d) for now.
24 | SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
25 | SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
26 | ENDIF(MSVC)
27 |
28 | # Specify source folders, relative to the project sources directory.
29 | SET(INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include")
30 | SET(SOURCES_DIR "${PROJECT_SOURCE_DIR}/src")
31 |
32 | MESSAGE(STATUS " Include directory: ${INCLUDE_DIR}")
33 | MESSAGE(STATUS " Source directory: ${SOURCES_DIR}")
34 | MESSAGE(STATUS "")
35 |
36 | ###################################################################################################
37 | ##### Build type specific preprocessor definitions. #####
38 | ###################################################################################################
39 |
40 | ADD_DEFINITIONS(
41 | -DTEXTURIZE_EXPORTS
42 | -D_WINDOWS
43 | -D_USRDLL
44 | -DUNICODE
45 | -D_UNICODE
46 | )
47 |
48 | ADD_DEFINITIONS(-D_USE_MATH_DEFINES)
49 |
50 | ###################################################################################################
51 | ##### Define build output. #####
52 | ###################################################################################################
53 |
54 | # Set header directories.
55 | LIST(APPEND INCLUDE_DIR
56 | ${TXTRZ_SAMPLING_INCLUDE_DIRS}
57 | ${TXTRZ_CODECS_INCLUDE_DIRS}
58 | ${TXTRZ_CODECS_EXR_INCLUDE_DIRS}
59 | )
60 |
61 | SET(MODULE_INCLUDES)
62 |
63 | IF(WITH_TAPKEE)
64 | LIST(APPEND MODULE_INCLUDES ${TXTRZ_ADAPTERS_TAPKEE_INCLUDE_DIRS})
65 | ENDIF(WITH_TAPKEE)
66 |
67 | INCLUDE_DIRECTORIES(
68 | ${INCLUDE_DIR}
69 | SYSTEM ${MODULE_INCLUDES}
70 | )
71 |
72 | FILE(GLOB SRC_FILES
73 | ${SOURCES_DIR}/*.cpp
74 | ${INCLUDE_DIR}/*.hpp
75 | ${PROJECT_DIR}/*.h
76 | ${PROJECT_DIR}/*.cpp
77 | )
78 |
79 | # Make the project an executable.
80 | ADD_EXECUTABLE(${PROJECT_NAME} Texturize.KMeans.cpp ${SRC_FILES})
81 |
82 | # Append "_d" to artifact names for debug builds.
83 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ".Dbg")
84 |
85 | # Setup target dependencies.
86 | LIST(APPEND LINK_LIBS Texturize.Sampling Texturize.Codecs.EXR)
87 |
88 | IF(WITH_TAPKEE)
89 | LIST(APPEND LINK_LIBS Texturize.Adapters.Tapkee)
90 | ENDIF(WITH_TAPKEE)
91 |
92 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} "${LINK_LIBS}")
93 |
94 | # Setup target includes.
95 | TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
96 | PUBLIC ${INCLUDE_DIR} $
97 | PRIVATE ${SOURCES_DIR}
98 | )
99 |
100 | ###################################################################################################
101 | ##### Define installer image. #####
102 | ###################################################################################################
103 | INSTALL(TARGETS ${PROJECT_NAME} EXPORT ${CONFIG_NAME}
104 | ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
105 | LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
106 | RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
107 | )
108 |
109 | # Install ressources.
110 | INSTALL(
111 | CODE "file( GLOB MODEL_FILES \"${CMAKE_SOURCE_DIR}/models\" )"
112 | CODE "file( INSTALL \${MODEL_FILES} DESTINATION \"${CMAKE_INSTALL_PREFIX}\" )"
113 | CODE "file( INSTALL \"${CMAKE_SOURCE_DIR}/Texturize.props\" DESTINATION \"${CMAKE_INSTALL_PREFIX}\" )"
114 | )
115 |
116 | ###################################################################################################
117 | ##### Define export package. #####
118 | ###################################################################################################
119 | EXPORT(TARGETS ${PROJECT_NAME} FILE ${CONFIG_NAME}.cmake)
--------------------------------------------------------------------------------
/apps/Texturize.KMeans/Texturize.KMeans.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | using namespace Texturize;
14 |
15 | // Command line parameter meta data.
16 | // NOTE: It's important to use spaces instead of tabstops here!
17 | const char* parameters =
18 | {
19 | "{h help usage ? | | Displays this help message.}"
20 | "{input in | | The name of an image file or a list of image files (seperated by \";\") that should be clustered.}"
21 | "{result r | | The name of the image file, the result is stored to.}"
22 | "{bins clusters b c | 64 | The number of clusters in the result.}"
23 | "{iterations i | 10 | The number of iterations executed to find an optimal solution.}"
24 | };
25 |
26 | // Persistence providers.
27 | DefaultPersistence _persistence;
28 |
29 | int main(int argc, const char** argv) {
30 | // Parse the command line.
31 | cv::CommandLineParser parser(argc, argv, parameters);
32 | parser.about(cv::format("Texturize %d.%d -- k-means Clustering", TEXTURIZE_VER_MAJOR, TEXTURIZE_VER_MINOR));
33 |
34 | if (parser.has("help") || argc == 1)
35 | {
36 | parser.printMessage();
37 | return 0;
38 | }
39 |
40 | if (!parser.check())
41 | {
42 | parser.printErrors();
43 | return EXIT_FAILURE;
44 | }
45 |
46 | // Register EXR codec.
47 | _persistence.registerCodec("txr", std::make_unique());
48 |
49 | // Parse parameters.
50 | std::string inputFileNames = parser.get("input");
51 | std::string resultFileName = parser.get("result");
52 | int clusters = parser.get("bins");
53 | int iterations = parser.get("iterations");
54 |
55 | // Get the individual input file names.
56 | std::vector inputFiles;
57 | std::istringstream tokens(inputFileNames);
58 | std::string token;
59 |
60 | while (std::getline(tokens, token, ';'))
61 | {
62 | if (token.empty())
63 | continue;
64 |
65 | inputFiles.push_back(token);
66 | }
67 |
68 | for (size_t file(0); file < inputFiles.size(); ++file)
69 | std::cout << "Input [" << file + 1 << "/" << inputFiles.size() << "]: " << inputFiles[file] << std::endl;
70 |
71 | std::cout << "Output: " << resultFileName << std::endl <<
72 | "Clusters: " << clusters << std::endl <<
73 | "Iterations: " << iterations << std::endl <<
74 | std::endl;
75 |
76 | // Load all input samples into one sample.
77 | std::vector inputSamples;
78 |
79 | for each (auto& fileName in inputFiles)
80 | {
81 | Sample sample;
82 | _persistence.loadSample(fileName, sample);
83 | inputSamples.push_back(sample);
84 | }
85 |
86 | Sample material = Sample::mergeSamples(std::initializer_list(inputSamples.data(), inputSamples.data() + inputSamples.size()));
87 |
88 | // Cluster the material.
89 | Sample result;
90 | KMeansClusterFilter filter(clusters, iterations);
91 |
92 | auto start = std::chrono::high_resolution_clock::now();
93 | filter.apply(result, material);
94 | auto end = std::chrono::high_resolution_clock::now();
95 | std::cout << " Done! (" << std::chrono::duration_cast(end - start).count() << "ms)" << std::endl;
96 |
97 | // Store the sample.
98 | _persistence.saveSample(resultFileName, result);
99 | }
--------------------------------------------------------------------------------
/apps/Texturize.KMeans/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.KMeans/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.KMeans/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.ProgressionMap/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.ProgressionMap/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.ProgressionMap/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.Sandbox/gaussianpdf.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | template
4 | T normalDistSym(T l, T extent, T alpha)
5 | {
6 | T sigma = extent * T(0.5);
7 | T a = (l - alpha) / (sigma / T(3.0));
8 | return std::exp(-T(0.5) * a * a);
9 | }
10 |
11 | template
12 | T normalDistAssym(T l, T extent, T alpha)
13 | {
14 | T sigma = l < alpha ? alpha : extent - alpha;
15 | T a = (l - alpha) / (sigma / T(3.0));
16 | return std::exp(-T(0.5) * a * a);
17 | }
--------------------------------------------------------------------------------
/apps/Texturize.Sandbox/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.Sandbox/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.Sandbox/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.Synthesize/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.Synthesize/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.Synthesize/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/apps/Texturize.UVMap/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ###################################################################################################
2 | ##### #####
3 | ##### Clusters an n-dimensional sample using k means clustering. #####
4 | ##### #####
5 | ###################################################################################################
6 |
7 | CMAKE_MINIMUM_REQUIRED(VERSION 3.12 FATAL_ERROR)
8 | SET(PROJECT_NAME Texturize.UVMap)
9 | PROJECT(${PROJECT_NAME} CXX)
10 | SET(CONFIG_NAME ${PROJECT_NAME}Config)
11 |
12 | MESSAGE(STATUS "---------------------------------------------------------------------------------------------------")
13 | MESSAGE(STATUS "")
14 | MESSAGE(STATUS "Setting up project: ${PROJECT_NAME}...")
15 |
16 | # Set compiler flags
17 | IF(MSVC)
18 | # Switch from Multi-Thread (/MT) to Multi-Thread Debug (/MTd) for debug builds.
19 | #SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
20 | #SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
21 |
22 | # NOTE: While the above should be correct for executables, there will be heap corruption errors
23 | # in debug mode, so we leave this on /MD(d) for now.
24 | SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
25 | SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
26 | ENDIF(MSVC)
27 |
28 | # Specify source folders, relative to the project sources directory.
29 | SET(INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include")
30 | SET(SOURCES_DIR "${PROJECT_SOURCE_DIR}/src")
31 |
32 | MESSAGE(STATUS " Include directory: ${INCLUDE_DIR}")
33 | MESSAGE(STATUS " Source directory: ${SOURCES_DIR}")
34 | MESSAGE(STATUS "")
35 |
36 | ###################################################################################################
37 | ##### Build type specific preprocessor definitions. #####
38 | ###################################################################################################
39 |
40 | ADD_DEFINITIONS(
41 | -DTEXTURIZE_EXPORTS
42 | -D_WINDOWS
43 | -D_USRDLL
44 | -DUNICODE
45 | -D_UNICODE
46 | )
47 |
48 | ADD_DEFINITIONS(-D_USE_MATH_DEFINES)
49 |
50 | ###################################################################################################
51 | ##### Define build output. #####
52 | ###################################################################################################
53 |
54 | # Set header directories.
55 | LIST(APPEND INCLUDE_DIR
56 | ${TXTRZ_SAMPLING_INCLUDE_DIRS}
57 | ${TXTRZ_CODECS_INCLUDE_DIRS}
58 | ${TXTRZ_CODECS_EXR_INCLUDE_DIRS}
59 | )
60 |
61 | SET(MODULE_INCLUDES)
62 |
63 | IF(WITH_TAPKEE)
64 | LIST(APPEND MODULE_INCLUDES ${TXTRZ_ADAPTERS_TAPKEE_INCLUDE_DIRS})
65 | ENDIF(WITH_TAPKEE)
66 |
67 | INCLUDE_DIRECTORIES(
68 | ${INCLUDE_DIR}
69 | SYSTEM ${MODULE_INCLUDES}
70 | )
71 |
72 | FILE(GLOB SRC_FILES
73 | ${SOURCES_DIR}/*.cpp
74 | ${INCLUDE_DIR}/*.hpp
75 | ${PROJECT_DIR}/*.h
76 | ${PROJECT_DIR}/*.cpp
77 | )
78 |
79 | # Make the project an executable.
80 | ADD_EXECUTABLE(${PROJECT_NAME} Texturize.UVMap.cpp ${SRC_FILES})
81 |
82 | # Append "_d" to artifact names for debug builds.
83 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ".Dbg")
84 |
85 | # Setup target dependencies.
86 | LIST(APPEND LINK_LIBS Texturize.Sampling Texturize.Codecs.EXR)
87 |
88 | IF(WITH_TAPKEE)
89 | LIST(APPEND LINK_LIBS Texturize.Adapters.Tapkee)
90 | ENDIF(WITH_TAPKEE)
91 |
92 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} "${LINK_LIBS}")
93 |
94 | # Setup target includes.
95 | TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
96 | PUBLIC ${INCLUDE_DIR} $
97 | PRIVATE ${SOURCES_DIR}
98 | )
99 |
100 | ###################################################################################################
101 | ##### Define installer image. #####
102 | ###################################################################################################
103 | INSTALL(TARGETS ${PROJECT_NAME} EXPORT ${CONFIG_NAME}
104 | ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
105 | LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
106 | RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
107 | )
108 |
109 | # Install ressources.
110 | INSTALL(
111 | CODE "file( GLOB MODEL_FILES \"${CMAKE_SOURCE_DIR}/models\" )"
112 | CODE "file( INSTALL \${MODEL_FILES} DESTINATION \"${CMAKE_INSTALL_PREFIX}\" )"
113 | CODE "file( INSTALL \"${CMAKE_SOURCE_DIR}/Texturize.props\" DESTINATION \"${CMAKE_INSTALL_PREFIX}\" )"
114 | )
115 |
116 | ###################################################################################################
117 | ##### Define export package. #####
118 | ###################################################################################################
119 | EXPORT(TARGETS ${PROJECT_NAME} FILE ${CONFIG_NAME}.cmake)
--------------------------------------------------------------------------------
/apps/Texturize.UVMap/Texturize.UVMap.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | using namespace Texturize;
14 |
15 | // Command line parameter meta data.
16 | // NOTE: It's important to use spaces instead of tabstops here!
17 | const char* parameters =
18 | {
19 | "{h help usage ? | | Displays this help message.}"
20 | "{input in | | The name of an image file that should be remapped.}"
21 | "{uvmap uv | | The name of an image file that contains the uv map that is used to remap the input.}"
22 | "{result r | | The name of the image file, the result is stored to.}"
23 | };
24 |
25 | // Persistence providers.
26 | DefaultPersistence _persistence;
27 |
28 | int main(int argc, const char** argv) {
29 | // Parse the command line.
30 | cv::CommandLineParser parser(argc, argv, parameters);
31 | parser.about(cv::format("Texturize %d.%d -- UV Remapping", TEXTURIZE_VER_MAJOR, TEXTURIZE_VER_MINOR));
32 |
33 | if (parser.has("help") || argc == 1)
34 | {
35 | parser.printMessage();
36 | return 0;
37 | }
38 |
39 | if (!parser.check())
40 | {
41 | parser.printErrors();
42 | return EXIT_FAILURE;
43 | }
44 |
45 | // Register EXR codec.
46 | _persistence.registerCodec("txr", std::make_unique());
47 |
48 | // Parse parameters.
49 | std::string inputFileName = parser.get("input");
50 | std::string uvMapFileName = parser.get("uvmap");
51 | std::string resultFileName = parser.get("result");
52 |
53 | std::cout << "Input: " << inputFileName << std::endl <<
54 | "UV-Map: " << uvMapFileName << std::endl <<
55 | "Output: " << resultFileName << std::endl <<
56 | std::endl;
57 |
58 | // Load the input sample and uv map.
59 | Sample sample, uvMap, result;
60 | _persistence.loadSample(inputFileName, sample);
61 | _persistence.loadSample(uvMapFileName, uvMap);
62 |
63 | if (uvMap.channels() != 2) {
64 | std::cout << "Warning: The uv map should contain only 2 channels. Additional channels are ignored." << std::endl;
65 |
66 | Sample remapped(2, uvMap.width(), uvMap.height());
67 | remapped.map({ 2, 0, 1, 1 }, uvMap);
68 | uvMap = remapped;
69 | }
70 |
71 | // Remap the input sample.
72 | sample.sample((cv::Mat)uvMap, result);
73 |
74 | // Store the sample.
75 | _persistence.saveSample(resultFileName, result);
76 | }
--------------------------------------------------------------------------------
/apps/Texturize.UVMap/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/apps/Texturize.UVMap/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #include
6 | #include
7 | #include
--------------------------------------------------------------------------------
/apps/Texturize.UVMap/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/cmake.ps1:
--------------------------------------------------------------------------------
1 | # Script parameters.
2 | Param(
3 | [String]$installTo = "install/", # Relative path (CMAKE_INSTALL_PREFIX)
4 | [String]$buildTo = "", # Relative path to source directory
5 | [String]$OpenCV,
6 | [String]$OpenEXR,
7 | [String]$TBB,
8 | [String]$HDF5,
9 | [String]$config = "Release",
10 | [Boolean]$x64 = $true,
11 | [Boolean]$verbose = $false,
12 | [String]$logFile = "",
13 | [String]$options = "" # CMake options (i.e. --debug-output or --trace[-expand])
14 | )
15 |
16 | # Build up a command to invoke.
17 | $invoke = "cmake CMakeLists.txt "
18 |
19 | if (![String]::IsNullOrEmpty($buildTo)) {
20 | $invoke += "-B`"$($buildTo)`" "
21 | }
22 |
23 | $invoke += "-DCMAKE_BUILD_TYPE=`"$($config)`" "
24 |
25 | if ($x64) {
26 | $invoke += "-G `"Visual Studio 15 2017 Win64`" "
27 | } else {
28 | $invoke += "-G `"Visual Studio 15 2017`" "
29 | }
30 |
31 | if (![String]::IsNullOrEmpty($installTo)) {
32 | $invoke += "-DCMAKE_INSTALL_PREFIX:STRING=`"$($installTo)`" "
33 | }
34 |
35 | if (![String]::IsNullOrEmpty($OpenCV)) {
36 | $invoke += "-DOpenCV_DIR:STRING=`"$($OpenCV)`" "
37 | }
38 |
39 | if (![String]::IsNullOrEmpty($OpenEXR)) {
40 | $invoke += "-DOPENEXR_LOCATION:STRING=`"$($OpenEXR)`" "
41 | }
42 |
43 | if (![String]::IsNullOrEmpty($TBB)) {
44 | $invoke += "-DTBB_DIR:STRING=`"$($TBB)`" "
45 | }
46 |
47 | if (![String]::IsNullOrEmpty($HDF5)) {
48 | $invoke += "-DHDF5_ROOT:STRING=`"$($HDF5)`" "
49 | }
50 |
51 | if ($verbose) {
52 | $invoke += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON "
53 | }
54 |
55 | $invoke += "$($options) "
56 |
57 | Write-Host "Invoking $($invoke)..."
58 | if (![String]::IsNullOrEmpty($logFile)) {
59 | Invoke-Expression $invoke | Tee-Object -FilePath $logFile
60 | } else {
61 | Invoke-Expression $invoke
62 | }
--------------------------------------------------------------------------------
/cmake/DefineApp.cmake:
--------------------------------------------------------------------------------
1 | ###################################################################################################
2 | ##### #####
3 | ##### Call this function in order to add an application depending on a cache option. #####
4 | ##### #####
5 | ##### Syntax example: #####
6 | ##### > OPTION(BUILD_APP "My App" ON) #####
7 | ##### > DEFINE_APP(BUILD_APP "app/MyApp") #####
8 | ##### #####
9 | ###################################################################################################
10 |
11 | FUNCTION(DEFINE_APP OPTION_NAME APP_DIRECTORY)
12 | IF(${OPTION_NAME})
13 | MESSAGE(STATUS "Adding app at '${APP_DIRECTORY}'...")
14 | ADD_SUBDIRECTORY(${APP_DIRECTORY})
15 | ELSE(${OPTION_NAME})
16 | MESSAGE(STATUS "Skipping app at '${APP_DIRECTORY}'.")
17 | ENDIF(${OPTION_NAME})
18 | ENDFUNCTION(DEFINE_APP OPTION_NAME APP_DIRECTORY)
--------------------------------------------------------------------------------
/cmake/GetPackageInfo.cmake:
--------------------------------------------------------------------------------
1 | ###################################################################################################
2 | ##### #####
3 | ##### Call this function after a package has been found by CMake's FIND_PACKAGE in order to #####
4 | ##### extract the include directories and binary names for the package. #####
5 | ##### #####
6 | ##### Syntax example: #####
7 | ##### > SET(MODULE_INCLUDES) #####
8 | ##### > SET(MODULE_BINARIES) #####
9 | ##### > LIST(APPEND MODULE_NAMES LibFoo LibBar) #####
10 | ##### > GET_PACKAGE_INFO("${MODULE_NAMES}" MODULE_INCLUDES MODULE_BINARIES) #####
11 | ##### #####
12 | ##### In the example above, the MODULE_INCLUDES will contain a list of include directories, #####
13 | ##### one for each module provided in MODULE_NAMES. MODULE_BINARIES will contain the imported #####
14 | ##### library locations. #####
15 | ##### #####
16 | ###################################################################################################
17 |
18 | FUNCTION(GET_PACKAGE_INFO ARG_MODULE_NAMES RET_INCLUDES RET_INSTALLER)
19 | SET(_INCLUDES "")
20 | SET(_BINARIES "")
21 |
22 | # Iterate each found module.
23 | FOREACH(_MODULE ${ARG_MODULE_NAMES})
24 | GET_PROPERTY(${_MODULE}_IMPORTED TARGET ${_MODULE} PROPERTY IMPORTED)
25 |
26 | # Check, if the library is imported.
27 | IF(NOT ${_MODULE}_IMPORTED)
28 | MESSAGE(WARNING " WARNING: The module ${_MODULE} is expected to be imported, but seems to be part of the build. \
29 | It will be skipped, which may corrupt your build!")
30 | ELSE(NOT ${_MODULE}_IMPORTED)
31 | # Get the include directories of the module.
32 | GET_PROPERTY(${_MODULE}_INCLUDE_DIRECTORIES TARGET ${_MODULE} PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
33 | MESSAGE(STATUS " [${_MODULE}] includes: ${${_MODULE}_INCLUDE_DIRECTORIES}")
34 | LIST(APPEND _INCLUDES ${${_MODULE}_INCLUDE_DIRECTORIES})
35 |
36 | # Check the module type.
37 | GET_PROPERTY(${_MODULE}_TYPE TARGET ${_MODULE} PROPERTY TYPE)
38 | #MESSAGE(STATUS " [${_MODULE}] TYPE: ${${_MODULE}_TYPE}")
39 |
40 | IF(NOT "${${_MODULE}_TYPE}" STREQUAL "INTERFACE_LIBRARY")
41 | # Resolve the assembly directories of the module.
42 | GET_PROPERTY(${_MODULE}_IMPORTED_LOCATION TARGET ${_MODULE} PROPERTY IMPORTED_LOCATION)
43 |
44 | # If there is no imported assembly, try again by importing for a current configuration.
45 | IF("${${_MODULE}_IMPORTED_LOCATION}" STREQUAL "")
46 | GET_PROPERTY(${_MODULE}_IMPORTED_LOCATION TARGET ${_MODULE} PROPERTY IMPORTED_LOCATION_${BUILD_TYPE})
47 | ENDIF("${${_MODULE}_IMPORTED_LOCATION}" STREQUAL "")
48 |
49 | # If there is still no imported assembly, try yet another time by importing for a mapped configuration.
50 | IF("${${_MODULE}_IMPORTED_LOCATION}" STREQUAL "")
51 | IF(${BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${BUILD_TYPE} STREQUAL "MINSIZEREL")
52 | SET(_BUILD_TYPE "RELEASE")
53 | ELSE(${BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${BUILD_TYPE} STREQUAL "MINSIZEREL")
54 | SET(_BUILD_TYPE "DEBUG")
55 | ENDIF(${BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${BUILD_TYPE} STREQUAL "MINSIZEREL")
56 |
57 | GET_PROPERTY(${_MODULE}_IMPORTED_LOCATION TARGET ${_MODULE} PROPERTY IMPORTED_LOCATION_${_BUILD_TYPE})
58 | ENDIF("${${_MODULE}_IMPORTED_LOCATION}" STREQUAL "")
59 |
60 | # If an assembly has been found, add it to the install list.
61 | IF(NOT "${${_MODULE}_IMPORTED_LOCATION}" STREQUAL "")
62 | MESSAGE(STATUS " [${_MODULE}] assemblies: ${${_MODULE}_IMPORTED_LOCATION}")
63 | LIST(APPEND _BINARIES ${${_MODULE}_IMPORTED_LOCATION})
64 | ELSE(NOT "${${_MODULE}_IMPORTED_LOCATION}" STREQUAL "")
65 | MESSAGE(STATUS " [${_MODULE}] assemblies: -")
66 | ENDIF(NOT "${${_MODULE}_IMPORTED_LOCATION}" STREQUAL "")
67 | ENDIF(NOT "${${_MODULE}_TYPE}" STREQUAL "INTERFACE_LIBRARY")
68 | ENDIF(NOT ${_MODULE}_IMPORTED)
69 | ENDFOREACH(_MODULE ${MODULE_NAMES})
70 |
71 | # Propagate variables to parent scope.
72 | SET(${RET_INCLUDES} ${_INCLUDES} PARENT_SCOPE)
73 | SET(${RET_INSTALLER} ${_BINARIES} PARENT_SCOPE)
74 | ENDFUNCTION(GET_PACKAGE_INFO ARG_MODULE_NAMES RET_INCLUDES RET_INSTALLER)
--------------------------------------------------------------------------------
/cmake/TexturizeSettings.cmake:
--------------------------------------------------------------------------------
1 | ###################################################################################################
2 | ##### #####
3 | ##### Default value definitions for CMake build options. #####
4 | ##### #####
5 | ###################################################################################################
6 |
7 | OPTION(BUILD_ZLIB "Include zlib in the build. You may disable this option if you provide zlib on your own." ON)
8 | OPTION(WITH_TAPKEE "Build advanced dimensionality reductors based on tapkee." ON)
9 |
10 | OPTION(BUILD_APP_SANDBOX "Builds the sandbox app." OFF)
11 | OPTION(BUILD_APP_FILTERMR8 "Builds MR8 filter bank app." ON)
12 | OPTION(BUILD_APP_KMEANS "Builds k-means clustering app." ON)
13 | OPTION(BUILD_APP_DISTANCE_MATRIX "Builds app that computes pairwise distances." ON)
14 | OPTION(BUILD_APP_PROGRESSION_MAP "Builds scalar progression map generation app." ON)
15 | OPTION(BUILD_APP_GUIDANCE_REFINE "Builds app for target guidance refinement." ON)
16 | OPTION(BUILD_APP_APPEARANCE_SPACE "Builds app that transforms exemplars into appearance space." ON)
17 | OPTION(BUILD_APP_SYNTHESIZE "Builds synthesizer app." ON)
18 | OPTION(BUILD_APP_UV_MAP "Builds app that remaps an input based on an user-provided UV map." ON)
19 |
20 | IF("${OpenCV_DIR}" STREQUAL "")
21 | SET(OpenCV_DIR "${CMAKE_MODULE_PATH}/opencv")
22 | ENDIF("${OpenCV_DIR}" STREQUAL "")
23 |
24 | IF("${OPENEXR_LOCATION}" STREQUAL "")
25 | SET(OPENEXR_LOCATION "${CMAKE_MODULE_PATH}")
26 | ENDIF("${OPENEXR_LOCATION}" STREQUAL "")
27 |
28 | IF("${TBB_DIR}" STREQUAL "")
29 | SET(TBB_DIR "${CMAKE_MODULE_PATH}")
30 | ENDIF("${TBB_DIR}" STREQUAL "")
31 |
32 | IF("${HDF5_ROOT}" STREQUAL "")
33 | SET(HDF5_ROOT "${CMAKE_MODULE_PATH}")
34 | ENDIF("${HDF5_ROOT}" STREQUAL "")
35 |
36 | IF("${ZLIB_ROOT}" STREQUAL "")
37 | SET(ZLIB_ROOT "${CMAKE_MODULE_PATH}/zlib")
38 | ENDIF("${ZLIB_ROOT}" STREQUAL "")
39 |
40 | IF("${EIGEN3_ROOT}" STREQUAL "")
41 | SET(EIGEN3_ROOT "${CMAKE_MODULE_PATH}")
42 | ENDIF("${EIGEN3_ROOT}" STREQUAL "")
43 |
44 | IF("${TAPKEE_DIR}" STREQUAL "")
45 | SET(TAPKEE_DIR "${CMAKE_MODULE_PATH}")
46 | ENDIF("${TAPKEE_DIR}" STREQUAL "")
--------------------------------------------------------------------------------
/cmake/TexturizeVersion.cmake:
--------------------------------------------------------------------------------
1 | ###################################################################################################
2 | ##### #####
3 | ##### For new releases, change version here. #####
4 | ##### #####
5 | ###################################################################################################
6 |
7 | # Major and minor project version.
8 | SET(Texturize_VERSION_MAJOR 1)
9 | SET(Texturize_VERSION_MINOR 2)
10 | SET(Texturize_VERSION_PATCH 0) # Unused
11 | SET(Texturize_VERSION_TWEAK 0) # Unused
12 |
13 | SET(Texturize_VERSION ${Texturize_VERSION_MAJOR}.${Texturize_VERSION_MINOR}.${Texturize_VERSION_PATCH}.${Texturize_VERSION_TWEAK})
--------------------------------------------------------------------------------
/docs/examples/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "queue": "cpp",
4 | "deque": "cpp",
5 | "vector": "cpp",
6 | "xstring": "cpp",
7 | "algorithm": "cpp",
8 | "cmath": "cpp",
9 | "cstddef": "cpp",
10 | "cstdint": "cpp",
11 | "cstdio": "cpp",
12 | "cstdlib": "cpp",
13 | "cstring": "cpp",
14 | "cwchar": "cpp",
15 | "exception": "cpp",
16 | "initializer_list": "cpp",
17 | "iosfwd": "cpp",
18 | "limits": "cpp",
19 | "new": "cpp",
20 | "stdexcept": "cpp",
21 | "tuple": "cpp",
22 | "type_traits": "cpp",
23 | "utility": "cpp",
24 | "xmemory": "cpp",
25 | "xmemory0": "cpp",
26 | "xstddef": "cpp",
27 | "xtr1common": "cpp",
28 | "xutility": "cpp"
29 | }
30 | }
--------------------------------------------------------------------------------
/docs/examples/AppearanceSpace.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // Create a sample that contains the image.
9 | Texturize::Sample exemplar(img);
10 |
11 | // Calculate the appearance space. Neighborhoods will retain a dimensionality of 4, which is a suitable choice for RGB(A) exemplars.
12 | Texturize::AppearanceSpace* searchSpace;
13 | Texturize::AppearanceSpace::calculate(exemplar, &searchSpace, 4);
14 |
15 | // It is recommended to use smart pointers to manage search space references.
16 | std::unique_ptr< Texturize::AppearanceSpace > descriptors(searchSpace);
17 |
18 | // Display the result.
19 | // Note: Since the appearance space uses principal component analysis (PCA) to transform pixel neighborhoods, the result might be hard
20 | // to interpret for human observers. Also the retained dimensionality does not need to equal 4, which makes this visualization a
21 | // special case. Note that it may differ for different input exemplars!
22 | Texturize::Sample transformedExemplar;
23 | descriptors->sample(transformedExemplar);
24 | cv::imshow("Appearance Space", (cv::Mat)transformedExemplar);
25 | cv::waitKey(1);
26 | }
--------------------------------------------------------------------------------
/docs/examples/BlurFilter.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using namespace Texturize;
4 |
5 | // ------------------------------------------------------------------------------------------------
6 | //
7 | // The example demonstrates how to implement a custom filter, that blurs an image.
8 | //
9 | // ------------------------------------------------------------------------------------------------
10 |
11 | class BlurFilter : public IFilter {
12 | public:
13 | void apply(Sample& result, const Sample& sample) const override;
14 | };
15 |
16 | void BlurFilter::apply(Sample& result, const Sample& sample) const
17 | {
18 | cv::Mat buffer;
19 | cv::GaussianBlur((cv::Mat)sample, buffer, cv::Size(5, 5), 0);
20 | result = Sample(buffer);
21 | }
22 |
23 | int main(int argc, const char** argv)
24 | {
25 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
26 | cv::Mat img = cv::imread(argv[0]);
27 |
28 | // Create a sample that contains the image.
29 | Sample exemplar(img);
30 |
31 | // Apply the filter fuction to the exemplar.
32 | Sample result;
33 | BlurFilter filter;
34 | filter.apply(result, exemplar);
35 |
36 | // Display the result.
37 | cv::imshow("Result", (cv::Mat)result);
38 | cv::waitKey(1);
39 | }
--------------------------------------------------------------------------------
/docs/examples/EventDispatcher.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class Producer {
4 | public:
5 | // An event dispatcher that calls back the progress to functions using an integer parameter and returning a boolean.
6 | Texturize::EventDispatcher ProgressHandler;
7 |
8 | public:
9 | void DoWork() {
10 | int i = 0;
11 |
12 | for (int i(0); i < 100; ++i) {
13 | // ...do something...
14 |
15 | // If some callback does not want the work to continue, return.
16 | if (!ProgressHandler.execute(i))
17 | break;
18 | }
19 | }
20 | };
21 |
22 | // Define the callback function.
23 | int OnProgress(int progress) {
24 | std::cout << "Progress: " << progress << "%" << std::endl;
25 | return true;
26 | }
27 |
28 | // Create a producer instance.
29 | Producer producer;
30 |
31 | int main(int argc, const char** argv)
32 | {
33 | // The producer will call the OnProgress function with each iteration.
34 | producer.ProgressHandler.add(OnProgress);
35 |
36 | // The same can be achieved inline using a lambda expression.
37 | producer.ProgressHandler.add([](int progress) -> bool {
38 | std::cout << "Progress: " << progress << "%" << std::endl;
39 | return true;
40 | });
41 | }
--------------------------------------------------------------------------------
/docs/examples/FeatureGuidance.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // The second command line parameter must contain the edge detector model.
9 | std::string edgeDetectorModel(argv[1]);
10 |
11 | // Create a sample that contains the image.
12 | Texturize::Sample exemplar(img);
13 |
14 | // Run an edge detector on the exemplar.
15 | Texturize::Sample exemplarEdges;
16 | std::unique_ptr edgeDetector = std::make_unique(edgeDetectorModel);
17 | edgeDetector->apply(exemplarEdges, exemplar);
18 |
19 | // Calculate the feature distances that are used as guidance.
20 | Texturize::Sample exemplarFeatures;
21 | std::unique_ptr featureExtractor = std::make_unique();
22 | featureExtractor->apply(exemplarFeatures, exemplarEdges);
23 |
24 | // Calculate the appearance space. Neighborhoods will retain a dimensionality of 4, which is a suitable choice for RGB(A) exemplars.
25 | Texturize::AppearanceSpace* searchSpace;
26 | Texturize::AppearanceSpace::calculate({ exemplarFeatures, exemplar}, &searchSpace, 4);
27 |
28 | // It is recommended to use smart pointers to manage search space references.
29 | std::unique_ptr descriptors(searchSpace);
30 |
31 | // Display the result.
32 | // Note: Since the appearance space uses principal component analysis (PCA) to transform pixel neighborhoods, the result might be hard
33 | // to interpret for human observers. Also the retained dimensionality does not need to equal 4, which makes this visualization a
34 | // special case. Note that it may differ for different input exemplars!
35 | Texturize::Sample transformedExemplar;
36 | descriptors->sample(transformedExemplar);
37 | cv::imshow("Appearance Space", transformedExemplar);
38 | cv::waitKey(1);
39 | }
--------------------------------------------------------------------------------
/docs/examples/FilterFunction.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // Create a sample that contains the image.
9 | Texturize::Sample exemplar(img);
10 |
11 | // Create a new filter.
12 | // The filter assumes that the result and sample are equally sized and the result depth is 1 channel.
13 | // The result will contain the mean value of all sample texel values.
14 | FunctionFilter filter([](Sample& result, Sample& sample) -> void {
15 | std::vector& sampleTexel;
16 | std::vector& resultTexel;
17 | float mean = 0.f;
18 |
19 | // Iterate each texel of the sample.
20 | for (int x(0); x < sample.width(); ++x)
21 | for (int y(0); y < sample.height(); ++y)
22 | {
23 | // Get the sample and result texel references.
24 | sample.at(x, y, sampleTexel);
25 | result.at(x, y, resultTexel);
26 |
27 | // Calculate the mean of the sample texel values.
28 | for each (float val in sampleTexel)
29 | mean += val;
30 |
31 | mean /= sampleTexel.size();
32 |
33 | // Store it to the result texel.
34 | resultTexel[0] = mean;
35 | }
36 | });
37 |
38 | // Apply the filter fuction to the exemplar.
39 | Texturize::Sample result(1, exemplar.size());
40 | filter.apply(result, exemplar);
41 |
42 | // Display the result.
43 | cv::imshow("Result", (cv::Mat)result);
44 | cv::waitKey(1);
45 | }
--------------------------------------------------------------------------------
/docs/examples/ProgressCallback.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // Create a sample that contains the image.
9 | Texturize::Sample exemplar(img);
10 | int width = exemplar.width();
11 | int height = exemplar.height();
12 | int depth = log2(width);
13 |
14 | // Calculate the appearance space. Neighborhoods will retain a dimensionality of 4, which is a suitable choice for RGB(A) exemplars.
15 | Texturize::AppearanceSpace* searchSpace;
16 | Texturize::AppearanceSpace::calculate(exemplar, &searchSpace, 4);
17 |
18 | // It is recommended to use smart pointers to manage search space references.
19 | std::unique_ptr descriptors(searchSpace);
20 |
21 | // Index the neighborhood descriptors. Neighborhood matching is performed based on random march.
22 | Texturize::RandomWalkIndex index(descriptors.get());
23 |
24 | // Setup a parallel pyramid synthesizer. The synthesizer is configured with a constant randomness of 0.1, a 5 pixel kernel and a constant seed.
25 | auto synthesizer = Texturize::ParallelPyramidSynthesizer::createSynthesizer(&index);
26 | Texturize::PyramidSynthesisSettings config(width, cv::Point2f(0.f, 0.f), 0.1f, 5, 0);
27 |
28 | // Setup a progress handler, that prints information to the console and displays the current sample.
29 | config._progressHandler.add([&exemplar, depth](int level, int pass, const cv::Mat& uv) -> void {
30 | if (pass == -1)
31 | std::cout << "Executed level " << level + 1 << "/" << depth << " (Correction pass skipped)" << std::endl;
32 | else
33 | std::cout << "Executed level " << level + 1 << "/" << depth << " (Correction pass " << pass + 1 << ")" << std::endl;
34 |
35 | // Display the current sample.
36 | Texturize::Sample result;
37 | exemplar.sample(uv, result);
38 | cv::imshow("Current Sample", (cv::Mat)result);
39 | cv::waitKey(1);
40 | });
41 |
42 | // Start synthesis.
43 | Texturize::Sample result;
44 | synthesizer->synthesize(width, height, result, config);
45 | }
--------------------------------------------------------------------------------
/docs/examples/PyramidSynthesizer.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // Create a sample that contains the image.
9 | Texturize::Sample exemplar(img);
10 | int width = exemplar.width();
11 | int height = exemplar.height();
12 | int depth = log2(width);
13 |
14 | // Calculate the appearance space. Neighborhoods will retain a dimensionality of 4, which is a suitable choice for RGB(A) exemplars.
15 | Texturize::AppearanceSpace* searchSpace;
16 | Texturize::AppearanceSpace::calculate(exemplar, &searchSpace, 4);
17 |
18 | // It is recommended to use smart pointers to manage search space references.
19 | std::unique_ptr descriptors(searchSpace);
20 |
21 | // Index the neighborhood descriptors. Neighborhood matching is performed based on random march.
22 | Texturize::RandomWalkIndex index(descriptors.get());
23 |
24 | // Setup a pyramid synthesizer. The synthesizer is configured with a constant randomness of 0.1, a 5 pixel kernel and a constant seed.
25 | auto synthesizer = Texturize::PyramidSynthesizer::createSynthesizer(&index);
26 | Texturize::PyramidSynthesisSettings config(width, cv::Point2f(0.f, 0.f), 0.1f, 5, 0);
27 |
28 | // Start synthesis.
29 | Texturize::Sample uvMap, result;
30 | synthesizer->synthesize(width, height, uvMap, config);
31 |
32 | // Display the result
33 | exemplar.sample((cv::Mat)uvMap, result)
34 | cv::imshow("Result", (cv::Mat)result);
35 | cv::waitKey(1);
36 | }
--------------------------------------------------------------------------------
/docs/examples/SampleConstruction.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // Create a sample that contains the image.
9 | Texturize::Sample exemplar(img);
10 |
11 | // Create another sample with 1 channel and the sample size as the earlier created instance.
12 | Texturize::Sample channelA(1, exemplar.size());
13 |
14 | // Copy the alpha channel to the sample.
15 | exemplar.extract({3, 0}, channelA);
16 |
17 | // Convert the sample back to an cv::Mat.
18 | cv::Mat alpha = (cv::Mat)channelA;
19 | }
--------------------------------------------------------------------------------
/docs/examples/SampleMapping.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // Read the uv map, provided by the second command line parameter. Note that uv maps must contain 2 channels.
9 | cv::Mat uv = cv::imread(argv[1]);
10 | TEXTURIZE_ASSERT(uv.depth() == 2);
11 |
12 | // Create a sample for the sample and uv map.
13 | // Note that both images may differ in size.
14 | Texturize::Sample exemplar(img);
15 | Texturize::Sample uvMap(uv);
16 |
17 | // Apply the uv map to the image and store the result to a new sample.
18 | Texturize::Sample result;
19 | exemplar.sample(uv, result);
20 |
21 | // Display the result. It will have the same size as the uv map and the same depth as the image.
22 | cv::imshow("Result", (cv::Mat)result);
23 | cv::waitKey(1);
24 | }
--------------------------------------------------------------------------------
/docs/examples/SamplePixelAccess.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, const char** argv)
4 | {
5 | // Read an image using OpenCV. The name of the image is provided within the first command line parameter.
6 | cv::Mat img = cv::imread(argv[0]);
7 |
8 | // Create a sample that contains the image.
9 | Texturize::Sample exemplar(img);
10 |
11 | // Iterate each texel.
12 | for (int x(0); x < exemplar.width(); ++x)
13 | for (int y(0); y < exemplar.height(); ++y)
14 | {
15 | std::vector texel, neighborhood;
16 |
17 | // Get the texel at the coordinates.
18 | // Assuming the image has 4 channels, the texel vector will have 4 values.
19 | exemplar.at(x, y, texel);
20 |
21 | // Get the gaussian-weighted 5 pixel neighborhood at the coordinates.
22 | // Assuming again, the image has 4 channels, the neighborhood vector will contain 5x5x4 = 100 values.
23 | exemplar.getNeighborhood(x, y, 5, neighborhood, true);
24 | }
25 | }
--------------------------------------------------------------------------------
/docs/getting-started-build.dox:
--------------------------------------------------------------------------------
1 |
2 | namespace Texturize {
3 | /** \page getting-started-build Building the project
4 | \brief There are several reasons, you may want to create a custom build of the framework. The most common one is to link it against
5 | different versions or builds of its dependencies. On this page, you will find information about the frameworks dependency builds
6 | and how to build it on your own.
7 |
8 | \tableofcontents
9 |
10 | \section getting-started-build Creating the project using CMake
11 |
12 | Texturize requires certain dependencies to be installed on your system. All dependencies are listed below. The version represents
13 | the latest build, the project has been successfully tested with. Higher versions may work, if they are compatible.
14 |
15 | | SDK/Framework | Project URL | Version | Source URL |
16 | |---------------|-------------------|:-------:|:---:|
17 | | OpenCV | https://opencv.org/ | 4.0.1 | [Link](https://github.com/opencv/opencv/tree/4.0.1) |
18 | | HDF5 | https://www.hdfgroup.org/ | 1.10.4 | [Link](https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.4/src/) |
19 | | TBB | https://www.threadingbuildingblocks.org/ | 20170919 | [Link](https://github.com/01org/tbb/releases/tag/2018_U1) |
20 | | OpenEXR | http://www.openexr.com/ | 2.3.0 | [Link](https://github.com/openexr/openexr) |
21 |
22 |
23 | \note **Custom OpenCV builds**
24 |
25 | \note By default, the framework is linked against the following OpenCV modules: `core`, `imgproc`, `ximgproc`, `imgcodecs`, `highgui`,
26 | `features2d`, `calib3d`, `ml` and `flann`. Do not forget to include them in your build as well! The other dependencies are build
27 | with default settings.
28 |
29 | \note **Regarding HDF5 builds**
30 |
31 | \note HDF5 can produce some tricky issues, like debug-time errors or falsely configured library links, when you try to compile custom
32 | builds. Creating custom builds typically resolves those issues. From the provided URL, download the CMake release and build it
33 | for your platform. Make sure to build both configurations (`Release` and `Debug`) successfully. Use the generated install
34 | package to build the framework.
35 |
36 | Make sure all dependencies are build correctly for your target system. If you do not want to build them on your own, some provide
37 | pre-compiled binaries. Copy the build of each dependency into the respective directory under `modules\` and run
38 |
39 | \code{.ps1}
40 | cmake CMakeLists.txt -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE="Release"
41 | \endcode
42 |
43 | Of course you can change the generator or build type, however, remember to also build your dependencies according to those parameters.
44 |
45 | \subsection getting-started-build-ps Using Powershell script
46 |
47 | There is a `cmake.ps1` script inside the root of the repository. You can run it in order to specify dependencies, different from the
48 | default `modules\` directory. The skript can be called as follows:
49 |
50 | \code{.ps1}
51 | .\cmake.ps1 -x64:$true -config "Release"
52 | -buildTo "../x64/"
53 | -installTo "install/"
54 | -OpenCV ""
55 | -TBB "\cmake"
56 | -OpenEXR ""
57 | -HDF5 ""
58 | \endcode
59 |
60 | You can create x86 builds by settings the `-x64` switch to false. In case you omit target configuration, `Release` is assumed by
61 | default. Note that in-source builds are not allowed, i.e. the `buildTo` directory needs to be different from your source directory.
62 | This also includes sub-directories created within the source directory. Use the `installTo` parameter to either specify an absolute
63 | path to drop the artifacts after build, or a relative path to the build directory.
64 |
65 | \section getting-started-building Building the solution
66 |
67 | After the skript has finished, open the `Texturize.sln` file and try building the `ALL_BUILD` and `INSTALL` projects. The binaries
68 | are available from the `install\` directory, or the directory specified earlier during the build.
69 |
70 | **/
71 | }
--------------------------------------------------------------------------------
/docs/html/m-texturize+doxygen.compiled.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crud89/Texturize/bba688d1afd60363f03e02d28e642a63845591d6/docs/html/m-texturize+doxygen.compiled.css
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/m-texturize+doxygen.compiled.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crud89/Texturize/bba688d1afd60363f03e02d28e642a63845591d6/docs/m-texturize+doxygen.compiled.css
--------------------------------------------------------------------------------
/docs/texturize-mcss.cfg:
--------------------------------------------------------------------------------
1 | # Derive from original config.
2 | @INCLUDE = texturize.cfg
3 |
4 | # Doxygen overwrites, specific for m.css.
5 | GENERATE_HTML = NO
6 | GENERATE_XML = YES
7 | XML_PROGRAMLISTING = NO
8 |
9 | # m.css handles examples differently, thus separate tutorial pages need to be created.
10 | INPUT = ..\ \
11 | ..\README.md \
12 | getting-started.dox \
13 | getting-started-build.dox \
14 | getting-started-sandbox.dox \
15 | tutorial.dox \
16 | tutorial-filter.dox \
17 | tutorial-search-space.dox \
18 | tutorial-search-index.dox \
19 | tutorial-synthesizer.dox
20 |
21 | IMAGE_PATH = ./images/
22 |
23 | # Use the light theme, because it better matches the available images.
24 | HTML_EXTRA_STYLESHEET = \
25 | https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600 \
26 | ../css/m-texturize+doxygen.compiled.css
27 |
28 | ##! M_THEME_COLOR = #22272e
29 |
30 | # No favicon.
31 | ##! M_FAVICON =
32 |
33 | # Navbar setup
34 | ##! M_LINKS_NAVBAR1 = "getting-started getting-started-build getting-started-sandbox" \
35 | ##! "tutorial tutorial-filter tutorial-search-space tutorial-search-index tutorial-synthesizer"
36 | ##! M_LINKS_NAVBAR2 = modules annotated namespaces
--------------------------------------------------------------------------------
/docs/tutorial-filter.dox:
--------------------------------------------------------------------------------
1 |
2 | namespace Texturize {
3 | /** \page tutorial-filter Implementing custom filters
4 | \brief The example demonstrates how to create and use a custom filter implementation. The filter uses OpenCV to apply gaussian blur with a kernel of 5 to an input image.
5 |
6 | \include BlurFilter.cpp
7 | */
8 | }
--------------------------------------------------------------------------------
/docs/tutorial-search-index.dox:
--------------------------------------------------------------------------------
1 |
2 | namespace Texturize {
3 | /** \page tutorial-search-index Implementing a search index
4 |
5 | This example demonstrates how to implement a search index. The implementation matches pixel neighborhoods by calculating the
6 | euclidean distance between pixel neighborhood descriptors. This basically resembles the naive sampling algorithm, described by
7 | Efros and Leung. It is simple to implement, but comes with a certain runtime cost. The `init` method, thus indexes pixel
8 | neighborhoods by using dimensionality reduction to minimize the number of descriptor components. The
9 | `Texturize::DescriptorExtractor` base class uses Principal Component Analysis (PCA) for this. Other approaches could use Local
10 | Linear Embedding (LLE) or Isomaps. Note that this dimensionality reduction was not done in naive sampling.
11 |
12 | The search index is also responsible for matching pixel neighborhoods during runtime. In this example, each pixel neighborhood
13 | of the exemplar is compared against the requested descriptor. This corresponds to an overall cost of
14 | \f$ \mathcal{O} (n \times m) \f$, which is not ideal. More satisfied approaches may use quantized search trees or coherencies.
15 | The `Texturize::CoherentIndex` uses a pre-calculated set of coherent pixel candidates, from which a random selection is chosen.
16 |
17 | \see Alexei A. Efros and Thomas K. Leung. "Texture Synthesis by Non Parametric Sampling." In: Proceedings of the International Conference on Computer Vision - Volume 2. ICCV '99. Washington, DC, USA: IEEE Computer Society, 1999. isbn: 0-7695-0164-8. url: http://dl.acm.org/citation.cfm?id=850924.851569.
18 | \see Li-Yi Wei and Marc Levoy. "Fast Texture Synthesis Using Tree-structured Vector Quantization." In: Proceedings of the 27th Annual Conference on Computer Graphics and Interactive Techniques. SIGGRAPH '00. New York, NY, USA: ACM Press/Addison-Wesley Publishing Co., 2000, pp. 479-488. isbn: 1-58113-208-5. doi: 10.1145/344779.345009. url: http://dx.doi.org/10.1145/344779.345009.
19 | \see Michael Ashikhmin. "Synthesizing Natural Textures." In: Proceedings of the 2001 Symposium on Interactive 3D Graphics. I3D '01. New York, NY, USA: ACM, 2001, pp. 217-226. isbn: 1-58113-292-1. doi: 10.1145/364338.364405. url: http://doi.acm.org/10.1145/364338.364405.
20 | \see Xin Tong et al. "Synthesis of Bidirectional Texture Functionson Arbitrary Surfaces." In: ACM Trans. Graph. 21.3 (July 2002), pp. 665-672. issn: 07300301. doi: 10.1145/566654.566634. url: http://doi.acm.org/10.1145/566654.566634.
21 |
22 | \include TrivialSearchIndex.cpp
23 | */
24 | }
--------------------------------------------------------------------------------
/docs/tutorial-search-space.dox:
--------------------------------------------------------------------------------
1 |
2 | namespace Texturize {
3 | /** \page tutorial-search-space Creating a search space
4 | \brief The example demonstrates how to implement a custom search space, that builds simple neighborhood descriptors from pixel color values.
5 |
6 | \include ColorSearchSpace.cpp
7 | */
8 | }
9 |
--------------------------------------------------------------------------------
/docs/tutorial-synthesizer.dox:
--------------------------------------------------------------------------------
1 |
2 | namespace Texturize {
3 | /** \page tutorial-synthesizer Writing your own synthesizer
4 |
5 | This example demonstrates how to implement a custom synthesizer. The following code implements a synthesizer, that generates a new texture by naive sampling, as
6 | described by Efros and Leung.
7 |
8 | \include NaiveSamplingSynthesizer.cpp
9 |
10 | \see Alexei A. Efros and Thomas K. Leung. "Texture Synthesis by Non Parametric Sampling." In: Proceedings of the International Conference on Computer Vision - Volume 2. ICCV '99. Washington, DC, USA: IEEE Computer Society, 1999. isbn: 0-7695-0164-8. url: http://dl.acm.org/citation.cfm?id=850924.851569.
11 | */
12 | }
--------------------------------------------------------------------------------
/docs/tutorial.dox:
--------------------------------------------------------------------------------
1 |
2 | namespace Texturize {
3 | /** \page tutorial Tutorials
4 | \brief The following tutorials help you to understand how to customize different modules of the *Texturize* workflow.
5 |
6 | - \ref tutorial-filter
7 | - \ref tutorial-search-space
8 | - \ref tutorial-search-index
9 | - \ref tutorial-synthesizer
10 | */
11 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/Texturize.Analysis.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)$(PlatformTarget)\$(Configuration)\;$(LibraryPath)
7 | $(SolutionDir)\Texturize.Analysis\include\;$(IncludePath)
8 |
9 |
10 |
11 | Texturize.Analysis.lib;%(AdditionalDependencies)
12 |
13 |
14 | xcopy /y /d "$(SolutionDir)\$(PlatformTarget)\$(Configuration)\Texturize.Analysis.dll" "$(OutDir)"
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/include/log2.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #pragma intrinsic(_BitScanReverse)
7 |
8 | /// \brief Approximates the log2 of an integral 32-bit value, by counting the index of the most significant bit of the input.
9 | static inline uint32_t log2(const uint32_t x) {
10 | unsigned long y(0);
11 |
12 | if (x > 0)
13 | _BitScanReverse(&y, x);
14 |
15 | return y;
16 | }
17 |
18 | #ifdef _WIN64
19 | /// \brief Approximates the log2 of an integral 64-bit value, by counting the index of the most significant bit of the input.
20 | static inline uint32_t log2(const uint64_t x) {
21 | unsigned long y(0);
22 |
23 | if (x > 0)
24 | _BitScanReverse64(&y, x);
25 |
26 | return y;
27 | }
28 | #else
29 | /// \brief Approximates the log2 of an integral 64-bit value, by counting the index of the most significant bit of the input.
30 | static inline uint32_t log2(const uint64_t x) {
31 | return x > 0 ? std::log2l(x) : 0;
32 | }
33 | #endif
34 |
35 | /// \brief If the parameter \p from already is a *power-of-two* number, it will be returned unchanged, otherwise the next highest number within the power-of-two is calculated.
36 | ///
37 | /// \param from A number to start searching for the next highest power-of-two number from.
38 | /// \returns The next highest power-of-two number, starting from \p from, or \p from, if it already is a power-of-two number.
39 | static inline int nextPoT(int from)
40 | {
41 | TEXTURIZE_ASSERT(from > 0);
42 |
43 | // Get the index of the most significant bit and create a new number by shifting one towards the index.
44 | int msb = log2(static_cast(from));
45 | int r = 1 << msb;
46 |
47 | // If the result equals the input, the input already is a valid PoT number, otherwise perform an additional shift.
48 | return r == from ? r : r << 1;
49 | }
50 |
51 | /// \brief Checks a given value \p v if it's a power-of-two number.
52 | ///
53 | /// \param v A value that should be checked to be a power-of-two number.
54 | /// \returns `true`, if the provided value \p v is a power-of-two number, otherwise `false`.
55 | static inline bool isPoT(int n)
56 | {
57 | // http://www.graphics.stanford.edu/~seander/bithacks.html
58 | return n && !(n & (n - 1));
59 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/DynamicThresholdFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// OTSU Binarization implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | void DynamicThresholdFilter::apply(Sample& result, const Sample& sample) const
12 | {
13 | cv::Mat s = (cv::Mat)sample;
14 | cv::Mat r(s.size(), CV_32FC1);
15 |
16 | s.convertTo(s, CV_8UC1, 255.f);
17 | cv::threshold(s, s, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
18 | s.convertTo(r, CV_32FC1, 1 / 255.f);
19 |
20 | result = Sample(r);
21 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/FeatureDistanceFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Euclidean distance transform implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | void FeatureDistanceFilter::apply(Sample& result, const Sample& sample) const
12 | {
13 | cv::Mat s = (cv::Mat)sample;
14 | cv::Mat r(s.size(), CV_32FC1);
15 | cv::Mat n(s.size(), CV_8UC1);
16 |
17 | s.convertTo(s, CV_8UC1);
18 | cv::threshold(s, n, 0, 255, cv::THRESH_BINARY_INV);
19 |
20 | cv::Mat dist, distNeg;
21 | cv::distanceTransform(s, dist, cv::DIST_L2, 5);
22 | cv::distanceTransform(n, distNeg, cv::DIST_L2, 5);
23 |
24 | cv::Mat rn = distNeg - dist;
25 | cv::normalize(rn, s, 255, 0, cv::NORM_MINMAX);
26 |
27 | s.convertTo(r, CV_32FC1, 1.f / 255.f);
28 | result = Sample(r);
29 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/FeatureExtractor.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Feature extraction implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | FeatureExtractor::FeatureExtractor()
12 | {
13 | _cascade.append(std::make_shared());
14 | _cascade.append(std::make_shared());
15 | }
16 |
17 | void FeatureExtractor::apply(Sample& result, const Sample& sample) const
18 | {
19 | _cascade.apply(result, sample);
20 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/FilterCascade.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Filter cascade implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | void FilterCascade::apply(Sample& result, const Sample& sample) const
12 | {
13 | std::queue> filters = _filters;
14 | Sample currentResult, previousResult = sample;
15 |
16 | while (!filters.empty())
17 | {
18 | auto filter = filters.front();
19 | filter->apply(currentResult, previousResult);
20 | filters.pop();
21 |
22 | previousResult = currentResult;
23 | }
24 |
25 | result = currentResult;
26 | }
27 |
28 | void FilterCascade::append(std::shared_ptr filter)
29 | {
30 | _filters.push(filter);
31 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/GaussianBlurFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Gaussian Blur Filter implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | GaussianBlurFilter::GaussianBlurFilter(const float& deviation) :
12 | GaussianBlurFilter(deviation, 5)
13 | {
14 | }
15 |
16 | GaussianBlurFilter::GaussianBlurFilter(const float& deviation, const int& kernel) :
17 | _deviation(deviation), _kernel(kernel)
18 | {
19 | TEXTURIZE_ASSERT(kernel > 0); // The kernel should be positive.
20 | TEXTURIZE_ASSERT(kernel % 2); // Evaluates to 1 (TRUE) if kernel is odd, which it is required to be.
21 | }
22 |
23 | void GaussianBlurFilter::apply(Sample& result, const Sample& sample) const
24 | {
25 | cv::Mat s = (cv::Mat)sample;
26 | cv::Mat r(s.size(), s.type());
27 |
28 | cv::GaussianBlur(s, r, cv::Size(5, 5), _deviation, _deviation, cv::BORDER_WRAP);
29 |
30 | result = Sample(r);
31 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/GrayscaleFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Normalization filter implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | void NormalizationFilter::apply(Sample& result, const Sample& sample) const
12 | {
13 | cv::Mat r;
14 | cv::normalize((cv::Mat)sample, r, 1.f, 0.f, cv::NORM_MINMAX);
15 | result = Sample(r);
16 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/HistogramExtractionFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | using namespace Texturize;
11 |
12 | ///////////////////////////////////////////////////////////////////////////////////////////////////
13 | ///// Histogram extraction filter implementation /////
14 | ///////////////////////////////////////////////////////////////////////////////////////////////////
15 |
16 | HistogramExtractionFilter::HistogramExtractionFilter(const int& bins, const int& kernel, const int& stride) :
17 | _bins(bins), _kernel(kernel), _stride(stride)
18 | {
19 | TEXTURIZE_ASSERT(kernel > 0); // The kernel must be positive.
20 | TEXTURIZE_ASSERT(kernel % 2 == 1); // The kernel must be an odd number.
21 | }
22 |
23 | void HistogramExtractionFilter::apply(Sample& result, const Sample& sample) const
24 | {
25 | cv::Mat source = (cv::Mat)sample;
26 |
27 | // In case we got an color image, convert it to greyscale.
28 | // For non-greyscale images or images that can't be converted into greyscale, raise an error.
29 | if (sample.channels() == 3 || sample.channels() == 4)
30 | cv::cvtColor(source, source, cv::COLOR_RGB2GRAY);
31 | else if (sample.channels() != 1)
32 | TEXTURIZE_ERROR(TEXTURIZE_ERROR_ASSERT, "Histograms can only be extracted on greyscale or color (RGB/A) images.");
33 |
34 | // One sample channel maps to one dimension in the histogram.
35 | const int stepsX{ sample.width() / _stride }, stepsY{ sample.height() / _stride };
36 | cv::Size histogramSize(_bins, stepsX * stepsY);
37 | cv::Mat histogram = cv::Mat::zeros(histogramSize, CV_32FC1);
38 |
39 | // Define the value range for one dimension. Since all channels should be normalized CV_32F, 0..1 is good.
40 | float range[2] = { 0.f, 1.f };
41 | const float* ranges = { range };
42 |
43 | // Calculate and return the histogram descriptor for each pixel.
44 | tbb::parallel_for(tbb::blocked_range2d(0, sample.height(), _stride, 0, sample.width(), _stride), [&source, &histogram, &ranges, &stepsX, this](const tbb::blocked_range2d& range) {
45 | for (size_t x = range.cols().begin(); x < range.cols().end(); x += range.cols().grainsize()) {
46 | for (size_t y = range.rows().begin(); y < range.rows().end(); y += range.cols().grainsize()) {
47 | // Generate a mask for a 49x49 pixel kernel at [x, y].
48 | auto mask = this->mask(source.size(), cv::Point2i(static_cast(x), static_cast(y)), this->_kernel);
49 |
50 | // Calculate the histogram at this point.
51 | cv::Mat descriptor;
52 | cv::calcHist(&source, 1, nullptr, mask, descriptor, 1, &_bins, &ranges);
53 | descriptor = descriptor.reshape(1, 1);
54 | descriptor.convertTo(descriptor, CV_32F, 1. / static_cast(this->_kernel * this->_kernel));
55 |
56 | // Store the descriptor.
57 | //auto row = y * source.cols + x;
58 | auto row = (((y / _stride) * stepsX) + (x / _stride));
59 | descriptor.copyTo(histogram.row(static_cast(row)));
60 | }
61 | }
62 | });
63 |
64 | result = Sample(histogram);
65 | }
66 |
67 | cv::Mat HistogramExtractionFilter::mask(const cv::Size& sampleSize, const cv::Point2i& at, const int kernel, const bool wrap) const
68 | {
69 | TEXTURIZE_ASSERT(kernel % 2 == 1); // The kernel should be an odd number.
70 | TEXTURIZE_ASSERT(at.x >= 0 && at.x < sampleSize.width); // X should be valid.
71 | TEXTURIZE_ASSERT(at.y >= 0 && at.y < sampleSize.height); // Y should be valid.
72 |
73 | cv::Mat mask = cv::Mat::zeros(sampleSize, CV_8UC1);
74 | int relativeKernel = kernel / 2;
75 |
76 | // For each pixel inside the kernel...
77 | // TODO: Check if range fits.
78 | tbb::parallel_for(tbb::blocked_range2d(-relativeKernel, relativeKernel, -relativeKernel, relativeKernel),
79 | [&mask, &wrap, &at](const tbb::blocked_range2d& range) {
80 | for (int x = range.cols().begin(); x < range.cols().end(); ++x) {
81 | for (int y = range.rows().begin(); y < range.rows().end(); ++y) {
82 | // Get the coordiantes of the point in the mask.
83 | int _x{ at.x + x }, _y{ at.y + y };
84 |
85 | // Check if the position is out of bounds.
86 | if (_x >= mask.size().width || _y >= mask.size().height || _x < 0 || _y < 0)
87 | {
88 | // In case no wrapping should be applied, ignore the pixel. Otherwise, wrap its coordinates.
89 | if (!wrap)
90 | continue;
91 | else
92 | Sample::wrapCoords(mask.size().width, mask.size().height, _x, _y);
93 | }
94 |
95 | // Set the mask.
96 | mask.at(cv::Point2i(_x, _y)) = 255;
97 | }
98 | }
99 | });
100 |
101 | return mask;
102 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/HistogramMatchingFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | using namespace Texturize;
9 |
10 | ///////////////////////////////////////////////////////////////////////////////////////////////////
11 | ///// Histogram equalization filter implementation /////
12 | ///////////////////////////////////////////////////////////////////////////////////////////////////
13 |
14 | HistogramMatchingFilter::HistogramMatchingFilter(const Sample& referenceSample) :
15 | _referenceCdf(sampleCdf(referenceSample))
16 | {
17 | }
18 |
19 | cv::Mat HistogramMatchingFilter::sampleCdf(const Sample& sample) const
20 | {
21 | cv::Mat grayscale;
22 | return this->sampleCdf(sample, grayscale);
23 | }
24 |
25 | cv::Mat HistogramMatchingFilter::sampleCdf(const Sample& sample, cv::Mat& grscl) const
26 | {
27 | // Convert to 8 bit greyscale in order to be able to get a discrete histogram.
28 | cv::Mat grayscale = this->toGrayscale(sample), histogram;
29 |
30 | // Calculate the reference histogram.
31 | int bins = 256; // Use 256 discrete bins.
32 | float discreteRange[] = { 0.f, static_cast(bins) };
33 | const float* channelRanges = { discreteRange }; // One per channel.
34 | cv::calcHist(&grayscale, 1, nullptr, cv::noArray(), histogram, 1, &bins, &channelRanges);
35 |
36 | // Calculate the pdf (normalize histogram to a range of [0, 1].
37 | cv::Mat pdf = histogram / (sample.width() * sample.height());
38 |
39 | // Calculate the cummulative pdf.
40 | cv::Mat cdf = static_cast(bins - 1) * cummulate(pdf);
41 |
42 | // Discretize the cdf.
43 | cdf.forEach([](float& val, const int* index) -> void {
44 | val = static_cast(cvRound(val));
45 | });
46 |
47 | grscl = grayscale;
48 | return cdf;
49 | }
50 |
51 | cv::Mat HistogramMatchingFilter::toGrayscale(const Sample& sample) const
52 | {
53 | cv::Mat grayscale;
54 |
55 | if (sample.channels() == 3)
56 | cv::cvtColor((cv::Mat)sample, grayscale, cv::COLOR_BGR2GRAY);
57 | else if (sample.channels() == 1)
58 | grayscale = (cv::Mat)sample;
59 | else
60 | TEXTURIZE_ERROR(TEXTURIZE_ERROR_ASSERT, "Provided sample with invalid channel count.");
61 |
62 | TEXTURIZE_ASSERT(grayscale.channels() == 1);
63 | grayscale.convertTo(grayscale, CV_8UC1, 255.f);
64 |
65 | return grayscale;
66 | }
67 |
68 | cv::Mat HistogramMatchingFilter::cummulate(const cv::Mat& histogram) const
69 | {
70 | // The histogram should be a 1D array, that stores bins within its rows.
71 | TEXTURIZE_ASSERT(histogram.cols == 1);
72 | TEXTURIZE_ASSERT(histogram.rows > 0);
73 |
74 | std::vector cumsum(histogram.rows);
75 | std::partial_sum(histogram.begin(), histogram.end(), cumsum.begin());
76 | return cv::Mat(cumsum, true);
77 | }
78 |
79 | void HistogramMatchingFilter::apply(Sample& result, const Sample& sample) const
80 | {
81 | // Get the cdf of the sample.
82 | cv::Mat grayscaleSample, sampleCdf = this->sampleCdf(sample, grayscaleSample);
83 | std::vector transformLookupTable(sampleCdf.rows);
84 |
85 | // Find the transformation function from the reference cdf to the sample cdf. This is done by iterating
86 | // the sample cdf and looking for the point within the reference cdf that has the same frequency (i.e.
87 | // number of pixels with that value). The offset is then remembered for each frequency within the
88 | // transformation function.
89 | _referenceCdf.forEach([&sampleCdf, &transformLookupTable](float& val, const int* index) -> void {
90 | // The value represents the probability that a pixel has a certain frequency within the reference
91 | // sample. The index contains the current row, i.e. the associated frequency.
92 | const int referenceFrequency = index[0];
93 | TEXTURIZE_ASSERT_DBG(index[1] == 0);
94 |
95 | // Iteratively walk the sample cdf to find the frequency with minimum deviation.
96 | float minimum = std::numeric_limits::max();
97 | int sampleFrequency(0);
98 |
99 | for (auto it = sampleCdf.begin(); it < sampleCdf.end(); ++it, ++sampleFrequency)
100 | {
101 | // Get the difference.
102 | float difference = abs(*it - val);
103 |
104 | // Now there are two cases: If the difference is lower than the current minimum, continue
105 | // minimization. Otherwise, the minimum has been surpassed and found.
106 | if (difference <= minimum)
107 | minimum = difference;
108 | else
109 | {
110 | transformLookupTable[sampleFrequency] = static_cast(referenceFrequency);
111 | break;
112 | }
113 | }
114 | });
115 |
116 | // The transformLookupTable now contains a mapping, that assigns each sample frequency a frequency of
117 | // the reference sample. All thats left to do is to apply this mapping to the sample.
118 | cv::Mat matchedSample;
119 | cv::LUT(grayscaleSample, cv::Mat(transformLookupTable, false), matchedSample);
120 |
121 | result = Sample(matchedSample);
122 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/KMeansClusterFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Histogram extraction filter implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | KMeansClusterFilter::KMeansClusterFilter(const int clusters, const int iterations) :
12 | _numClusters(clusters), _iterations(iterations)
13 | {
14 | }
15 |
16 | void KMeansClusterFilter::apply(Sample& result, const Sample& sample) const
17 | {
18 | cv::Mat features = ((cv::Mat)sample).reshape(1, sample.height() * sample.width());
19 | cv::TermCriteria terminationRule(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, _iterations, 1.0);
20 |
21 | //int dimensions = features.cols;
22 | //cv::Mat labels, centers;
23 | //cv::kmeans(features, _numClusters, labels, terminationRule, _iterations, cv::KMEANS_PP_CENTERS, centers);
24 | //
25 | //labels = labels.reshape(1, sample.height());
26 | //cv::Mat centeroids(labels.size(), CV_32FC(dimensions));
27 | //
28 | // // TODO: For each [x, y] in `labels`: Copy centers[labels[x, y]] to centeroids[x, y].
29 |
30 | cv::Mat labels;
31 | cv::kmeans(features, _numClusters, labels, terminationRule, _iterations, cv::KMEANS_PP_CENTERS);
32 | labels.convertTo(labels, CV_32F, 1.f / static_cast(_numClusters));
33 | result = Sample(labels.reshape(1, sample.height()));
34 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/NormalizationFilter.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Normalization filter implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | void GrayscaleFilter::apply(Sample& result, const Sample& sample) const
12 | {
13 | TEXTURIZE_ASSERT(sample.channels() == 3);
14 |
15 | cv::Mat r;
16 | cv::cvtColor((cv::Mat)sample, r, cv::COLOR_BGR2GRAY);
17 |
18 | result = Sample(r);
19 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/PerlinNoise.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // PerlinNoise.{h|cpp} - perlin noise image generator.
3 | //
4 | // github:
5 | // https://github.com/yoggy/cv_perlin_noise
6 | //
7 | // license:
8 | // Copyright (c) 2015 yoggy
9 | // Released under the MIT license
10 | // http://opensource.org/licenses/mit-license.php
11 | //
12 | // reference:
13 | // http://cs.nyu.edu/~perlin/noise/
14 | //
15 | #include
16 | #include "PerlinNoise.h"
17 |
18 | namespace yoggy {
19 | class PerlinNoise {
20 | public:
21 | int p[512];
22 |
23 | PerlinNoise() {
24 | int permutation[] = { 151, 160, 137, 91, 90, 15, 131, 13, 201,
25 | 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37,
26 | 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62,
27 | 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56,
28 | 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139,
29 | 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133,
30 | 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25,
31 | 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200,
32 | 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3,
33 | 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255,
34 | 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
35 | 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153,
36 | 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79,
37 | 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242,
38 | 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249,
39 | 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204,
40 | 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222,
41 | 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 };
42 |
43 | for (int i = 0; i < 256; i++) {
44 | p[256 + i] = p[i] = permutation[i];
45 | }
46 | }
47 |
48 | double noise(const double &src_x, const double &src_y, const double &src_z) {
49 | int X = (int)floor(src_x) & 255;
50 | int Y = (int)floor(src_y) & 255;
51 | int Z = (int)floor(src_z) & 255;
52 |
53 | double x = src_x - floor(src_x);
54 | double y = src_y - floor(src_y);
55 | double z = src_z - floor(src_z);
56 |
57 | double u = fade(x);
58 | double v = fade(y);
59 | double w = fade(z);
60 |
61 | int A = p[X] + Y;
62 | int AA = p[A] + Z;
63 | int AB = p[A + 1] + Z;
64 | int B = p[X + 1] + Y;
65 | int BA = p[B] + Z;
66 | int BB = p[B + 1] + Z;
67 |
68 | double r = lerp(
69 | w,
70 | lerp(v,
71 | lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1, y, z)),
72 | lerp(u, grad(p[AB], x, y - 1, z),
73 | grad(p[BB], x - 1, y - 1, z))),
74 | lerp(v,
75 | lerp(u, grad(p[AA + 1], x, y, z - 1),
76 | grad(p[BA + 1], x - 1, y, z - 1)),
77 | lerp(u, grad(p[AB + 1], x, y - 1, z - 1),
78 | grad(p[BB + 1], x - 1, y - 1, z - 1))));
79 |
80 | return r;
81 | }
82 |
83 | protected:
84 | double fade(double t) {
85 | return t * t * t * (t * (t * 6 - 15) + 10);
86 | }
87 |
88 | double lerp(double t, double a, double b) {
89 | return a + t * (b - a);
90 | }
91 |
92 | double grad(int hash, double x, double y, double z) {
93 | int h = hash & 15;
94 | double u = h < 8 ? x : y;
95 | double v = h < 4 ? y : h == 12 || h == 14 ? x : z;
96 | return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
97 | }
98 | } perlin_noise;
99 | }
100 |
101 | cv::Mat CreatePerlinNoiseImage(const cv::Size &size, const double &scale)
102 | {
103 | using namespace yoggy;
104 |
105 | cv::Mat img;
106 | img.create(size, CV_8UC1);
107 |
108 | for (int y = 0; y < size.height; ++y) {
109 | for (int x = 0; x < size.width; ++x) {
110 | double p = perlin_noise.noise(x * scale, y * scale, 0.0); // -1.0�`1.0
111 | p = (p + 1.0) / 2.0; // 0.0�`1.0
112 | img.at(cv::Point(x, y)) = (uchar)(p * 255);
113 | }
114 | }
115 |
116 | return img;
117 | }
118 |
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/PerlinNoise.h:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // PerlinNoise.{h|cpp} - perlin noise image generator.
4 | //
5 | // github:
6 | // https://github.com/yoggy/cv_perlin_noise
7 | //
8 | // license:
9 | // Copyright (c) 2015 yoggy
10 | // Released under the MIT license
11 | // http://opensource.org/licenses/mit-license.php
12 | //
13 | // reference:
14 | // http://cs.nyu.edu/~perlin/noise/
15 | //
16 | #pragma once
17 |
18 | #pragma warning(disable : 4819)
19 |
20 | #include
21 | #include
22 |
23 | cv::Mat CreatePerlinNoiseImage(const cv::Size &size, const double &scale = 0.05);
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/PerlinNoise2D.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #include "PerlinNoise.h"
9 |
10 | using namespace Texturize;
11 |
12 | ///////////////////////////////////////////////////////////////////////////////////////////////////
13 | ///// 2D Perlin noise generator /////
14 | ///////////////////////////////////////////////////////////////////////////////////////////////////
15 |
16 | void PerlinNoise2D::makeNoise(Sample& sample) const
17 | {
18 | cv::Mat noise = CreatePerlinNoiseImage(sample.size(), 1.0), result;
19 | cv::add((cv::Mat)sample, noise, result);
20 |
21 | sample = Sample(result);
22 | }
23 |
24 | void PerlinNoise2D::apply(Sample& result, const Sample& sample) const
25 | {
26 | // Store sample in result and add noise to it.
27 | this->makeNoise(result = sample);
28 | }
29 |
30 | ///////////////////////////////////////////////////////////////////////////////////////////////////
31 | ///// 2D Perlin noise generator from a reference variance /////
32 | ///////////////////////////////////////////////////////////////////////////////////////////////////
33 |
34 | MatchingVarianceNoise::MatchingVarianceNoise(const float referenceVariance) :
35 | _referenceVariance({ referenceVariance })
36 | {
37 | }
38 |
39 | MatchingVarianceNoise::MatchingVarianceNoise(const std::vector& referenceVariances) :
40 | _referenceVariance(referenceVariances)
41 | {
42 | }
43 |
44 | void MatchingVarianceNoise::makeNoise(Sample& sample) const
45 | {
46 | // If the filter has been provided with multiple variance values, there must be enough for each sample channel. In case
47 | // the filter only got provided with one variance value, the same amplitude is applied to all channels.
48 | TEXTURIZE_ASSERT(_referenceVariance.size() == 1 || sample.channels() <= _referenceVariance.size());
49 |
50 | cv::Scalar mean, deviation;
51 | cv::meanStdDev((cv::Mat)sample, mean, deviation);
52 | Sample result(sample.channels());
53 |
54 | for (int channel(0); channel < sample.channels(); ++channel)
55 | {
56 | // Create 2D perlin noise and convert it to a floating-point image.
57 | cv::Mat noise, buffer;
58 | ::CreatePerlinNoiseImage(sample.size()).convertTo(noise, CV_32FC1, 1.f / 255.f);
59 |
60 | // Calculate the amplitude as the ratio between reference and sample variances.
61 | // In case only one reference variance value is provided, it is used over all channels, otherwise
62 | // it is selected for the current channel.
63 | float amplitude = _referenceVariance.size() == 1 ?
64 | _referenceVariance[0] / std::pow(static_cast(deviation.val[channel]), 2.f) :
65 | _referenceVariance[channel] / std::pow(static_cast(deviation.val[channel]), 2.f);
66 |
67 | noise *= amplitude;
68 |
69 | // Mix the results and store it within the respective sample channel.
70 | cv::add(sample.getChannel(channel), noise, buffer, cv::noArray(), CV_32F);
71 |
72 | // TODO: Normalizing here should affect the variance ratio and should typically not be required. On the other
73 | // hand, not normalizing results in invalid refined channels.
74 | cv::normalize(buffer, buffer);
75 | result.setChannel(channel, buffer);
76 | }
77 |
78 | sample = Sample(result);
79 | }
80 |
81 | std::unique_ptr MatchingVarianceNoise::FromSample(const Sample& sample)
82 | {
83 | std::vector variances;
84 |
85 | cv::Scalar mean, deviation;
86 | cv::meanStdDev((cv::Mat)sample, mean, deviation);
87 |
88 | for (int channel(0); channel < sample.channels(); ++channel)
89 | variances.push_back(static_cast(pow(deviation.val[channel], 2)));
90 |
91 | return std::make_unique(variances);
92 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/StructuredEdgeDetector.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 |
5 | using namespace Texturize;
6 |
7 | ///////////////////////////////////////////////////////////////////////////////////////////////////
8 | ///// Random Forest Edge Detector implementation /////
9 | ///////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | StructuredEdgeDetector::StructuredEdgeDetector(const std::string& modelName) :
12 | _detector(cv::ximgproc::createStructuredEdgeDetection(modelName))
13 | {
14 | }
15 |
16 | void StructuredEdgeDetector::apply(Sample& result, const Sample& sample) const
17 | {
18 | cv::Mat s = (cv::Mat)sample;
19 | cv::Mat r(s.size(), CV_32FC1);
20 |
21 | _detector->detectEdges(s, r);
22 | cv::normalize(r, r, 1.f, 0.f, cv::NORM_MINMAX);
23 |
24 | result = Sample(r);
25 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/analysis.cpp:
--------------------------------------------------------------------------------
1 | #include
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/dllmain.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
4 | {
5 | switch (reason)
6 | {
7 | case DLL_PROCESS_ATTACH:
8 | case DLL_THREAD_ATTACH:
9 | case DLL_THREAD_DETACH:
10 | case DLL_PROCESS_DETACH:
11 | break;
12 | }
13 | return TRUE;
14 | }
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "targetver.h"
4 |
5 | #define WIN32_LEAN_AND_MEAN
6 |
7 | #include
8 | #include
9 | #include
--------------------------------------------------------------------------------
/libs/Texturize.Analysis/src/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/libs/Texturize.Codecs.EXR/Texturize.Codecs.EXR.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)$(PlatformTarget)\$(Configuration)\;$(LibraryPath)
7 | $(SolutionDir)\Texturize.Codecs.EXR\include\;$(IncludePath)
8 |
9 |
10 |
11 | Texturize.Codecs.EXR.lib;%(AdditionalDependencies)
12 |
13 |
14 | xcopy /y /d "$(SolutionDir)\$(PlatformTarget)\$(Configuration)\Texturize.Codecs.EXR.dll" "$(OutDir)"
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/libs/Texturize.Codecs.EXR/include/Codecs/exr.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include
8 | #include
9 |
10 | namespace Texturize {
11 |
12 | /// \brief
13 | class TEXTURIZE_API EXRCodec :
14 | public ISampleCodec
15 | {
16 | public:
17 | virtual void load(const std::string& fileName, Sample& sample) const override;
18 | virtual void load(std::istream& stream, Sample& sample) const override;
19 | virtual void save(const std::string& fileName, const Sample& sample, const int depth = CV_8U) const override;
20 | virtual void save(std::ostream& stream, const Sample& sample, const int depth = CV_8U) const override;
21 | };
22 | }
--------------------------------------------------------------------------------
/libs/Texturize.Codecs.EXR/src/Stream.hpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | using namespace OPENEXR_IMF_NAMESPACE;
9 | using namespace IMATH_NAMESPACE;
10 |
11 | class IStreamImpl :
12 | public IStream
13 | {
14 | private:
15 | std::istream* _stream;
16 |
17 | public:
18 | IStreamImpl(std::istream* stream) :
19 | IStream(""), _stream(stream)
20 | {
21 | TEXTURIZE_ASSERT(_stream != nullptr);
22 | }
23 |
24 | virtual ~IStreamImpl()
25 | {
26 | //delete _stream;
27 | }
28 |
29 | bool read(char c[], int n) override;
30 | Int64 tellg() override;
31 | void seekg(Int64 pos) override;
32 | void clear() override;
33 | };
34 |
35 | class OStreamImpl :
36 | public OStream
37 | {
38 | private:
39 | std::ostream* _stream;
40 |
41 | public:
42 | OStreamImpl(std::ostream* stream) :
43 | OStream(""), _stream(stream)
44 | {
45 | TEXTURIZE_ASSERT(_stream != nullptr);
46 | }
47 |
48 | virtual ~OStreamImpl()
49 | {
50 | //delete _stream;
51 | }
52 |
53 | void write(const char c[], int n) override;
54 | Int64 tellp() override;
55 | void seekp(Int64 p) override;
56 | };
57 |
58 | bool IStreamImpl::read(char c[], int n)
59 | {
60 | _stream->read(c, static_cast