logo 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,302 @@
1
+ #include "template_match.h"
2
+ #include "highgui.h"
3
+
4
+ void* init_template_match(void)
5
+ {
6
+ void *ptm = (void*) new TemplateMatch();
7
+ return ptm;
8
+ }
9
+
10
+ void release_template_match(void* ptemplate_match)
11
+ {
12
+ if(!ptemplate_match)
13
+ return;
14
+ TemplateMatch *ptm = (TemplateMatch*) ptemplate_match;
15
+ delete ptm;
16
+ return;
17
+ }
18
+
19
+ void* init_image_feature(void* ptemplate_match, const char* img_path)
20
+ {
21
+ if(!ptemplate_match || !img_path)
22
+ return NULL;
23
+ TemplateMatch *ptm = (TemplateMatch*) ptemplate_match;
24
+ string imgName;
25
+ imgName.assign(img_path);
26
+ return (void*)ptm->ExtractImageContour(imgName);
27
+ }
28
+
29
+ void release_image_feature(void* pimage_feature)
30
+ {
31
+ if(!pimage_feature)
32
+ return;
33
+ Mat* pfeature = (Mat*) pimage_feature;
34
+ delete pfeature;
35
+ return;
36
+ }
37
+
38
+ int add_image_template(void* ptemplate_match, const char* template_img_path, const char* label, int x, int y, int width, int height)
39
+ {
40
+ if(!ptemplate_match || !template_img_path || !label)
41
+ return -1;
42
+ TemplateMatch *ptm = (TemplateMatch*) ptemplate_match;
43
+ Rect roi = Rect(x, y, width, height);
44
+ string imgName, strlabel;
45
+ imgName.assign(template_img_path);
46
+ strlabel.assign(label);
47
+ return ptm->AddImageTemplate(imgName, strlabel, roi);
48
+ }
49
+
50
+ float match_image(void* ptemplate_match, void* pimage_feature, char* label)
51
+ {
52
+ if(!ptemplate_match || !pimage_feature || !label)
53
+ return NO_MATCH_SCORE;
54
+ TemplateMatch *ptm = (TemplateMatch*) ptemplate_match;
55
+ string templateLabel;
56
+ templateLabel.assign(label);
57
+ return ptm->MatchOneTemplate( *(Mat*)pimage_feature, templateLabel);
58
+ }
59
+
60
+ Rect TemplateMatch::DefaultROI = Rect(DEFAULT_X, DEFAULT_Y, DEFAULT_COLS, DEFAULT_ROWS);
61
+
62
+ TemplateMatch::TemplateMatch(void) : mMatchThresh(0.4)
63
+ {
64
+ }
65
+
66
+ TemplateMatch::~TemplateMatch(void)
67
+ {
68
+ }
69
+
70
+ Mat* TemplateMatch::ExtractImageContour(string& imgName)
71
+ {
72
+ if( imgName == "")
73
+ return NULL;
74
+ Rect roi = DefaultROI;
75
+ Mat *pfMat = new Mat(roi.height, roi.width, CV_32FC1);
76
+ if(!pfMat)
77
+ return NULL;
78
+ Mat imgMat = imread(imgName, 0);
79
+ Mat imgROI = imgMat(Range(roi.y, roi.height + roi.y), Range(roi.x, roi.width + roi.x) );
80
+ GaussianBlur(imgROI, imgROI, Size(7, 7), 0, 0);
81
+
82
+ /*these two threshold are small than threshold used when calculate template contour.*/
83
+ Canny(imgROI, imgROI, 20, 80, 3);
84
+ imgROI.convertTo(*pfMat, CV_32FC1, 1, 0);
85
+ normalize(*pfMat, *pfMat, 1.0, 0, NORM_MINMAX);
86
+ return pfMat;
87
+ }
88
+
89
+ int TemplateMatch::AddImageTemplate(string& imgName, string& label, Rect& roi)
90
+ {
91
+ if( imgName == "")
92
+ return -1;
93
+
94
+ Mat imgMat = imread(imgName, 0);
95
+ Mat imgROI = imgMat(Range(roi.y, roi.height + roi.y), Range(roi.x, roi.width + roi.x) );
96
+ Mat tplMat = imgROI.clone();
97
+ Mat fROI(roi.height, roi.width, CV_32FC1);
98
+ GaussianBlur(imgROI, imgROI, Size(7, 7), 0, 0);
99
+ //Canny(imgROI, imgROI, 50, 120, 3);
100
+ Canny(imgROI, imgROI, 50, 110, 3);
101
+ imgROI.convertTo(fROI, CV_32FC1, 1, 0);
102
+ normalize(fROI, fROI, 1.0, 0, NORM_MINMAX);
103
+ slogo logo;
104
+ logo.name = label;
105
+ logo.contourMat = fROI;
106
+ logo.templateMat = tplMat;
107
+ logo.contourRect = roi;
108
+ AddLogoTemplate(logo);
109
+ return 0;
110
+
111
+ }
112
+
113
+ int TemplateMatch::AddLogoTemplate(slogo logo)
114
+ {
115
+ mslogoArray.push_back(logo);
116
+ return 0;
117
+ }
118
+
119
+ int TemplateMatch::AddLogoTemplate(string& lgName, Mat& ctMat, Mat& tplMat)
120
+ {
121
+ slogo logo;
122
+ logo.name = lgName;
123
+ logo.contourMat = ctMat;
124
+ logo.templateMat = tplMat;
125
+ mslogoArray.push_back(logo);
126
+ return 0;
127
+ }
128
+
129
+ float TemplateMatch::MatchOneTemplate(Mat& dstContourMat, string label)
130
+ {
131
+ int i, length;
132
+ length = mslogoArray.size();
133
+ for(i=0; i < mslogoArray.size(); i++)
134
+ {
135
+ if(mslogoArray[i].name == label)
136
+ break;
137
+ }
138
+
139
+ if( i == length )
140
+ return NO_MATCH_SCORE;
141
+ slogo logo = mslogoArray.at(i);
142
+ Rect r = logo.contourRect;
143
+ Mat dstct_roi = dstContourMat(Range(r.y - DefaultROI.y, r.y - DefaultROI.y + r.height), Range(r.x - DefaultROI.x, r.x - DefaultROI.x + r.width) );
144
+ return BilateralMatch(logo.contourMat, dstct_roi, TemplateMatch::INTERSECT);
145
+ }
146
+
147
+
148
+ string TemplateMatch::MatchImage(string& imgName, float* score)
149
+ {
150
+ if(imgName == "" || !score)
151
+ return "image not found";
152
+ Rect roi = DefaultROI;
153
+ Mat imgMat = imread(imgName, 0);
154
+ Mat imgROI = imgMat(Range(roi.y, roi.height + roi.y), Range(roi.x, roi.width + roi.x) );
155
+ Mat tplMat = imgROI.clone();
156
+ Mat fROI(roi.height, roi.width, CV_32FC1);
157
+ GaussianBlur(imgROI, imgROI, Size(7, 7), 0, 0);
158
+ //these two threshold are small than threshold used when calculate template contour.
159
+ Canny(imgROI, imgROI, 20, 80, 3);
160
+ imgROI.convertTo(fROI, CV_32FC1, 1, 0);
161
+ normalize(fROI, fROI, 1.0, 0, NORM_MINMAX);
162
+ return RetrievebyScore(fROI, tplMat, score);
163
+
164
+ }
165
+
166
+
167
+ string TemplateMatch::RetrievebyScore(Mat& dstContourMat, Mat& dstMat, float* score)
168
+ {
169
+ float difRatio;
170
+ int pos;
171
+ int flag=1;
172
+ mMatchResult.clear();
173
+ for(int i = 0; i < mslogoArray.size(); i++)
174
+ {
175
+ slogo logo = mslogoArray.at(i);
176
+ Rect r = logo.contourRect;
177
+ Mat dstct_roi = dstContourMat(Range(r.y - DefaultROI.y, r.y - DefaultROI.y + r.height), Range(r.x - DefaultROI.x, r.x - DefaultROI.x + r.width) );
178
+
179
+ difRatio = BilateralMatch(logo.contourMat, dstct_roi, TemplateMatch::INTERSECT);
180
+ InsertMatchResult(logo.name, difRatio);
181
+ }
182
+ SortMatchResult();
183
+ *score = mMatchResult[0].second;
184
+ return mMatchResult[0].first;
185
+ }
186
+
187
+
188
+ float TemplateMatch::BilateralMatch(Mat& srcMat, Mat& dstMat, enum method m)
189
+ {
190
+ if(srcMat.rows != dstMat.rows
191
+ || srcMat.cols != dstMat.cols
192
+ || srcMat.depth() != dstMat.depth()
193
+ || srcMat.channels() != dstMat.channels()
194
+ )
195
+ return NO_MATCH_SCORE;
196
+
197
+ float score, difRatio, count;
198
+ if(m == TemplateMatch::MINUSDIST)
199
+ {
200
+ Mat difMat(srcMat.rows, srcMat.cols, CV_32FC1);
201
+ difMat = abs(srcMat - dstMat);
202
+ score = sum(difMat)[0];
203
+ difRatio = score/(srcMat.rows * srcMat.cols);
204
+ }
205
+ else if(m == TemplateMatch::INTERSECT)
206
+ {
207
+ Mat scoreMat(srcMat.rows, srcMat.cols, CV_32FC1);
208
+ scoreMat = dstMat.mul(srcMat);
209
+ score = sum(scoreMat)[0];
210
+ count = sum(srcMat)[0];
211
+ difRatio = (count - score)/count;
212
+ }
213
+
214
+ return difRatio;
215
+ }
216
+
217
+ float TemplateMatch::CalcHistScore(Mat& srcMat, Mat& dstMat)
218
+ {
219
+ IplImage *srcImg;
220
+ IplImage *dstImg;
221
+ *srcImg = (IplImage(srcMat));//&(IplImage(srcMat));
222
+ *dstImg = (IplImage(dstMat));//&(IplImage(dstMat));
223
+ int hist_size = 256;
224
+ float range[] = {0, 255};
225
+ float *ranges[] = {range};
226
+ CvHistogram *srcHist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
227
+ cvCalcHist(&srcImg, srcHist, 0, 0);
228
+ CvHistogram *dstHist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
229
+ cvCalcHist(&dstImg, dstHist, 0, 0);
230
+ float com1 = cvCompareHist(srcHist, dstHist, CV_COMP_BHATTACHARYYA);
231
+ return com1;
232
+ }
233
+
234
+ Rect TemplateMatch::GetContourRect(Mat& ctMat)
235
+ {
236
+ Rect r;
237
+ int min_x, min_y, max_x, max_y;
238
+ max_x = max_y = 0;
239
+ min_x = ctMat.cols;
240
+ min_y = ctMat.rows;
241
+ for(int i = 0 ; i < ctMat.rows ; i++)
242
+ for(int j = 0; j < ctMat.cols ; j++)
243
+ {
244
+ float element = ctMat.at<float>(i, j);
245
+ if(element > 0.0)
246
+ {
247
+ if( j < min_x )
248
+ min_x = j;
249
+ if( i < min_y)
250
+ min_y = i;
251
+ if( j > max_x )
252
+ max_x = j;
253
+ if( i > max_y )
254
+ max_y = i;
255
+ }
256
+ }
257
+ r.x = min_x;
258
+ r.y = min_y;
259
+ r.width = max_x - min_x ;
260
+ r.height = max_y - min_y;
261
+ return r;
262
+ }
263
+
264
+ int TemplateMatch::SortMatchResult(bool bAscend)
265
+ {
266
+ //sort mMatchResult with bubble sort
267
+ int length = mMatchResult.size();
268
+ if(bAscend)
269
+ {
270
+ for(int i = 0; i < length; i++)
271
+ for(int j = 0; j< length -i -1; j++)
272
+ {
273
+ if( mMatchResult.at(j).second > mMatchResult.at(j+1).second )
274
+ {
275
+ pair<string, float> temp = mMatchResult.at(j+1);
276
+ mMatchResult.at(j+1) = mMatchResult.at(j);
277
+ mMatchResult.at(j) = temp;
278
+ }
279
+ }
280
+ }
281
+ else
282
+ {
283
+ for(int i = 0; i < length; i++)
284
+ for(int j = length -1; j> i; j--)
285
+ {
286
+ if( mMatchResult.at(j).second < mMatchResult.at(j-1).second )
287
+ {
288
+ pair<string, float> temp = mMatchResult.at(j-1);
289
+ mMatchResult.at(j-1) = mMatchResult.at(j);
290
+ mMatchResult.at(j) = temp;
291
+ }
292
+ }
293
+ }
294
+ return 0;
295
+ }
296
+
297
+
298
+ int TemplateMatch::InsertMatchResult(string label, float ratio)
299
+ {
300
+ mMatchResult.push_back(pair<string, float>(label, ratio));
301
+ return mMatchResult.size();
302
+ }
Binary file
Binary file
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'rca_logo_recognition'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,8 @@
1
+ $:.unshift('.')
2
+ $:.unshift(File.dirname(__FILE__))
3
+ require File.join(File.dirname(__FILE__),"../lib/logo")
4
+
5
+ yml='/Users/cuizheng/Documents/rca_project/rca.cv/test/suite/suite.yml'
6
+ sco = Logo::Scouts.new(yml)
7
+ puts sco.show_hand('./test/1371714252.jpg')
8
+ puts sco.show_hand('./test/1371714902.jpg')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -88,11 +88,16 @@ files:
88
88
  - ext/logo/recognize/extconf.rb
89
89
  - ext/logo/recognize/recognize.c
90
90
  - ext/logo/recognize/recognize.h
91
+ - ext/logo/recognize/template_match.cpp
91
92
  - ext/logo/recognize/template_match.h
92
93
  - ext/logo/recognize/template_match_test.c
93
94
  - lib/logo.rb
94
95
  - lib/logo/scouts.rb
95
96
  - lib/logo/suite.rb
97
+ - test/1371714252.jpg
98
+ - test/1371714902.jpg
99
+ - test/helper.rb
100
+ - test/test_rca_logo_recognition.rb
96
101
  - LICENSE.txt
97
102
  - README.rdoc
98
103
  homepage: http://github.com/charlescui/logo
@@ -110,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
115
  version: '0'
111
116
  segments:
112
117
  - 0
113
- hash: -2516966878859114465
118
+ hash: -67238116112909683
114
119
  required_rubygems_version: !ruby/object:Gem::Requirement
115
120
  none: false
116
121
  requirements: