logo 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|