mexopencv  3.4.1
MEX interface for OpenCV library
ImgHash_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include "opencv2/img_hash.hpp"
10 #include <typeinfo>
11 using namespace std;
12 using namespace cv;
13 using namespace cv::img_hash;
14 
15 // Persistent objects
16 namespace {
18 int last_id = 0;
21 
26 
40  const string& alg,
43 {
44  ptrdiff_t len = std::distance(first, last);
46  if (alg == "AverageHash") {
47  nargchk(len==0);
48  p = AverageHash::create();
49  }
50  else if (alg == "BlockMeanHash") {
51  nargchk((len%2)==0);
53  for (; first != last; first += 2) {
54  string key(first->toString());
55  const MxArray& val = *(first + 1);
56  if (key == "Mode")
57  mode = BlockMeanHashModeMap[val.toString()];
58  else
59  mexErrMsgIdAndTxt("mexopencv:error",
60  "Unrecognized option %s", key.c_str());
61  }
62  p = BlockMeanHash::create(mode);
63  }
64  else if (alg == "ColorMomentHash") {
65  nargchk(len==0);
67  }
68  else if (alg == "MarrHildrethHash") {
69  nargchk((len%2)==0);
70  float alpha = 2.0f;
71  float scale = 1.0f;
72  for (; first != last; first += 2) {
73  string key(first->toString());
74  const MxArray& val = *(first + 1);
75  if (key == "Alpha")
76  alpha = val.toFloat();
77  else if (key == "Scale")
78  scale = val.toFloat();
79  else
80  mexErrMsgIdAndTxt("mexopencv:error",
81  "Unrecognized option %s", key.c_str());
82  }
83  p = MarrHildrethHash::create(alpha, scale);
84  }
85  else if (alg == "PHash") {
86  nargchk(len==0);
87  p = PHash::create();
88  }
89  else if (alg == "RadialVarianceHash") {
90  nargchk((len%2)==0);
91  double sigma = 1;
92  int numOfAngleLine = 180;
93  for (; first != last; first += 2) {
94  string key(first->toString());
95  const MxArray& val = *(first + 1);
96  if (key == "Sigma")
97  sigma = val.toDouble();
98  else if (key == "NumOfAngleLine")
99  numOfAngleLine = val.toInt();
100  else
101  mexErrMsgIdAndTxt("mexopencv:error",
102  "Unrecognized option %s", key.c_str());
103  }
104  p = RadialVarianceHash::create(sigma, numOfAngleLine);
105  }
106  else
107  mexErrMsgIdAndTxt("mexopencv:error",
108  "Unrecognized hash algorithm %s",alg.c_str());
109  if (p.empty())
110  mexErrMsgIdAndTxt("mexopencv:error", "Failed to create ImgHashBase");
111  return p;
112 }
113 }
114 
122 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
123 {
124  // Check the number of arguments
125  nargchk(nrhs>=2 && nlhs<=1);
126 
127  // Argument vector
128  vector<MxArray> rhs(prhs, prhs+nrhs);
129  int id = rhs[0].toInt();
130  string method(rhs[1].toString());
131 
132  // Constructor is called. Create a new object from argument
133  if (method == "new") {
134  nargchk(nrhs>=3 && nlhs<=1);
136  rhs[2].toString(), rhs.begin() + 3, rhs.end());
137  plhs[0] = MxArray(last_id);
138  mexLock();
139  return;
140  }
141  // static methods calls
142  else if (method == "averageHash") {
143  nargchk(nrhs==3 && nlhs<=1);
144  Mat img(rhs[2].toMat(CV_8U)), hash;
145  averageHash(img, hash);
146  plhs[0] = MxArray(hash);
147  return;
148  }
149  else if (method == "blockMeanHash") {
150  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
151  int mode = BLOCK_MEAN_HASH_MODE_0;
152  for (int i=3; i<nrhs; i+=2) {
153  string key(rhs[i].toString());
154  if (key == "Mode")
155  mode = BlockMeanHashModeMap[rhs[i+1].toString()];
156  else
157  mexErrMsgIdAndTxt("mexopencv:error",
158  "Unrecognized option %s", key.c_str());
159  }
160  Mat img(rhs[2].toMat(CV_8U)), hash;
161  blockMeanHash(img, hash, mode);
162  plhs[0] = MxArray(hash);
163  return;
164  }
165  else if (method == "colorMomentHash") {
166  nargchk(nrhs==3 && nlhs<=1);
167  Mat img(rhs[2].toMat(CV_8U)), hash;
168  colorMomentHash(img, hash);
169  plhs[0] = MxArray(hash);
170  return;
171  }
172  else if (method == "marrHildrethHash") {
173  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
174  float alpha = 2.0f;
175  float scale = 1.0f;
176  for (int i=3; i<nrhs; i+=2) {
177  string key(rhs[i].toString());
178  if (key == "Alpha")
179  alpha = rhs[i+1].toFloat();
180  else if (key == "Scale")
181  scale = rhs[i+1].toFloat();
182  else
183  mexErrMsgIdAndTxt("mexopencv:error",
184  "Unrecognized option %s", key.c_str());
185  }
186  Mat img(rhs[2].toMat(CV_8U)), hash;
187  marrHildrethHash(img, hash, alpha, scale);
188  plhs[0] = MxArray(hash);
189  return;
190  }
191  else if (method == "pHash") {
192  nargchk(nrhs==3 && nlhs<=1);
193  Mat img(rhs[2].toMat(CV_8U)), hash;
194  pHash(img, hash);
195  plhs[0] = MxArray(hash);
196  return;
197  }
198  else if (method == "radialVarianceHash") {
199  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
200  double sigma = 1;
201  int numOfAngleLine = 180;
202  for (int i=3; i<nrhs; i+=2) {
203  string key(rhs[i].toString());
204  if (key == "Sigma")
205  sigma = rhs[i+1].toDouble();
206  else if (key == "NumOfAngleLine")
207  numOfAngleLine = rhs[i+1].toInt();
208  else
209  mexErrMsgIdAndTxt("mexopencv:error",
210  "Unrecognized option %s", key.c_str());
211  }
212  Mat img(rhs[2].toMat(CV_8U)), hash;
213  radialVarianceHash(img, hash, sigma, numOfAngleLine);
214  plhs[0] = MxArray(hash);
215  return;
216  }
217 
218  // Big operation switch
219  Ptr<ImgHashBase> obj = obj_[id];
220  if (obj.empty())
221  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
222  if (method == "delete") {
223  nargchk(nrhs==2 && nlhs==0);
224  obj_.erase(id);
225  mexUnlock();
226  }
227  else if (method == "typeid") {
228  nargchk(nrhs==2 && nlhs<=1);
229  plhs[0] = MxArray(string(typeid(*obj).name()));
230  }
231  else if (method == "compute") {
232  nargchk(nrhs==3 && nlhs<=1);
233  Mat img(rhs[2].toMat(CV_8U)), hash;
234  obj->compute(img, hash);
235  plhs[0] = MxArray(hash);
236  }
237  else if (method == "compare") {
238  nargchk(nrhs==4 && nlhs<=1);
239  Mat hashOne(rhs[2].toMat()),
240  hashTwo(rhs[3].toMat()); // hashes CV_8U or CV_64F
241  double val = obj->compare(hashOne, hashTwo);
242  plhs[0] = MxArray(val);
243  }
244  //TODO: expose derived-class specific methods:
245  // BlockMeanHash::getMean
246  // RadialVarianceHash::getFeatures
247  // RadialVarianceHash::getPixPerLine
248  // RadialVarianceHash::getProjection
249  else
250  mexErrMsgIdAndTxt("mexopencv:error",
251  "Unrecognized operation %s",method.c_str());
252 }
void blockMeanHash(cv::InputArray inputArr, cv::OutputArray outputArr, int mode=BLOCK_MEAN_HASH_MODE_0)
T distance(T... args)
void averageHash(cv::InputArray inputArr, cv::OutputArray outputArr)
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
void colorMomentHash(cv::InputArray inputArr, cv::OutputArray outputArr)
#define CV_8U
STL namespace.
T end(T... args)
const ConstMap< string, int > BlockMeanHashModeMap
BlockMeanHash mode map for option processing.
Definition: ImgHash_.cpp:23
struct mxArray_tag mxArray
Forward declaration for mxArray.
Definition: matrix.h:259
STL class.
double compare(cv::InputArray hashOne, cv::InputArray hashTwo) const
map< int, Ptr< ImgHashBase > > obj_
Object container.
Definition: ImgHash_.cpp:20
void compute(cv::InputArray inputArr, cv::OutputArray outputArr)
void radialVarianceHash(cv::InputArray inputArr, cv::OutputArray outputArr, double sigma=1, int numOfAngleLine=180)
LIBMWMEX_API_EXTERN_C void mexErrMsgIdAndTxt(const char *identifier, const char *err_msg,...)
Issue formatted error message with corresponding error identifier and return to MATLAB prompt...
float toFloat() const
Convert MxArray to float.
Definition: MxArray.cpp:503
LIBMWMEX_API_EXTERN_C void mexUnlock(void)
Unlock a locked MEX-function so that it can be cleared from memory.
int last_id
Last object id to allocate.
Definition: ImgHash_.cpp:18
mxArray object wrapper for data conversion and manipulation.
Definition: MxArray.hpp:123
void nargchk(bool cond)
Alias for input/output arguments number check.
Definition: mexopencv.hpp:181
STL class.
bool empty() const
void marrHildrethHash(cv::InputArray inputArr, cv::OutputArray outputArr, float alpha=2.0f, float scale=1.0f)
Global constant definitions.
T begin(T... args)
T c_str(T... args)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
Definition: ImgHash_.cpp:122
double toDouble() const
Convert MxArray to double.
Definition: MxArray.cpp:496
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
Ptr< ImgHashBase > createImgHashBase(const string &alg, vector< MxArray >::const_iterator first, vector< MxArray >::const_iterator last)
Create an instance of ImgHashBase using options in arguments.
Definition: ImgHash_.cpp:39
void create(int arows, int acols, int atype, Target target=ARRAY_BUFFER, bool autoRelease=false)
cv::Mat toMat() const
void pHash(cv::InputArray inputArr, cv::OutputArray outputArr)