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.
- data/ext/logo/recognize/template_match.cpp +302 -0
- data/test/1371714252.jpg +0 -0
- data/test/1371714902.jpg +0 -0
- data/test/helper.rb +18 -0
- data/test/test_rca_logo_recognition.rb +8 -0
- metadata +7 -2
@@ -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
|
+
}
|
data/test/1371714252.jpg
ADDED
Binary file
|
data/test/1371714902.jpg
ADDED
Binary file
|
data/test/helper.rb
ADDED
@@ -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.
|
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: -
|
118
|
+
hash: -67238116112909683
|
114
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
120
|
none: false
|
116
121
|
requirements:
|