Skip to content
Snippets Groups Projects
Commit 5ab0585d authored by moenck's avatar moenck
Browse files

greatly reduced utility

parent 810def6e
No related branches found
No related tags found
No related merge requests found
Pipeline #12462 passed
Showing
with 95 additions and 1059 deletions
......@@ -30,37 +30,20 @@ set_target_properties(${TN} PROPERTIES
target_sources(${TN}
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/settings/Settings.cpp"
"${CMAKE_CURRENT_LIST_DIR}/settings/StringTranslator.cpp"
"${CMAKE_CURRENT_LIST_DIR}/settings/SystemCompatibilityCheck.cpp"
"${CMAKE_CURRENT_LIST_DIR}/TrackedComponents/TrackedComponentFactory.cpp"
"${CMAKE_CURRENT_LIST_DIR}/TrackedComponents/TrackedElement.cpp"
"${CMAKE_CURRENT_LIST_DIR}/TrackedComponents/TrackedTrajectory.cpp"
"${CMAKE_CURRENT_LIST_DIR}/util/CvHelper.cpp"
"${CMAKE_CURRENT_LIST_DIR}/util/misc.cpp"
"${CMAKE_CURRENT_LIST_DIR}/util/stringTools.cpp"
"${CMAKE_CURRENT_LIST_DIR}/IConfig.cpp"
)
set(${TN}_PUBLIC_HEADERS
"${CMAKE_CURRENT_LIST_DIR}/settings/Messages.h"
"${CMAKE_CURRENT_LIST_DIR}/settings/ParamNames.h"
"${CMAKE_CURRENT_LIST_DIR}/settings/Settings.h"
"${CMAKE_CURRENT_LIST_DIR}/settings/StringTranslator.h"
"${CMAKE_CURRENT_LIST_DIR}/settings/SystemCompatibilityCheck.h"
"${CMAKE_CURRENT_LIST_DIR}/TrackedComponents/TrackedComponentFactory.h"
"${CMAKE_CURRENT_LIST_DIR}/TrackedComponents/TrackedElement.h"
"${CMAKE_CURRENT_LIST_DIR}/TrackedComponents/TrackedTrajectory.h"
"${CMAKE_CURRENT_LIST_DIR}/util/CvHelper.h"
"${CMAKE_CURRENT_LIST_DIR}/util/Exceptions.h"
"${CMAKE_CURRENT_LIST_DIR}/util/misc.h"
"${CMAKE_CURRENT_LIST_DIR}/util/MutexWrapper.h"
"${CMAKE_CURRENT_LIST_DIR}/util/PanZoomState.h"
"${CMAKE_CURRENT_LIST_DIR}/util/platform.h"
"${CMAKE_CURRENT_LIST_DIR}/util/QtRaiiWrapper.hpp"
"${CMAKE_CURRENT_LIST_DIR}/util/ScreenHelper.h"
"${CMAKE_CURRENT_LIST_DIR}/util/singleton.h"
"${CMAKE_CURRENT_LIST_DIR}/util/stdext.h"
"${CMAKE_CURRENT_LIST_DIR}/util/stringTools.h"
"${CMAKE_CURRENT_LIST_DIR}/util/ImagePreProcessor.h"
"${CMAKE_CURRENT_LIST_DIR}/util/IImageProcessor.h"
"${CMAKE_CURRENT_LIST_DIR}/IConfig.h"
)
\ No newline at end of file
#include "IConfig.h"
#include <QStandardPaths>
QString IConfig::configLocation = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
QString IConfig::dataLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
cv::Mat IConfig::asMat(QString str){
return asMat(str.toStdString());
}
std::vector<std::string> explode(std::string const & s, char delim)
{
std::vector<std::string> result;
std::istringstream iss(s);
for (std::string token; std::getline(iss, token, delim); )
{
result.push_back(std::move(token));
}
return result;
}
cv::Mat IConfig::asMat(std::string str){
std::vector<std::string> row = explode(str, ';');
std::vector<std::string> cols = explode(row[0], '#');
cv::Mat m(row.size(), cols.size(), CV_32F);
for (int i = 0; i < row.size(); i++) {
std::vector<std::string> cols = explode(row[i], '#');
for (int j = 0; j < cols.size(); j++) {
m.at<float>(i, j) = std::atof(cols[j].c_str());
}
}
return m;
};
std::string IConfig::asStdString(cv::Mat m){
return asQString(m).toStdString();
}
QString IConfig::asQString(cv::Mat m){
std::string result;
int w = m.size().width;
int h = m.size().height;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
result += std::to_string(m.at<float>(i, j));
if (j < w - 1)
result += "#";
}
result += ";";
}
return QString(result.c_str());
};
#pragma once
#include <QString>
#include <cv.h>
class IConfig
{
public:
static QString configLocation;
static QString dataLocation;
virtual void load(QString dir, QString file = "sampleConfig.ini") = 0;
virtual void save(QString dir, QString file) = 0;
static cv::Mat asMat(QString str);
static cv::Mat asMat(std::string str);
static std::string asStdString(cv::Mat m);
static QString asQString(cv::Mat m);
};
#pragma once
namespace BioTracker {
namespace Core {
namespace Messages {
namespace System {
static const std::string APPLICATION_CANNOT_START =
"Application cannot start";
static const std::string NO_OPENGL =
"This system has no OpenGL support!";
static const std::string MISSING_CONFIGURATION_FILE =
"Configuration file is missing! Using default parameters.";
}
enum class MessageType : size_t {
NOTIFICATION = 0,
WARNING,
FAIL,
FILE_OPEN
};
inline MessageType fromInt(const size_t v) {
return static_cast<MessageType>(v);
}
}
using Messages::MessageType;
}
}
#pragma once
#include <string> // std::string
#include <boost/filesystem.hpp>
#include <QDir>
#include <QStandardPaths>
namespace ConfigParam {
static const boost::filesystem::path CONFIG_PATH = boost::filesystem::path(
QDir::toNativeSeparators(
QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)).toStdString());
static const boost::filesystem::path BASE_PATH = CONFIG_PATH / "BioTracker";
static const boost::filesystem::path CONFIGURATION_FILE = BASE_PATH / "config.json";
static const boost::filesystem::path GEOMETRY_FILE = BASE_PATH / "geometry.cfg";
static const boost::filesystem::path STATE_FILE = BASE_PATH / "state.cfg";
static const boost::filesystem::path MODULE_PATH = BASE_PATH / "modules";
}
namespace TrackerParam {
static const std::string TRACKING_ENABLED = "TRACKERPARAM.TRACKING_ENABLED";
static const std::string SELECTED_TRACKER = "TRACKERPARAM.SELECTED_TRACKER";
}
namespace GuiParam {
enum class MediaType : uint8_t {
NoMedia = 0,
Video,
Images,
Camera
};
enum class VideoMode : uint8_t {
Playing = 0,
Paused,
Stopped,
Init
};
static const std::string MEDIA_TYPE = "GUIPARAM.MEDIA_TYPE";
static const std::string SHORTCUT_PLAY = "GUIPARAM.SHORTCUT_PLAY";
static const std::string SHORTCUT_NEXT = "GUIPARAM.SHORTCUT_NEXT";
static const std::string SHORTCUT_PREV = "GUIPARAM.SHORTCUT_PREV";
static const std::string SHORTCUT_ZOOM = "GUIPARAM.SHORTCUT_ZOOM";
static const std::string SHORTCUT_TRACKING = "GUIPARAM.SHORTCUT_TRACKING";
static const std::string PAUSED_AT_FRAME = "GUIPARAM.PAUSED_AT_FRAME";
}
namespace PictureParam {
//path to picture
static const std::string PICTURE_FILES = "PICTUREPARAM.PICTURE_FILES";
}
namespace CaptureParam {
// Video path
static const std::string CAP_VIDEO_FILE = "CAPTUREPARAM.CAP_VIDEO_FILE";
static const std::string CAP_SCREENSHOT_PATH =
"CAPTUREPARAM.CAP_SCREENSHOT_PATH";
static const std::string CAP_CAMERA_ID = "CAPTUREPARAM.CAP_CAMERA_ID";
// Video paths
static const std::string ENABLE_RECORD_RAW =
"CAPTUREPARAM.ENABLE_RECORD_RAW";
static const std::string ENABLE_RECORD_TRACKING =
"CAPTUREPARAM.ENABLE_RECORD_TRACKING";
static const std::string ENABLE_RECORD_TRACK_INFO =
"CAPTUREPARAM.ENABLE_RECORD_TRACK_INFO";
static const std::string RECORDING_TRACKING_PATH =
"CAPTUREPARAM.RECORDING_TRACKING_PATH";
static const std::string RECORDING_RAW_PATH =
"CAPTUREPARAM.RECORDING_RAW_PATH";
static const std::string TRACKING_INFO_OUTPUT_PATH =
"CAPTUREPARAM.TRACKING_INFO_OUTPUT_PATH";
enum CAP_TYPE_ENUM {
CAP_FROM_CAM = 0,
CAP_FROM_FILE = 1
};
enum CAP_STATE_ENUM {
CAP_FINISHED = 0,
CAP_PAUSE = 1,
CAP_AVAILABLE = 2,
CAP_EXITED = 3
};
}
#include "settings/Settings.h"
#include <QFile>
#include <QMessageBox>
#include "util/Exceptions.h"
#include "settings/Messages.h"
namespace boost {
void throw_exception(std::exception const & e) {};
}
namespace BioTracker {
namespace Core {
const boost::property_tree::ptree Settings::getDefaultParams() {
boost::property_tree::ptree pt;
return pt;
}
}
}
#pragma once
#include <type_traits>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include "../util/stringTools.h" // (un)escape_non_ascii
#include "StringTranslator.h"
#include "ParamNames.h"
#include <mutex>
#include "util/singleton.h"
#define GET_CORESETTINGS BioTracker::Util::TypedSingleton<BioTracker::Core::Settings>::getInstance
namespace {
template<typename Test, template<typename...> class Ref>
struct is_specialization : std::false_type {};
template<template<typename...> class Ref, typename... Args>
struct is_specialization<Ref<Args...>, Ref>: std::true_type {};
}
namespace BioTracker {
namespace Core {
class Settings {
private:
std::string _confFile;
std::mutex _m;
std::map<std::string, void*> _dataStore;
public:
/* This is a singleton. Get it using something like:
* SettingsIAC *myInstance = SettingsIAC::getInstance();
*/
Settings(std::string config) {
//_m.lock();
//Setting default file, if unset
if (config == "") _confFile = "config.ini";
else _confFile = config;
std::ifstream conf(_confFile.c_str());
if (conf.good())
{
boost::property_tree::read_json(_confFile, _ptree);
}
else {
_ptree = getDefaultParams();
boost::property_tree::write_json(_confFile, _ptree);
}
//_m.unlock();
}
void storeValue(std::string key, void* value) {
_dataStore.insert(std::pair<std::string, void*>(key, value));
}
void* readValue(std::string key) {
std::map<std::string, void*>::iterator it = _dataStore.find(key);
if (it != _dataStore.end()) {
return it->second;
}
return nullptr;
}
// C++ 11 style
// =======
Settings(Settings const&) = delete;
void operator=(Settings const&) = delete;
/**
* Sets the parameter.
* @param paramName name of the parameter,
* @param paramValue value of the parameter,
*/
template <typename T>
void setParam(std::string const &paramName, T &&paramValue) {
//_m.lock();
_ptree.put(paramName, preprocess_value(std::forward<T>(paramValue)));
boost::property_tree::write_json(_confFile, _ptree);
//_m.unlock();
}
/**
* Sets the vector of values of a parameter.
* @param paramName name of the parameter,
* @param paramVector vector of values of the parameter,
*/
template <typename T>
void setParam(std::string const &paramName, std::vector<T> &&paramVector) {
//_m.lock();
boost::property_tree::ptree subtree;
for (T &value : paramVector) {
boost::property_tree::ptree valuetree;
valuetree.put("", value);
subtree.push_back(std::make_pair("", valuetree));
}
_ptree.put_child(paramName, subtree);
boost::property_tree::write_json(_confFile, _ptree);
//_m.unlock();
}
/**
* Gets the parameter value provided by parameter name.
* @param paramName the parameter name,
* @return the value of the parameter as the specified type.
*/
template <typename T>
typename std::enable_if<!is_specialization<T, std::vector>::value, T>::type
getValueOfParam(const std::string &paramName) const {
//_m.lock();
auto a = postprocess_value(_ptree.get<T>(paramName));
//_m.unlock();
return a;
}
/**
* Gets the vector of values provided by parameter name.
*
* Throws an boost exception if parameter does not exist.
*
* @param paramName the parameter name,
* @return the vector of values of the parameter with the specified type.
*/
template <typename T>
typename std::enable_if<is_specialization<T, std::vector>::value, T>::type
getValueOfParam(const std::string &paramName) const {
//_m.lock();
T result;
for (auto &item : _ptree.get_child(paramName)) {
result.push_back(postprocess_value(
item.second.get_value<typename T::value_type>()));
}
//_m.unlock();
return result;
}
/**
* Gets either the parameter value provided by parameter name, if it
* exists, or a empty boost::optional<T> otherwise.
* @param paramName the parameter name,
* @return the value of the parameter wrapped in a boost::optional.
*/
template <typename T>
boost::optional<T> maybeGetValueOfParam(const std::string &paramName) {
//_m.lock();
auto a = _ptree.get_optional<T>(paramName);
//_m.unlock();
return a;
}
/**
* Gets the parameter value provided by parameter name.
* If the parameter is not set yet, set to default value and return it.
* @param paramName the parameter name,
* @param defaultValue the default parameter value,
* @return the value of the parameter as the specified type.
*/
template <typename T>
T getValueOrDefault(const std::string &paramName, const T &defaultValue) {
//_m.lock();
boost::optional<T> value = maybeGetValueOfParam<T>(paramName);
T t;
if (value) {
t = value.get();
} else {
setParam(paramName, defaultValue);
t = defaultValue;
}
//_m.unlock();
return t;
}
private:
boost::property_tree::ptree _ptree;
static const boost::property_tree::ptree getDefaultParams();
/**
* preprocesses paramValue before it's stored in the boost config tree
*
* default implementation: forward value
*
*/
template<typename T>
static T preprocess_value(T &&paramValue) {
return std::forward<T>(paramValue);
}
/**
* postprocesses paramValue after it's extracted from the boost config tree
*
* default implementation: forward value
*
*/
template<typename T>
static T postprocess_value(T &&paramValue) {
return std::forward<T>(paramValue);
}
};
/**
* std::string specialisation as a workaround for a bug in boost's config tree
*
* this function escapes every non-ASCII character
*
* (the tree correctly escapes non-ASCII characters and stores them
* as "\u00XX" where XX is the character's hex value, but it can't read these
* values correctly)
*
*/
template<>
inline std::string Settings::preprocess_value(std::string &&paramValue) {
return Util::escape_non_ascii(paramValue);
}
/**
* std::string specialisation as a workaround for a bug in boost's config tree
*
* (the tree converts escaped non-ASCII characters ("\u00XX") to "\xFF")
*
*/
template<>
inline std::string Settings::postprocess_value(std::string &&paramValue) {
return Util::unescape_non_ascii(paramValue);
}
}
}
#include "settings/StringTranslator.h"
#pragma once
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp>
#include "ParamNames.h"
#include "settings/SystemCompatibilityCheck.h"
//#include <QGLFormat>
bool SystemCompatibilityCheck::checkOpenGLSupport() {
return true;//QGLFormat::hasOpenGL();
}
#pragma once
#include "util/platform.h"
namespace SystemCompatibilityCheck {
/**
* Check the system supports openGL.
* @return true, system supports openGL, false otherwise.
*/
bool BIOTRACKER_DLLEXPORT checkOpenGLSupport();
}
/*
* CvHelper.cpp
*
* Created on: May 12, 2015
* Author: tobias
*/
#include "util/CvHelper.h"
namespace BioTracker {
namespace Core {
namespace CvHelper {
std::string cvDataType2str(int type) {
const int depth = CV_MAT_DEPTH(type);
const int cn = CV_MAT_CN(type);
std::string result = "CV_";
switch (depth) {
case CV_8U:
result += "8U";
break;
case CV_8S:
result += "8S";
break;
case CV_16U:
result += "16U";
break;
case CV_16S:
result += "16S";
break;
case CV_32S:
result += "32S";
break;
case CV_32F:
result += "32F";
break;
case CV_64F:
result += "64F";
break;
default:
result += "UNKOWN";
break;
}
result += "C" + std::to_string(cn);
return result;
}
}
}
}
#pragma once
#include <opencv2/opencv.hpp> // cv::Point, cv::Rect
#include <QRect> // QRect
#include <QPoint> // QPoint
#include <string> // std::string; std::to_string(int)
/**
* Computer vision helper functions
*/
namespace BioTracker {
namespace Core {
namespace CvHelper {
struct cv_point_compare_less_x {
template<typename CV_POINT>
bool operator()(const CV_POINT &lhs, const CV_POINT &rhs) const {
return lhs.x < rhs.x;
}
};
struct cv_point_compare_less_y {
template<typename CV_POINT>
bool operator()(const CV_POINT &lhs, const CV_POINT &rhs) const {
return lhs.y < rhs.y;
}
};
inline cv::Rect toCv(const QRect &rect) {
return cv::Rect(rect.x(), rect.y(), rect.width(), rect.height());
}
inline QRect toQt(const cv::Rect &rect) {
return QRect(rect.x,rect.y,rect.width,rect.height);
}
inline QPoint toQt(const cv::Point &point) {
return QPoint(point.x, point.y);
}
/**
* @see: http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare
*/
struct cv_vec_compare_less_lexicographically {
template<typename CV_VEC>
bool operator()(const CV_VEC &lhs, const CV_VEC &rhs) const {
for (int i = 0; i < CV_VEC::channels; ++i) {
if (lhs[i] < rhs[i]) {
return true;
}
if (rhs[i] < lhs[i]) {
return false;
}
}
return false;
}
};
/**
* converts an opencv data type value (int) to the name of the corresponding macro i.e. "CV_\d+[UFS]C\d"
*
* @see: cv::DataType<T>::type
*
* @example:
* CvHelper::cvDataType2str( CV_8UC3 ) --> std::string( "CV_8UC3" )
*
*/
std::string cvDataType2str(int type);
}
}
}
#pragma once
#include <stdexcept>
namespace BioTracker {
namespace Core {
struct video_open_error : std::invalid_argument {
using std::invalid_argument::invalid_argument;
};
struct file_not_found : std::invalid_argument {
using std::invalid_argument::invalid_argument;
};
struct directory_not_found : std::invalid_argument {
using std::invalid_argument::invalid_argument;
};
struct device_open_error : std::invalid_argument {
using std::invalid_argument::invalid_argument;
};
struct invalid_tracker_lib_error : std::invalid_argument {
using std::invalid_argument::invalid_argument;
};
struct path_creation_error : std::runtime_error {
using std::runtime_error::runtime_error;
};
}
}
#ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H
#define THREAD_SAFETY_ANALYSIS_MUTEX_H
#include <mutex>
// Enable thread safety attributes only with clang.
// The attributes can be safely erased when compiling with other compilers.
#if defined(__clang__) && (!defined(SWIG))
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
#define CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define SCOPED_CAPABILITY \
THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define GUARDED_BY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define PT_GUARDED_BY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define ACQUIRED_BEFORE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
#define ACQUIRED_AFTER(...) \
THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
#define REQUIRES(...) \
THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
#define REQUIRES_SHARED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
#define ACQUIRE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
#define ACQUIRE_SHARED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
#define RELEASE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
#define RELEASE_SHARED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
#define TRY_ACQUIRE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
#define TRY_ACQUIRE_SHARED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
#define EXCLUDES(...) \
THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define ASSERT_CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
#define ASSERT_SHARED_CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
#define RETURN_CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#define NO_THREAD_SAFETY_ANALYSIS \
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
// Defines an annotated interface for mutexes.
// These methods can be implemented to use any internal mutex implementation.
class CAPABILITY("mutex") Mutex {
public:
// Acquire/lock this mutex exclusively. Only one thread can have exclusive
// access at any one time. Write operations to guarded data require an
// exclusive lock.
void Lock() ACQUIRE() {
mutex.lock();
}
// Acquire/lock this mutex for read operations, which require only a shared
// lock. This assumes a multiple-reader, single writer semantics. Multiple
// threads may acquire the mutex simultaneously as readers, but a writer
// must wait for all of them to release the mutex before it can acquire it
// exclusively.
void ReaderLock() ACQUIRE_SHARED();
// Release/unlock an exclusive mutex.
void Unlock() RELEASE() {
mutex.unlock();
}
// Release/unlock a shared mutex.
void ReaderUnlock() RELEASE_SHARED();
// Try to acquire the mutex. Returns true on success, and false on failure.
bool TryLock() TRY_ACQUIRE(true) {
return mutex.try_lock();
}
// Try to acquire the mutex for read operations.
bool ReaderTryLock() TRY_ACQUIRE_SHARED(true);
// Assert that this mutex is currently held by the calling thread.
void AssertHeld() ASSERT_CAPABILITY(this);
// Assert that is mutex is currently held for read operations.
void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this);
private:
std::mutex mutex;
};
// MutexLocker is an RAII class that acquires a mutex in its constructor, and
// releases it in its destructor.
class SCOPED_CAPABILITY MutexLocker {
private:
Mutex &mutex;
public:
MutexLocker(Mutex &mu) ACQUIRE(mu) : mutex(mu) {
mutex.Lock();
}
~MutexLocker() RELEASE() {
mutex.Unlock();
}
};
#ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
// The original version of thread safety analysis the following attribute
// definitions. These use a lock-based terminology. They are still in use
// by existing thread safety code, and will continue to be supported.
// Deprecated.
#define PT_GUARDED_VAR \
THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded)
// Deprecated.
#define GUARDED_VAR \
THREAD_ANNOTATION_ATTRIBUTE__(guarded)
// Replaced by REQUIRES
#define EXCLUSIVE_LOCKS_REQUIRED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
// Replaced by REQUIRES_SHARED
#define SHARED_LOCKS_REQUIRED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
// Replaced by CAPABILITY
#define LOCKABLE \
THREAD_ANNOTATION_ATTRIBUTE__(lockable)
// Replaced by SCOPED_CAPABILITY
#define SCOPED_LOCKABLE \
THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
// Replaced by ACQUIRE
#define EXCLUSIVE_LOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
// Replaced by ACQUIRE_SHARED
#define SHARED_LOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
// Replaced by RELEASE and RELEASE_SHARED
#define UNLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
// Replaced by TRY_ACQUIRE
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
// Replaced by TRY_ACQUIRE_SHARED
#define SHARED_TRYLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
// Replaced by ASSERT_CAPABILITY
#define ASSERT_EXCLUSIVE_LOCK(...) \
THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
// Replaced by ASSERT_SHARED_CAPABILITY
#define ASSERT_SHARED_LOCK(...) \
THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
// Replaced by EXCLUDE_CAPABILITY.
#define LOCKS_EXCLUDED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
// Replaced by RETURN_CAPABILITY
#define LOCK_RETURNED(x) \
THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#endif // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
#endif // THREAD_SAFETY_ANALYSIS_MUTEX_H
#pragma once
#include "boost/optional.hpp"
namespace BioTracker {
namespace Core {
/**
* @brief Used to store mouse cursor offsets while panning.
*/
struct CurrentPanState {
QPointF lastPos;
CurrentPanState(const QPointF lastPos)
: lastPos(lastPos) {
}
};
/**
* @brief Stores the current zoom and pan offsets. While panning, panState stores the last mouse cursor position.
*/
struct PanZoomState {
float zoomFactor = 0.f;
float panX = 0.f;
float panY = 0.f;
bool isChanged = false;
boost::optional<CurrentPanState> panState;
};
}
}
#pragma once
namespace BioTracker {
namespace Util {
/**
* source: http://stackoverflow.com/a/28125217
*/
template<typename UiClass, typename ParentClass> class QtRaiiWrapper : public UiClass
{
public:
QtRaiiWrapper(ParentClass *parent)
{
this->setupUi(parent);
}
};
}
}
#pragma once
#include <QRect> // QRect
#include <QPoint> // QPoint
#include "PanZoomState.h"
#include "math.h"
/**
* Screen helper functions
*/
namespace BioTracker {
namespace Core {
namespace ScreenHelper {
/**
* @brief calculate_viewport
* @param im_w width of the image
* @param im_h height of the image
* @param w width of the videoview
* @param h height of the videoview
* @param window OUT parameter
* @param viewport OUT parameter
*/
inline float calculate_viewport(
const int im_w, const int im_h,
const int w, const int h,
QRect &window, QRect &viewport) {
// We use setWindow and setViewport to fit the video into the
// given video widget frame (with width "w" and height "h")
// we later need to adjust an offset caused the use of different
// dimensions for window and viewport.
const float im_wf = static_cast<float>(im_w);
const float im_hf = static_cast<float>(im_h);
const float w_f = static_cast<float>(w);
const float h_f = static_cast<float>(h);
float ratio = 0;
int offset_top = 0;
int offset_left = 0;
if ((im_wf/im_hf) > (w_f/h_f)) {
// image ratio is bigger (wider image than window)
ratio = im_wf / w_f;
const float px = w_f / im_wf;
const float px_im_hf = px * im_hf;
offset_top = h/2 - static_cast<int>(px_im_hf / 2);
} else {
// window ratio is bigger (narrow image)
ratio = im_hf / h_f;
const float px = h_f / im_hf;
const float px_im_wf = px * im_wf;
offset_left = w/2 - static_cast<int>(px_im_wf / 2);
}
const int screen_w = static_cast<int>(im_wf * ratio);
const int screen_h = static_cast<int>(im_hf * ratio);
window.setX(0);
window.setY(0);
window.setWidth(screen_w);
window.setHeight(screen_h);
viewport.setX(offset_left);
viewport.setY(offset_top);
viewport.setWidth(im_w);
viewport.setHeight(im_h);
// adjust the panning as the viewport is potentially scewed
// and mouse movements given by the window are not translated
// one-to-one anymore
return screen_w / im_wf;
}
/**
* @brief getImDimsInScreenCoords
* Calculates the actual dimension of the image with all zoom, pan and
* viewport transformations applied
* @return a rectangle that represents the position and dimension of the
* image in the videoview element
*/
inline QRect getImDimsInScreenCoords(
const PanZoomState zoomState,
const int im_w, const int im_h,
const int w, const int h) {
QRect viewport, window;
const float viewportRatio = calculate_viewport(im_w, im_h, w, h, window, viewport);
const float zoom = 1 + zoomState.zoomFactor;
// back-translate the pan to non-zoomed coordinate space
float realPanX = -zoomState.panX;
float realPanY = -zoomState.panY;
realPanX += (viewport.x());
realPanY += (viewport.y());
// The image in screen coords
QRect actualIm(
static_cast<int>(realPanX), static_cast<int>(realPanY),
static_cast<int>((im_w / viewportRatio) * zoom),
static_cast<int>((im_h / viewportRatio) * zoom)
);
return actualIm;
}
/**
* @brief imageToScreenCoords
*/
inline QPoint imageToScreenCoords(
const PanZoomState zoomState,
const int im_w, const int im_h,
const int w, const int h,
const QPoint poi) {
QPoint result;
const QRect actualIm = getImDimsInScreenCoords(zoomState, im_w, im_h, w, h);
const float one_step_x = actualIm.width() / static_cast<float>(im_w);
const float one_step_y = actualIm.height() / static_cast<float>(im_h);
const int actualPosXInIm = static_cast<int>(round(poi.x() * one_step_x));
const int actualPosYInIm = static_cast<int>(round(poi.y() * one_step_y));
result.setX(actualPosXInIm + actualIm.x());
result.setY(actualPosYInIm + actualIm.y());
return result;
}
/**
* @brief screenToImageCoords
* Translate the window coordinates to the actual image coords
* @param im_w image width
* @param im_h image height
* @param w width of the videoview
* @param h height of the videoview
* @param poi Point in Screen Coords
*/
inline QPoint screenToImageCoords(
const BioTracker::Core::PanZoomState zoomState,
const int im_w, const int im_h,
const int w, const int h,
QPoint poi) {
QPoint result(0, 0);
// The image in screen coords
QRect actualIm = getImDimsInScreenCoords(zoomState, im_w, im_h, w, h);
const float im_wf = static_cast<float>(im_w);
const float im_hf = static_cast<float>(im_h);
const float one_step_x = im_wf / actualIm.width();
const float one_step_y = im_hf / actualIm.height();
const float transformedX = (-actualIm.x() + poi.x()) * one_step_x;
const float transformedY = (-actualIm.y() + poi.y()) * one_step_y;
result.setX(static_cast<int>(round(transformedX)));
result.setY(static_cast<int>(round(transformedY)));
return result;
}
/**
* @brief zoomTo
* Modifies the panzoomstate so that the cursor (zoomCenter) will point to the same
* location in the image as prior to the zoom
* @param im_w width of the image (in px)
* @param im_h height of the image (in px)
* @param w width of the videoview element
* @param h height of the videoview element
*/
inline PanZoomState zoomTo(
PanZoomState state,
const int im_w,
const int im_h,
const int w,
const int h,
const float deltaZoom,
const QPoint zoomCenter) {
const QPoint imPos = screenToImageCoords(state, im_w, im_h, w, h, zoomCenter);
const float oldZoomFactor = state.zoomFactor;
const float newZoomFactor = state.zoomFactor - (deltaZoom/2000);
if (newZoomFactor <= -1.0f) {
// MAX VALUE
return state;
}
const float zoom = 1 + newZoomFactor;
const float oldPanX = state.panX / (1 + oldZoomFactor);
const float oldPanY = state.panY / (1 + oldZoomFactor);
// zoom with origin in (0/0)
state.panX = oldPanX * zoom;
state.panY = oldPanY * zoom;
state.zoomFactor = newZoomFactor;
// As we do not want to zoom to (0/0) but rather keep the focus on the chosen
// image position (zoomCenter) we now have to "back-translate" to our initial
// position
const QPoint translatedZoomCenter = imageToScreenCoords(state, im_w, im_h, w, h, imPos);
const QPoint translate = translatedZoomCenter - zoomCenter;
state.panX += translate.x();
state.panY += translate.y();
state.isChanged = true;
return state;
}
}
}
}
......@@ -4,7 +4,7 @@
#include <QString>
#include <QStringList>
int split(std::string &txt, std::vector<std::string> &strs, char ch)
int BioTrackerUtilsMisc::split(std::string &txt, std::vector<std::string> &strs, char ch)
{
std::string::size_type pos = txt.find(ch);
std::string::size_type initialPos = 0;
......@@ -24,7 +24,7 @@ int split(std::string &txt, std::vector<std::string> &strs, char ch)
return strs.size();
}
std::string getTimeAndDate(std::string prefix, std::string suffix)
std::string BioTrackerUtilsMisc::getTimeAndDate(std::string prefix, std::string suffix)
{
// time_t timetitle;
// std::string timeInfo = prefix;
......@@ -59,7 +59,7 @@ std::string getTimeAndDate(std::string prefix, std::string suffix)
return out;
}
std::vector<cv::Point> stringToCVPointVec(std::string arena) {
std::vector<cv::Point> BioTrackerUtilsMisc::stringToCVPointVec(std::string arena) {
std::vector<cv::Point> pts;
QString qarena(arena.c_str());
......@@ -73,20 +73,20 @@ std::vector<cv::Point> stringToCVPointVec(std::string arena) {
}
std::vector<cv::Point> QVecToCvVec(std::vector<QPoint> q) {
std::vector<cv::Point> BioTrackerUtilsMisc::QVecToCvVec(std::vector<QPoint> q) {
std::vector<cv::Point> v;
for (int i = 0; i < q.size(); i++)
v.push_back(cv::Point(q[i].x(), q[i].y()));
return v;
}
std::vector<QPoint> CvVecToQVec(std::vector<cv::Point> q) {
std::vector<QPoint> BioTrackerUtilsMisc::CvVecToQVec(std::vector<cv::Point> q) {
std::vector<QPoint> v;
for (int i = 0; i < q.size(); i++)
v.push_back(QPoint(q[i].x, q[i].y));
return v;
}
std::string cvPointsToString(std::vector<cv::Point> ac) {
std::string BioTrackerUtilsMisc::cvPointsToString(std::vector<cv::Point> ac) {
std::string arena = "";
for (int i = 0; i < ac.size(); i++)
......
......@@ -5,10 +5,12 @@
#include <cv.h>
#include <QPoint>
namespace BioTrackerUtilsMisc{
int split(std::string &txt, std::vector<std::string> &strs, char ch);
std::string getTimeAndDate(std::string prefix, std::string suffix);
std::vector<cv::Point> stringToCVPointVec(std::string arena);
std::vector<cv::Point> QVecToCvVec(std::vector<QPoint> q);
std::string cvPointsToString(std::vector<cv::Point> ac);
std::vector<QPoint> CvVecToQVec(std::vector<cv::Point> q);
}
#endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment