parent
071b7ae127
commit
6f1b6eb469
8 changed files with 969 additions and 21 deletions
@ -0,0 +1,88 @@ |
||||
#pragma once |
||||
#ifndef CMTIMER_H |
||||
#define CMTIMER_H |
||||
|
||||
#include "kyheader.h" |
||||
|
||||
class CmTimer |
||||
{ |
||||
public: |
||||
CmTimer(CStr t):title(t) { is_started = false; start_clock = 0; cumulative_clock = 0; n_starts = 0; } |
||||
|
||||
~CmTimer(){ if (is_started) printf("CmTimer '%s' is started and is being destroyed.\n", title.c_str()); } |
||||
|
||||
inline void Start(); |
||||
inline void Stop(); |
||||
inline void Reset(); |
||||
|
||||
inline bool Report(); |
||||
inline bool StopAndReport() { Stop(); return Report(); } |
||||
inline float TimeInSeconds(); |
||||
|
||||
private: |
||||
CStr title; |
||||
|
||||
bool is_started; |
||||
clock_t start_clock; |
||||
clock_t cumulative_clock; |
||||
unsigned int n_starts; |
||||
}; |
||||
|
||||
/************************************************************************/ |
||||
/* Implementations */ |
||||
/************************************************************************/ |
||||
|
||||
void CmTimer::Start() |
||||
{ |
||||
if (is_started){ |
||||
printf("CmTimer '%s' is already started. Nothing done.\n", title.c_str()); |
||||
return; |
||||
} |
||||
|
||||
is_started = true; |
||||
n_starts++; |
||||
start_clock = clock(); |
||||
} |
||||
|
||||
void CmTimer::Stop() |
||||
{ |
||||
if (!is_started){ |
||||
printf("CmTimer '%s' is started. Nothing done\n", title.c_str()); |
||||
return; |
||||
} |
||||
|
||||
cumulative_clock += clock() - start_clock; |
||||
is_started = false; |
||||
} |
||||
|
||||
void CmTimer::Reset() |
||||
{ |
||||
if (is_started) { |
||||
printf("CmTimer '%s'is started during reset request.\n Only reset cumulative time.\n"); |
||||
return; |
||||
} |
||||
cumulative_clock = 0; |
||||
} |
||||
|
||||
bool CmTimer::Report() |
||||
{ |
||||
if (is_started){ |
||||
printf("CmTimer '%s' is started.\n Cannot provide a time report.", title.c_str()); |
||||
return false; |
||||
} |
||||
|
||||
float timeUsed = TimeInSeconds(); |
||||
printf("[%s] CumuTime: %gs, #run: %d, AvgTime: %gs\n", title.c_str(), timeUsed, n_starts, timeUsed/n_starts); |
||||
return true; |
||||
} |
||||
|
||||
float CmTimer::TimeInSeconds() |
||||
{ |
||||
if (is_started){ |
||||
printf("CmTimer '%s' is started. Nothing done\n", title.c_str()); |
||||
return 0; |
||||
} |
||||
return float(cumulative_clock) / CLOCKS_PER_SEC; |
||||
} |
||||
|
||||
#endif // CMTIMER_H
|
@ -0,0 +1,78 @@ |
||||
#include "kyheader.h" |
||||
#include "FilterTIG.h" |
||||
#include "CmShow.h" |
||||
|
||||
|
||||
void FilterTIG::update(CMat &w1f){ |
||||
CV_Assert(w1f.cols * w1f.rows == D && w1f.type() == CV_32F && w1f.isContinuous()); |
||||
float b[D], residuals[D]; |
||||
memcpy(residuals, w1f.data, sizeof(float)*D); |
||||
for (int i = 0; i < NUM_COMP; i++){ |
||||
float avg = 0; |
||||
for (int j = 0; j < D; j++){ |
||||
b[j] = residuals[j] >= 0.0f ? 1.0f : -1.0f; |
||||
avg += residuals[j] * b[j]; |
||||
} |
||||
avg /= D; |
||||
_coeffs1[i] = avg, _coeffs2[i] = avg*2, _coeffs4[i] = avg*4, _coeffs8[i] = avg*8; |
||||
for (int j = 0; j < D; j++) |
||||
residuals[j] -= avg*b[j]; |
||||
UINT64 tig = 0; |
||||
for (int j = 0; j < D; j++) |
||||
tig = (tig << 1) | (b[j] > 0 ? 1 : 0); |
||||
_bTIGs[i] = tig; |
||||
} |
||||
} |
||||
|
||||
void FilterTIG::reconstruct(Mat &w1f){ |
||||
w1f = Mat::zeros(8, 8, CV_32F); |
||||
float *weight = (float*)w1f.data; |
||||
for (int i = 0; i < NUM_COMP; i++){ |
||||
UINT64 tig = _bTIGs[i]; |
||||
for (int j = 0; j < D; j++) |
||||
weight[j] += _coeffs1[i] * (((tig >> (63-j)) & 1) ? 1 : -1); |
||||
} |
||||
} |
||||
|
||||
// For a W by H gradient magnitude map, find a W-7 by H-7 CV_32F matching score map
|
||||
// Please refer to my paper for definition of the variables used in this function
|
||||
Mat FilterTIG::matchTemplate(const Mat &mag1u){ |
||||
const int H = mag1u.rows, W = mag1u.cols; |
||||
const Size sz(W+1, H+1); // Expand original size to avoid dealing with boundary conditions
|
||||
Mat_<INT64> Tig1 = Mat_<INT64>::zeros(sz), Tig2 = Mat_<INT64>::zeros(sz); |
||||
Mat_<INT64> Tig4 = Mat_<INT64>::zeros(sz), Tig8 = Mat_<INT64>::zeros(sz); |
||||
Mat_<byte> Row1 = Mat_<byte>::zeros(sz), Row2 = Mat_<byte>::zeros(sz); |
||||
Mat_<byte> Row4 = Mat_<byte>::zeros(sz), Row8 = Mat_<byte>::zeros(sz); |
||||
Mat_<float> scores(sz); |
||||
for(int y = 1; y <= H; y++){ |
||||
const byte* G = mag1u.ptr<byte>(y-1); |
||||
INT64* T1 = Tig1.ptr<INT64>(y); // Binary TIG of current row
|
||||
INT64* T2 = Tig2.ptr<INT64>(y); |
||||
INT64* T4 = Tig4.ptr<INT64>(y); |
||||
INT64* T8 = Tig8.ptr<INT64>(y); |
||||
INT64* Tu1 = Tig1.ptr<INT64>(y-1); // Binary TIG of upper row
|
||||
INT64* Tu2 = Tig2.ptr<INT64>(y-1); |
||||
INT64* Tu4 = Tig4.ptr<INT64>(y-1); |
||||
INT64* Tu8 = Tig8.ptr<INT64>(y-1); |
||||
byte* R1 = Row1.ptr<byte>(y); |
||||
byte* R2 = Row2.ptr<byte>(y); |
||||
byte* R4 = Row4.ptr<byte>(y); |
||||
byte* R8 = Row8.ptr<byte>(y); |
||||
float *s = scores.ptr<float>(y); |
||||
for (int x = 1; x <= W; x++) { |
||||
byte g = G[x-1]; |
||||
R1[x] = (R1[x-1] << 1) | ((g >> 4) & 1); |
||||
R2[x] = (R2[x-1] << 1) | ((g >> 5) & 1); |
||||
R4[x] = (R4[x-1] << 1) | ((g >> 6) & 1); |
||||
R8[x] = (R8[x-1] << 1) | ((g >> 7) & 1); |
||||
T1[x] = (Tu1[x] << 8) | R1[x]; |
||||
T2[x] = (Tu2[x] << 8) | R2[x]; |
||||
T4[x] = (Tu4[x] << 8) | R4[x]; |
||||
T8[x] = (Tu8[x] << 8) | R8[x]; |
||||
s[x] = dot(T1[x], T2[x], T4[x], T8[x]); |
||||
} |
||||
} |
||||
Mat matchCost1f; |
||||
scores(Rect(8, 8, W-7, H-7)).copyTo(matchCost1f); |
||||
return matchCost1f; |
||||
} |
@ -0,0 +1,45 @@ |
||||
#pragma once |
||||
#include "kyheader.h" |
||||
class FilterTIG |
||||
{ |
||||
public: |
||||
void update(CMat &w); |
||||
|
||||
// For a W by H gradient magnitude map, find a W-7 by H-7 CV_32F matching score map
|
||||
Mat matchTemplate(const Mat &mag1u); |
||||
|
||||
inline float dot(const INT64 tig1, const INT64 tig2, const INT64 tig4, const INT64 tig8); |
||||
|
||||
public: |
||||
void reconstruct(Mat &w); // For illustration purpose
|
||||
|
||||
private: |
||||
static const int NUM_COMP = 2; // Number of components
|
||||
static const int D = 64; // Dimension of TIG
|
||||
INT64 _bTIGs[NUM_COMP]; // Binary TIG features
|
||||
float _coeffs1[NUM_COMP]; // Coefficients of binary TIG features
|
||||
|
||||
// For efficiently deals with different bits in CV_8U gradient map
|
||||
float _coeffs2[NUM_COMP], _coeffs4[NUM_COMP], _coeffs8[NUM_COMP]; |
||||
}; |
||||
|
||||
|
||||
inline float FilterTIG::dot(const INT64 tig1, const INT64 tig2, const INT64 tig4, const INT64 tig8) |
||||
{ |
||||
INT64 bcT1 = __builtin_popcountll(tig1); |
||||
INT64 bcT2 = __builtin_popcountll(tig2); |
||||
INT64 bcT4 = __builtin_popcountll(tig4); |
||||
INT64 bcT8 = __builtin_popcountll(tig8); |
||||
|
||||
INT64 bc01 = (__builtin_popcountll(_bTIGs[0] & tig1) << 1) - bcT1; |
||||
INT64 bc02 = ((__builtin_popcountll(_bTIGs[0] & tig2) << 1) - bcT2) << 1; |
||||
INT64 bc04 = ((__builtin_popcountll(_bTIGs[0] & tig4) << 1) - bcT4) << 2; |
||||
INT64 bc08 = ((__builtin_popcountll(_bTIGs[0] & tig8) << 1) - bcT8) << 3; |
||||
|
||||
INT64 bc11 = (__builtin_popcountll(_bTIGs[1] & tig1) << 1) - bcT1; |
||||
INT64 bc12 = ((__builtin_popcountll(_bTIGs[1] & tig2) << 1) - bcT2) << 1; |
||||
INT64 bc14 = ((__builtin_popcountll(_bTIGs[1] & tig4) << 1) - bcT4) << 2; |
||||
INT64 bc18 = ((__builtin_popcountll(_bTIGs[1] & tig8) << 1) - bcT8) << 3; |
||||
|
||||
return _coeffs1[0] * (bc01 + bc02 + bc04 + bc08) + _coeffs1[1] * (bc11 + bc12 + bc14 + bc18); |
||||
} |
@ -0,0 +1,72 @@ |
||||
#pragma once |
||||
|
||||
/************************************************************************/ |
||||
/* A value struct vector that supports efficient sorting */ |
||||
/************************************************************************/ |
||||
|
||||
template<typename VT, typename ST> |
||||
struct ValStructVec |
||||
{ |
||||
ValStructVec(){clear();} |
||||
inline int size() const {return sz;} |
||||
inline void clear() {sz = 0; structVals.clear(); valIdxes.clear();} |
||||
inline void reserve(int resSz){clear(); structVals.reserve(resSz); valIdxes.reserve(resSz); } |
||||
inline void pushBack(const VT& val, const ST& structVal) {valIdxes.push_back(make_pair(val, sz)); structVals.push_back(structVal); sz++;} |
||||
|
||||
inline const VT& operator ()(int i) const {return valIdxes[i].first;} // Should be called after sort
|
||||
inline const ST& operator [](int i) const {return structVals[valIdxes[i].second];} // Should be called after sort
|
||||
inline VT& operator ()(int i) {return valIdxes[i].first;} // Should be called after sort
|
||||
inline ST& operator [](int i) {return structVals[valIdxes[i].second];} // Should be called after sort
|
||||
|
||||
void sort(bool descendOrder = true); |
||||
const vector<ST> &getSortedStructVal(); |
||||
void append(const ValStructVec<VT, ST> &newVals, int startV = 0); |
||||
|
||||
vector<ST> structVals; // struct values
|
||||
|
||||
private: |
||||
int sz; // size of the value struct vector
|
||||
vector<pair<VT, int>> valIdxes; // Indexes after sort
|
||||
bool smaller() {return true;}; |
||||
vector<ST> sortedStructVals; |
||||
}; |
||||
|
||||
template<typename VT, typename ST> |
||||
void ValStructVec<VT, ST>::append(const ValStructVec<VT, ST> &newVals, int startV) |
||||
{ |
||||
int sz = newVals.size(); |
||||
for (int i = 0; i < sz; i++) |
||||
pushBack((float)((i+300)*startV)/*newVals(i)*/, newVals[i]); |
||||
} |
||||
|
||||
template<typename VT, typename ST> |
||||
void ValStructVec<VT, ST>::sort(bool descendOrder /* = true */) |
||||
{ |
||||
if (descendOrder) |
||||
std::sort(valIdxes.begin(), valIdxes.end(), std::greater<pair<VT, int>>()); |
||||
else |
||||
std::sort(valIdxes.begin(), valIdxes.end(), std::less<pair<VT, int>>()); |
||||
} |
||||
|
||||
template<typename VT, typename ST> |
||||
const vector<ST>& ValStructVec<VT, ST>::getSortedStructVal() |
||||
{ |
||||
sortedStructVals.resize(sz); |
||||
for (int i = 0; i < sz; i++) |
||||
sortedStructVals[i] = structVals[valIdxes[i].second]; |
||||
return sortedStructVals; |
||||
} |
||||
|
||||
/*
|
||||
void valStructVecDemo() |
||||
{ |
||||
ValStructVec<int, string> sVals; |
||||
sVals.pushBack(3, "String 3"); |
||||
sVals.pushBack(5, "String 5"); |
||||
sVals.pushBack(4, "String 4"); |
||||
sVals.pushBack(1, "String 1"); |
||||
sVals.sort(false); |
||||
for (int i = 0; i < sVals.size(); i++) |
||||
printf("%d, %s\n", sVals(i), _S(sVals[i])); |
||||
} |
||||
*/ |
@ -0,0 +1,224 @@ |
||||
#ifndef KYHEADER_H |
||||
#define KYHEADER_H |
||||
|
||||
#include <assert.h> |
||||
#include <string> |
||||
#include <vector> |
||||
#include <functional> |
||||
#include <list> |
||||
#include <algorithm> |
||||
#include <iostream> |
||||
#include <cmath> |
||||
#include <time.h> |
||||
#include <fstream> |
||||
#include <random> |
||||
//#include <atlstr.h>
|
||||
//#include <atltypes.h>
|
||||
#include <omp.h> |
||||
#include <strstream> |
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
//#include "LibLinear/linear.h"
|
||||
//#include <opencv2/opencv.hpp>
|
||||
#include "opencv2/core.hpp" |
||||
|
||||
#define CV_VERSION_ID CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION) |
||||
#ifdef _DEBUG |
||||
#define cvLIB(name) "opencv_" name CV_VERSION_ID "d" |
||||
#else |
||||
#define cvLIB(name) "opencv_" name CV_VERSION_ID |
||||
#endif |
||||
|
||||
#pragma comment( lib, cvLIB("core")) |
||||
#pragma comment( lib, cvLIB("imgproc")) |
||||
#pragma comment( lib, cvLIB("highgui")) |
||||
using namespace cv; |
||||
using namespace std; |
||||
#ifdef WIN32 |
||||
/* windows stuff */ |
||||
#else |
||||
typedef unsigned long DWORD; |
||||
typedef unsigned short WORD; |
||||
typedef unsigned int UNINT32; |
||||
typedef bool BOOL; |
||||
typedef void *HANDLE; |
||||
typedef unsigned char byte; |
||||
#endif |
||||
|
||||
typedef std::vector<int> vecI; |
||||
typedef const std::string CStr; |
||||
typedef const Mat CMat; |
||||
typedef std::vector<std::string> vecS; |
||||
typedef std::vector<Mat> vecM; |
||||
typedef std::vector<float> vecF; |
||||
typedef std::vector<double> vecD; |
||||
|
||||
enum{CV_FLIP_BOTH = -1, CV_FLIP_VERTICAL = 0, CV_FLIP_HORIZONTAL = 1}; |
||||
#define _S(str) ((str).c_str()) |
||||
#define CHK_IND(p) ((p).x >= 0 && (p).x < _w && (p).y >= 0 && (p).y < _h) |
||||
#define CV_Assert_(expr, args) \ |
||||
{\
|
||||
if(!(expr)) {\
|
||||
String msg = cv::format args; \
|
||||
printf("%s in %s:%d\n", msg.c_str(), __FILE__, __LINE__); \
|
||||
cv::error(cv::Exception(CV_StsAssert, msg, __FUNCTION__, __FILE__, __LINE__) ); }\
|
||||
} |
||||
|
||||
using namespace std; |
||||
|
||||
// Return -1 if not in the list
|
||||
template<typename T> |
||||
static inline int findFromList(const T &word, const vector<T> &strList) { |
||||
//TODO delete test code
|
||||
//cout << "\n\n" << "word" <<" "<< word << endl;
|
||||
for(int i=0; i<strList.size(); i++) { |
||||
//cout <<"test word:"<< word << " " << endl;
|
||||
//cout << "Size w " << word.size() << " Size L "<< strList[i].size() << endl;
|
||||
} |
||||
|
||||
auto it = std::find(strList.begin(),strList.end(), word); |
||||
if (it == strList.end()) |
||||
{ |
||||
return -1; |
||||
} else |
||||
{ |
||||
auto index = std::distance(strList.begin(), it); |
||||
//cout << "index" <<" "<< index << endl;
|
||||
return index; |
||||
} |
||||
}
|
||||
/*template<typename T>
|
||||
static inline int findFromList(const string &word, const vector<T> &strList) { |
||||
//for(int i=0; i<strList.size(); i++){
|
||||
//cout <<"element: " <<strList[i]<<" "<<word << endl;
|
||||
//if (std::strcmp(word.c_str(),strList[i].c_str())==0) return i;
|
||||
} |
||||
|
||||
return -1; |
||||
} |
||||
*/ |
||||
|
||||
template<typename T> inline T sqr(T x) { return x * x; } // out of range risk for T = byte, ...
|
||||
template<class T, int D> inline T vecSqrDist(const Vec<T, D> &v1, const Vec<T, D> &v2) {T s = 0; for (int i=0; i<D; i++) s += sqr(v1[i] - v2[i]); return s;} // out of range risk for T = byte, ...
|
||||
template<class T, int D> inline T vecDist(const Vec<T, D> &v1, const Vec<T, D> &v2) { return sqrt(vecSqrDist(v1, v2)); } // out of range risk for T = byte, ...
|
||||
|
||||
inline Rect Vec4i2Rect(Vec4i &v){return Rect(Point(v[0] - 1, v[1] - 1), Point(v[2], v[3])); } |
||||
|
||||
#ifdef __WIN32 |
||||
#define INT64 long long |
||||
#else |
||||
#define INT64 long |
||||
typedef unsigned long UINT64; |
||||
#endif |
||||
|
||||
/////
|
||||
#if (_MSC_VER >= 1500) |
||||
# include <intrin.h> |
||||
# define POPCNT(x) __popcnt(x) |
||||
# define POPCNT64(x) __popcnt64(x) |
||||
#endif |
||||
|
||||
#if defined(__GNUC__) |
||||
# define POPCNT(x) __builtin_popcount(x) |
||||
# define POPCNT64(x) __builtin_popcountll(x) |
||||
#endif |
||||
|
||||
inline int popcnt64(register uint64_t u) |
||||
{ |
||||
u = (u & 0x5555555555555555) + ((u >> 1) & 0x5555555555555555); |
||||
u = (u & 0x3333333333333333) + ((u >> 2) & 0x3333333333333333); |
||||
u = (u & 0x0f0f0f0f0f0f0f0f) + ((u >> 4) & 0x0f0f0f0f0f0f0f0f); |
||||
u = (u & 0x00ff00ff00ff00ff) + ((u >> 8) & 0x00ff00ff00ff00ff); |
||||
u = (u & 0x0000ffff0000ffff) + ((u >>16) & 0x0000ffff0000ffff); |
||||
u = (u & 0x00000000ffffffff) + ((u >>32) & 0x00000000ffffffff); |
||||
return u; |
||||
} |
||||
|
||||
inline int popcnt(register uint32_t u) |
||||
{ |
||||
u = (u & 0x55555555) + ((u >> 1) & 0x55555555); |
||||
u = (u & 0x33333333) + ((u >> 2) & 0x33333333); |
||||
u = (u & 0x0f0f0f0f) + ((u >> 4) & 0x0f0f0f0f); |
||||
u = (u & 0x00ff00ff) + ((u >> 8) & 0x00ff00ff); |
||||
u = (u & 0x0000ffff) + ((u >>16) & 0x0000ffff); |
||||
return u; |
||||
} |
||||
|
||||
inline int popcnt64_nibble(register uint64_t u) |
||||
{ |
||||
static const uint8_t Table[] = { |
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 |
||||
}; |
||||
|
||||
int c = 0; |
||||
while (u) |
||||
{ |
||||
c += Table[u & 0xf]; |
||||
u >>= 4; |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
inline int popcnt_nibble(register uint32_t u) |
||||
{ |
||||
static const uint8_t Table[] = { |
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 |
||||
}; |
||||
|
||||
int c = 0; |
||||
while (u) |
||||
{ |
||||
c += Table[u & 0xf]; |
||||
u >>= 4; |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
inline int popcnt64_byte(register uint64_t u) |
||||
{ |
||||
#define B2(k) k, k+1, k+1, k+2 |
||||
#define B4(k) B2(k), B2(k+1), B2(k+1), B2(k+2) |
||||
#define B6(k) B4(k), B4(k+1), B4(k+1), B4(k+2) |
||||
static const uint8_t Table[] = { |
||||
B6(0), B6(1), B6(1), B6(2) |
||||
}; |
||||
#undef B6 |
||||
#undef B4 |
||||
#undef B2 |
||||
|
||||
int c = 0; |
||||
while (u) |
||||
{ |
||||
c += Table[u & 0xff]; |
||||
u >>= 8; |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
inline int popcnt_byte(register uint32_t u) |
||||
{ |
||||
#define B2(k) k, k+1, k+1, k+2 |
||||
#define B4(k) B2(k), B2(k+1), B2(k+1), B2(k+2) |
||||
#define B6(k) B4(k), B4(k+1), B4(k+1), B4(k+2) |
||||
static const uint8_t Table[] = { |
||||
B6(0), B6(1), B6(1), B6(2) |
||||
}; |
||||
#undef B6 |
||||
#undef B4 |
||||
#undef B2 |
||||
|
||||
int c = 0; |
||||
while (u) |
||||
{ |
||||
c += Table[u & 0xff]; |
||||
u >>= 8; |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
|
||||
/////
|
||||
#include "CmTimer.h" |
||||
#include "CmFile.h" |
||||
#endif // KYHEADER_H
|
Loading…
Reference in new issue