Added flaky support for finding Matlab on Windows machines
This commit is contained in:
parent
9cc949e341
commit
6549e5e052
@ -24,13 +24,26 @@
|
|||||||
#
|
#
|
||||||
# cmake -DMATLAB_ROOT_DIR='/PATH/TO/ROOT_DIR' ..
|
# cmake -DMATLAB_ROOT_DIR='/PATH/TO/ROOT_DIR' ..
|
||||||
|
|
||||||
|
# ----- set_library_presuffix -----
|
||||||
|
function(set_libarch_prefix_suffix)
|
||||||
|
if (UNIX AND NOT APPLE)
|
||||||
|
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE)
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a" PARENT_SCOPE)
|
||||||
|
elseif (APPLE)
|
||||||
|
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE)
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".a" PARENT_SCOPE)
|
||||||
|
elseif (WIN32)
|
||||||
|
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE)
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# ----- locate_matlab_root -----
|
# ----- locate_matlab_root -----
|
||||||
#
|
#
|
||||||
# Attempt to find the path to the Matlab installation. If successful, sets
|
# Attempt to find the path to the Matlab installation. If successful, sets
|
||||||
# the absolute path in the variable MATLAB_ROOT_DIR
|
# the absolute path in the variable MATLAB_ROOT_DIR
|
||||||
function(locate_matlab_root)
|
function(locate_matlab_root)
|
||||||
|
|
||||||
# --- LINUX ---
|
# --- LINUX ---
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
# possible root locations, in order of likelihood
|
# possible root locations, in order of likelihood
|
||||||
@ -64,18 +77,47 @@ function(locate_matlab_root)
|
|||||||
|
|
||||||
# --- WINDOWS ---
|
# --- WINDOWS ---
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
# query the registry
|
# search the path to see if Matlab exists there
|
||||||
|
# fingers crossed it is, otherwise we have to start hunting through the registry :/
|
||||||
|
string(REGEX REPLACE ".*[;=](.*MATLAB[^;]*)\\\\bin.*" "\\1" MATLAB_ROOT_DIR_ "$ENV{PATH}")
|
||||||
|
if (MATLAB_ROOT_DIR_)
|
||||||
|
set(MATLAB_ROOT_DIR ${MATLAB_ROOT_DIR_} PARENT_SCOPE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# determine the Matlab version
|
||||||
|
set(REG_EXTENSION_ "SOFTWARE\\Mathworks\\MATLAB")
|
||||||
set(REG_ROOTS_ "HKEY_LOCAL_MACHINE" "HKEY_CURRENT_USER")
|
set(REG_ROOTS_ "HKEY_LOCAL_MACHINE" "HKEY_CURRENT_USER")
|
||||||
foreach(REG_ROOT_ REG_ROOTS_)
|
foreach(REG_ROOT_ ${REG_ROOTS_})
|
||||||
execute_process(COMMAND reg query ${REG_ROOT_}\\SOFTWARE\\MathWorks\\MATLAB /f * /k OUTPUT_VARIABLE VERSIONS_)
|
execute_process(COMMAND reg query "${REG_ROOT_}\\${REG_EXTENSION_}"
|
||||||
if (VERSIONS_)
|
OUTPUT_VARIABLE QUERY_RESPONSE_
|
||||||
|
)
|
||||||
|
if (QUERY_RESPONSE)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(QUERY_PATH_ ${REG_ROOT_}\\SOFTWARE)
|
||||||
|
set(QUERY_PATH_REGEX_ "${REG_ROOT_}\\\\SOFTWARE\\\\Mathworks\\\\MATLAB\\\\([\\.0-9]+)")
|
||||||
|
message(${QUERY_PATH_})
|
||||||
|
execute_process(COMMAND reg query ${QUERY_PATH_} OUTPUT_VARIABLE QUERY_RESPONSE_
|
||||||
|
ERROR_VARIABLE ERROR_VAR_)
|
||||||
|
message("Error: ${ERROR_VAR_}")
|
||||||
|
message("Response: ${QUERY_RESPONSE_}")
|
||||||
|
if (QUERY_RESPONSE_)
|
||||||
|
string(REGEX MATCHALL ${QUERY_PATH_REGEX_} QUERY_MATCHES_ ${QUERY_RESPONSE_})
|
||||||
|
foreach(QUERY_MATCH_ ${QUERY_MATCHES_})
|
||||||
|
string(REGEX REPLACE ${QUERY_PATH_REGEX_} "\\1" QUERY_MATCH_ ${QUERY_MATCH_})
|
||||||
|
list(APPEND VERSIONS_ ${QUERY_MATCH_})
|
||||||
|
endforeach()
|
||||||
|
message(${VERSIONS_})
|
||||||
# sort in order from highest to lowest
|
# sort in order from highest to lowest
|
||||||
list(SORT VERSIONS_)
|
list(SORT VERSIONS_)
|
||||||
list(REVERSE VERSIONS_)
|
list(REVERSE VERSIONS_)
|
||||||
list(GET VERSIONS_ 0 VERSION_)
|
list(GET VERSIONS_ 0 VERSION_)
|
||||||
get_filename_component(MATLAB_ROOT_DIR_ [${REG_ROOT_}\\SOFTWARE\\MathWorks\\MATLAB\\${VERSION_};Install_Dir] ABSOLUTE PATH)
|
get_filename_component(MATLAB_ROOT_DIR_ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\MATLAB] ABSOLUTE CACHE)
|
||||||
|
message(${MATLAB_ROOT_DIR_})
|
||||||
if (MATLAB_ROOT_DIR_)
|
if (MATLAB_ROOT_DIR_)
|
||||||
break()
|
#break()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
@ -105,14 +147,22 @@ function(locate_matlab_components MATLAB_ROOT_DIR)
|
|||||||
if (NOT MATLAB_MEXEXT_)
|
if (NOT MATLAB_MEXEXT_)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(STRIP ${MATLAB_MEXEXT_} MATLAB_MEXEXT_)
|
string(STRIP ${MATLAB_MEXEXT_} MATLAB_MEXEXT_)
|
||||||
string(REPLACE "mex" "" MATLAB_ARCH_ ${MATLAB_MEXEXT_})
|
|
||||||
|
# map the mexext to an architecture extension
|
||||||
|
set(ARCHITECTURES_ "maci64" "maci" "glnxa64" "glnx64" "sol64" "sola64" "win32" "win64" )
|
||||||
|
foreach(ARCHITECTURE_ ${ARCHITECTURES_})
|
||||||
|
if(EXISTS ${MATLAB_ROOT_DIR}/bin/${ARCHITECTURE_})
|
||||||
|
set(MATLAB_ARCH_ ${ARCHITECTURE_})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
# get the path to the libraries
|
# get the path to the libraries
|
||||||
set(MATLAB_LIBRARY_DIR_ ${MATLAB_ROOT_DIR}/bin/${MATLAB_ARCH_})
|
set(MATLAB_LIBRARY_DIR_ ${MATLAB_ROOT_DIR}/bin/${MATLAB_ARCH_})
|
||||||
|
|
||||||
# get the libraries
|
# get the libraries
|
||||||
|
set_libarch_prefix_suffix()
|
||||||
find_library(MATLAB_LIB_MX_ mx PATHS ${MATLAB_LIBRARY_DIR_} NO_DEFAULT_PATH)
|
find_library(MATLAB_LIB_MX_ mx PATHS ${MATLAB_LIBRARY_DIR_} NO_DEFAULT_PATH)
|
||||||
find_library(MATLAB_LIB_MEX_ mex PATHS ${MATLAB_LIBRARY_DIR_} NO_DEFAULT_PATH)
|
find_library(MATLAB_LIB_MEX_ mex PATHS ${MATLAB_LIBRARY_DIR_} NO_DEFAULT_PATH)
|
||||||
find_library(MATLAB_LIB_MAT_ mat PATHS ${MATLAB_LIBRARY_DIR_} NO_DEFAULT_PATH)
|
find_library(MATLAB_LIB_MAT_ mat PATHS ${MATLAB_LIBRARY_DIR_} NO_DEFAULT_PATH)
|
||||||
|
@ -67,6 +67,8 @@ endif()
|
|||||||
if (BUILD_TESTS)
|
if (BUILD_TESTS)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
endif()
|
endif()
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
add_subdirectory(io)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Configure time components
|
# Configure time components
|
||||||
@ -84,6 +86,9 @@ foreach(opencv_module ${MATLAB_DEPS})
|
|||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
# add extra headers by hand
|
||||||
|
list(APPEND opencv_hdrs "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/base.hpp")
|
||||||
|
|
||||||
# Configure checks
|
# Configure checks
|
||||||
# Check to see whether the generator and the mex compiler are working.
|
# Check to see whether the generator and the mex compiler are working.
|
||||||
# The checks currently test:
|
# The checks currently test:
|
||||||
|
@ -9,8 +9,12 @@ class MatlabWrapperGenerator(object):
|
|||||||
ns = {}
|
ns = {}
|
||||||
for file in input_files:
|
for file in input_files:
|
||||||
# get the file name
|
# get the file name
|
||||||
name = os.path.splitext(os.path.basename(file))[0]
|
name = re.findall('include/opencv2/([^./]+)', file)[0]
|
||||||
ns[name] = parser.parse(file)
|
#name = os.path.splitext(os.path.basename(file))[0]
|
||||||
|
try:
|
||||||
|
ns[name] = ns[name] + parser.parse(file)
|
||||||
|
except KeyError:
|
||||||
|
ns[name] = parser.parse(file)
|
||||||
|
|
||||||
# cleanify the parser output
|
# cleanify the parser output
|
||||||
parse_tree = ParseTree()
|
parse_tree = ParseTree()
|
||||||
|
@ -1,11 +1,116 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <stringstream>
|
#include <stringstream>
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
const char* day[] = { "Sun", "Mon", "Tue", "Wed", "Thurs", "Fri", "Sat" };
|
const char* day[] = { "Sun", "Mon", "Tue", "Wed", "Thurs", "Fri", "Sat" };
|
||||||
const char* month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
const char* month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||||
const char* arch = "${MEX_ARCH}"
|
const char* arch = "${MEX_ARCH}";
|
||||||
|
|
||||||
std::string formatCurrentTime() {
|
// ----------------------------------------------------------------------------
|
||||||
|
// BASIC OPERATIONS
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
string MatlabIO::filename(void) const { return filename_; }
|
||||||
|
bool open(const string& filename, ios_base::openmode mode);
|
||||||
|
filename_ = filename;
|
||||||
|
stream_.open(filename, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOpen() const { return stream_.valid(); }
|
||||||
|
void close() { stream_.close(); }
|
||||||
|
|
||||||
|
std::ifstream::pos_type filesize() {
|
||||||
|
std::ifstream::pos_type current = stream_.tellg();
|
||||||
|
stream_.seekg(0, std::ifstream::end);
|
||||||
|
std::ifstream::pos_type end = stream_.tellg();
|
||||||
|
stream_.seekg(current, std::ifstream::beg);
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushStreamPosition() {
|
||||||
|
stream_pos_ = stream_.tellg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void popStreamPosition() {
|
||||||
|
stream_.seekg(stream_pos_, std::ifstream::beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStreamPosition(std::ifstream::pos_type position) {
|
||||||
|
stream_.seekg(position, std::ifstream::beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// HEADERS
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void getFileHeader() {
|
||||||
|
// store the current stream position
|
||||||
|
pushStreamPosition();
|
||||||
|
setStreamPosition(0);
|
||||||
|
stream_.read(const_cast<char *>(header_.data()), sizeof(char)*HEADER_LENGTH);
|
||||||
|
stream_.read(const_cast<char *>(subsys_.data()), sizeof(char)*SUBSYS_LENGTH);
|
||||||
|
stream_.read((char *)&version_, sizeof(int16_t));
|
||||||
|
stream_.read(const_cast<char *>(endian_.data()), sizeof(char)*ENDIAN_LENGTH);
|
||||||
|
|
||||||
|
// get the actual version
|
||||||
|
if (version_ == 0x0100) version_ = Matlab::IO::Version5;
|
||||||
|
if (version_ == 0x0200) version_ = Matlab::IO::Version73;
|
||||||
|
|
||||||
|
// get the endianness
|
||||||
|
if (endian_.compare("IM") == 0) byte_swap_ = false;
|
||||||
|
if (endian_.compare("MI") == 0) byte_swap_ = true;
|
||||||
|
|
||||||
|
// restore the current stream position
|
||||||
|
popStreamPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// INDEXING OPERATIONS
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void MatlabIO::indexNode(const MappingIndex& current) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MatlabIO::indexNode(const SequenceIndex& current) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MatlabIO::index() {
|
||||||
|
// if there is no open file, do nothing
|
||||||
|
if (!isOpen()) return;
|
||||||
|
|
||||||
|
// read the global header
|
||||||
|
getFileHeader();
|
||||||
|
|
||||||
|
// change the endianness if need be
|
||||||
|
|
||||||
|
// manually index the top-level node
|
||||||
|
MappingIndex root(filename_, vector<size_t>(), stream_.tellg(), filesize(), 0, 0, stream_);
|
||||||
|
indexNode(root);
|
||||||
|
index_ = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// FORMATTING / PRINTING
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template <typename Iterable>
|
||||||
|
string delimitedStringFromIterable(const Iterable& obj, const string& delimiter=string(" ")) {
|
||||||
|
string cache = "";
|
||||||
|
ostringstream oss;
|
||||||
|
for (Iterable::iterator it = obj.begin(); it != obj.end(); ++it) {
|
||||||
|
// flush the cache and insert the next element
|
||||||
|
oss << cache << *it;
|
||||||
|
cache = delimiter;
|
||||||
|
}
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string formatCurrentTime() {
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
struct tm* timeinfo;
|
struct tm* timeinfo;
|
||||||
@ -24,9 +129,42 @@ std::string formatCurrentTime() {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatlabIO::whos() {
|
|
||||||
std::cout << "-------------------- whos --------------------" << std::endl;
|
void MatlabIO::printRootIndex() const {
|
||||||
std::cout << "Filename: " << filename() << std::endl;
|
cout << "--------------- top level file index ------------------" << endl;
|
||||||
std::cout << "File size: " << filesize() << "MB" << std::endl << std::endl;
|
cout << "Filename: " << filename() << endl;
|
||||||
std::cout << "Name size bytes type" << std::endl;
|
cout << "File size: " << filesize() << "MB" << endl << endl;
|
||||||
std::cout << "----------------------------------------------" << std::endl;
|
cout << "Name size bytes type" << endl;
|
||||||
|
for (Map<String, Index>::iterator it = index_.mapping.begin(); it != index_.mapping.end(); ++it) {
|
||||||
|
cout << it->name << " ";
|
||||||
|
cout << delimitedStringFromIterable(it->size, "x") << " ";
|
||||||
|
cout << it->end - it->begin << " ";
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
cout << "-------------------------------------------------------" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printIndex(const Index& index, const int indentation) {
|
||||||
|
cout << string(2*indentation - 1, ' ') << "|" << endl;
|
||||||
|
cout << string(2*indentation - 1, ' ') << "|-- ";
|
||||||
|
cout << index.name << " (" << delimitedStringFromIterable(index.size, "x") << ")" << endl;
|
||||||
|
if (index.leaf) return;
|
||||||
|
if (index.associative) {
|
||||||
|
for (Map<string, Index>::iterator it = index.mapping.begin(); it != index.mapping.end(); ++it) {
|
||||||
|
printIndex(it->second, indentation+1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (vector<Index>::iterator it = index.sequence.begin(); it != index.sequence.end(); ++it) {
|
||||||
|
printIndex(it->second, indentation+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MatlabIO::printFullIndex() const {
|
||||||
|
int indentation = 0;
|
||||||
|
cout << "----------------- full file index ---------------------" << endl;
|
||||||
|
printIndex(index_, indentation);
|
||||||
|
cout << "-------------------------------------------------------" << endl;
|
||||||
|
}
|
||||||
|
@ -1,19 +1,39 @@
|
|||||||
#ifndef MATLAB_IO_HPP_
|
#ifndef MATLAB_IO_HPP_
|
||||||
#define MATLAB_IO_HPP_
|
#define MATLAB_IO_HPP_
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <zlib.h>
|
||||||
#include <opencv2/core.hpp>
|
#include <opencv2/core.hpp>
|
||||||
|
#include <opencv2/core/persistence.hpp>
|
||||||
|
#include "primitives.hpp"
|
||||||
|
#include "bridge.hpp"
|
||||||
|
#include "mxarray.hpp"
|
||||||
#include "map.hpp"
|
#include "map.hpp"
|
||||||
|
|
||||||
namespace Matlab {
|
namespace Matlab {
|
||||||
namespace IO {
|
namespace IO {
|
||||||
static const int VERSION_5 = 5;
|
class RandomAccessRead {};
|
||||||
static const int VERSION_73 = 73;
|
class SequentialWrite {};
|
||||||
|
static const int Version5 = 5;
|
||||||
|
static const int Version73 = 73;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Index {
|
// predeclarations
|
||||||
private:
|
class IONode;
|
||||||
|
class IONodeIterator;
|
||||||
|
class MatlabIO;
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// FILE AS A DATA STRUCTURE
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
class IONode {
|
||||||
|
protected:
|
||||||
//! the name of the field (if associative container)
|
//! the name of the field (if associative container)
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
//! the size of the field
|
||||||
|
std::vector<size_t> size_;
|
||||||
//! beginning of the data field in the file
|
//! beginning of the data field in the file
|
||||||
size_t begin_;
|
size_t begin_;
|
||||||
//! address after the last data field
|
//! address after the last data field
|
||||||
@ -26,36 +46,126 @@ private:
|
|||||||
bool compressed_;
|
bool compressed_;
|
||||||
//! are the descendents associative (mappings)
|
//! are the descendents associative (mappings)
|
||||||
bool associative_;
|
bool associative_;
|
||||||
//! the descendents of this node
|
//! is this a leaf node containing data, or an interior node
|
||||||
union {
|
bool leaf_;
|
||||||
//! valid if the container is a sequence (list)
|
//! the data stream from which the file was indexed
|
||||||
std::vector<Index> sequence_;
|
cv::Ptr<std::istream> stream_;
|
||||||
//! valid if the container is a mapping (associative)
|
//! valid if the container is a sequence (list)
|
||||||
Map<std::string, Index> mapping_;
|
std::vector<IONode> sequence_;
|
||||||
};
|
//! valid if the container is a mapping (associative)
|
||||||
|
Map<std::string, IONode> mapping_;
|
||||||
|
IONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end,
|
||||||
|
int stored_type, int type, bool compressed, bool associative, bool leaf, istream& stream) :
|
||||||
|
name_(name), size_(size), begin_(begin), end_(end), stored_type_(stored_type), type_(type),
|
||||||
|
compressed_(compressed), associative_(associative), leaf_(leaf), stream_(stream) {}
|
||||||
|
public:
|
||||||
|
std::string name() const { return name_; }
|
||||||
|
std::vector<size_t> size() const { return size_; }
|
||||||
|
size_t begin() const { return begin_; }
|
||||||
|
size_t end() const { return end_; }
|
||||||
|
int stored_type() const { return stored_type_; }
|
||||||
|
int type() const { return type_; }
|
||||||
|
bool compressed() const { return compressed_; }
|
||||||
|
bool associative() const { return associative_; }
|
||||||
|
bool leaf() const { return leaf_; }
|
||||||
|
IONode() : begin_(0), end_(0), stored_type_(0), type_(0), leaf_(true) {}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
// conversion operators
|
||||||
|
template <typename T> void operator=(const T& obj) { static_assert(0, "Unimplemented specialization for given type"); }
|
||||||
|
template <typename T> operator T() { static_assert(0, "Unimplemented specialization for given type"); }
|
||||||
|
#else
|
||||||
|
// conversion operators
|
||||||
|
template <typename T> void operator=(const T& obj) { T::unimplemented_specialization; }
|
||||||
|
template <typename T> operator T() { T::unimplemented_specialization; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void swap(const IONode& other) {
|
||||||
|
using std::swap;
|
||||||
|
swap(name_, other.name_);
|
||||||
|
swap(size_, other.size_);
|
||||||
|
swap(begin_, other.begin_);
|
||||||
|
swap(end_, other.end_);
|
||||||
|
swap(stored_type_, other.stored_type_);
|
||||||
|
swap(type_, other.type_);
|
||||||
|
swap(compressed_, other.compressed_);
|
||||||
|
swap(associative_, other.associative_);
|
||||||
|
swap(leaf_, other.leaf_);
|
||||||
|
swap(stream_, other.stream_);
|
||||||
|
swap(sequence_, other.sequence_);
|
||||||
|
swap(mapping_, other.mapping_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SequenceIONode : public IONode {
|
||||||
|
public:
|
||||||
|
std::vector<IONode>& sequence() { return sequence_; }
|
||||||
|
SequenceIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end,
|
||||||
|
int stored_type, int type, const std::istream& stream) :
|
||||||
|
IONode(name, size, begin, end, stored_type, type, false, false, false, stream) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MappingIONode : public IONode {
|
||||||
|
public:
|
||||||
|
Map<std::string, IONode>& mapping() { return mapping_; }
|
||||||
|
MappingIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end,
|
||||||
|
int stored_type, int type, const std::istream& stream) :
|
||||||
|
IONode(name, size, begin, end, stored_type, type, false, true, false, stream) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class LeafIONode : public IONode {
|
||||||
|
LeafIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end,
|
||||||
|
int stored_type, int type, const std::istream& stream) :
|
||||||
|
IONode(name, size, begin, end, stored_type, type, false, false, true, stream) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompressedIONode : public IONode {
|
||||||
|
private:
|
||||||
|
std::istringstream uncompressed_stream_;
|
||||||
|
std::vector<char> data_;
|
||||||
|
public:
|
||||||
|
CompressedIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end,
|
||||||
|
int stored_type, int type, const std::stream& stream) :
|
||||||
|
IONode(name, size, begin, end, stored_type, type, true, false, false, stream) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Header : public IONode {
|
||||||
|
Header(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end,
|
||||||
|
int stored_type, int type, const std::stream& stream) :
|
||||||
|
IONode(name, size, begin, end, stored_type, type, true, false, false, stream) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// FILE NODE
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
class IONodeIterator : public std::iterator<std::random_access_iterator_tag, MatlabIONode> {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MatlabIONode {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// MATLABIO
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
class MatlabIO {
|
class MatlabIO {
|
||||||
private:
|
private:
|
||||||
// member variables
|
// member variables
|
||||||
static const int HEADER_LENGTH = 116;
|
static const int HEADER_LENGTH = 116;
|
||||||
static const int SUBSYS_LENGTH = 8;
|
static const int SUBSYS_LENGTH = 8;
|
||||||
static const int ENDIAN_LENGTH = 2;
|
static const int ENDIAN_LENGTH = 2;
|
||||||
char header_[HEADER_LENGTH+1];
|
std::string header_;
|
||||||
char subsys_[SUBSYS_LENGTH+1];
|
std::string subsys_;
|
||||||
char endian_[ENDIAN_LENGTH+1];
|
std::string endian_;
|
||||||
int version_;
|
int version_;
|
||||||
bool byte_swap_;
|
bool byte_swap_;
|
||||||
std::string filename_;
|
std::string filename_;
|
||||||
// uses a custom stream buffer for fast memory-mapped access and endian swapping
|
// uses a custom stream buffer for fast memory-mapped access and endian swapping
|
||||||
std::fstream stream_;
|
std::fstream stream_;
|
||||||
|
std::ifstream::pos_type stream_pos_;
|
||||||
//! the main file index. The top-level index must be associative
|
//! the main file index. The top-level index must be associative
|
||||||
Index index_;
|
IONode index_;
|
||||||
|
|
||||||
// internal methods
|
// internal methods
|
||||||
void getFileHeader();
|
void getFileHeader();
|
||||||
@ -64,18 +174,31 @@ private:
|
|||||||
void getHeader();
|
void getHeader();
|
||||||
void setHeader();
|
void setHeader();
|
||||||
|
|
||||||
|
CompressedIONode uncompress(const IONode& node);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// construct/destruct
|
// construct/destruct
|
||||||
MatlabIO() {}
|
MatlabIO() : header_(HEADER_LENGTH+1, '\0'), subsys_(SUBSYS_LENGTH+1, '\0'),
|
||||||
|
endian_(ENDIAN_LENGTH+1, '\0'), byte_swap(false), stream_pos_(0) {}
|
||||||
~MatlabIO {}
|
~MatlabIO {}
|
||||||
|
|
||||||
// global read and write routines
|
// global read and write routines
|
||||||
std::string filename(void);
|
std::string filename(void);
|
||||||
bool open(const std::string& filename, const std::string& mode);
|
bool open(const std::string& filename, std::ios_base::openmode mode);
|
||||||
|
bool isOpen() const;
|
||||||
|
void close();
|
||||||
|
void clear();
|
||||||
|
|
||||||
// index the contents of the file
|
// index the contents of the file
|
||||||
void index();
|
void index();
|
||||||
|
|
||||||
// print all of the top-level variables in the file
|
// print all of the top-level variables in the file
|
||||||
}
|
void printRootIndex() const;
|
||||||
|
void printFullIndex() const;
|
||||||
|
|
||||||
|
// FileNode operations
|
||||||
|
IONode root() const;
|
||||||
|
IONode operator[](const String& nodename) const;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -64,6 +64,33 @@ classdef OpenCVTest < matlab.unittest.TestCase
|
|||||||
testcase.verifyLessThan(norm(mt1 - mt2), 1e-8, 'Too much precision lost in tranposition');
|
testcase.verifyLessThan(norm(mt1 - mt2), 1e-8, 'Too much precision lost in tranposition');
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% multiple return
|
||||||
|
function multipleReturn(testcase)
|
||||||
|
A = randn(10);
|
||||||
|
A = A'*A;
|
||||||
|
[V1, D1] = eig(A); D1 = diag(D1);
|
||||||
|
[~, D2, V2] = cv.eigen(A);
|
||||||
|
testcase.verifyLessThan(norm(V1 - V2), 1e-6, 'Too much precision lost in eigenvectors');
|
||||||
|
testcase.verifyLessThan(norm(D1 - D2), 1e-6, 'Too much precision lost in eigenvalues');
|
||||||
|
end
|
||||||
|
|
||||||
|
% complex output from SVD
|
||||||
|
function complexOutputSVD(testcase)
|
||||||
|
A = randn(10);
|
||||||
|
[V1, D1] = eig(A);
|
||||||
|
[~, D2, V2] = cv.eigen(A);
|
||||||
|
testcase.verifyTrue(~isreal(V2) && size(V2,3) == 1, 'Output should be complex');
|
||||||
|
testcase.verifyLessThan(norm(V1 - V2), 1e-6, 'Too much precision lost in eigenvectors');
|
||||||
|
end
|
||||||
|
|
||||||
|
% complex output from Fourier Transform
|
||||||
|
function complexOutputFFT(testcase)
|
||||||
|
A = randn(10);
|
||||||
|
F1 = fft2(A);
|
||||||
|
F2 = cv.dft(A, cv.DFT_COMPLEX_OUTPUT);
|
||||||
|
testcase.verifyTrue(~isreal(F2) && size(F2,3) == 1, 'Output should be complex');
|
||||||
|
testcase.verifyLessThan(norm(F1 - F2), 1e-6, 'Too much precision lost in eigenvectors');
|
||||||
|
end
|
||||||
|
|
||||||
% -------------------------------------------------------------------------
|
% -------------------------------------------------------------------------
|
||||||
% TYPE CASTS
|
% TYPE CASTS
|
||||||
|
Loading…
x
Reference in New Issue
Block a user