Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
谢明辉
/
VVAS-Match
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit d0cf0291
authored
Dec 02, 2020
by
xmh
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
加入人体特征
1 parent
877b932f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
125 additions
and
36 deletions
src/main/java/com/viontech/match/config/Constant.java
src/main/java/com/viontech/match/service/PersonService.java
src/main/java/com/viontech/match/service/PoolService.java
src/main/resources/application-option.properties
src/main/java/com/viontech/match/config/Constant.java
0 → 100644
View file @
d0cf029
package
com
.
viontech
.
match
.
config
;
/**
* .
*
* @author 谢明辉
* @date 2020/12/2
*/
public
class
Constant
{
/** 人脸特征维数 */
public
final
static
int
FACE_FEATURE_DIMS
=
512
;
/** 人体特征维数 */
public
final
static
int
BODY_FEATURE_DIMS
=
2048
;
/** poolId不存在时es返回的message所包含的字段 */
public
final
static
String
STR_POOL_ID_ALREADY_EXISTS
=
"already_exists"
;
/** 人脸匹配结果的数量 */
public
final
static
int
MATCH_RESULT_SIZE
=
5
;
}
src/main/java/com/viontech/match/service/PersonService.java
View file @
d0cf029
package
com
.
viontech
.
match
.
service
;
package
com
.
viontech
.
match
.
service
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.viontech.keliu.model.BodyFeature
;
import
com.viontech.keliu.model.FaceFeature
;
import
com.viontech.keliu.model.FaceFeature
;
import
com.viontech.keliu.model.Person
;
import
com.viontech.keliu.model.Person
;
import
com.viontech.keliu.model.Pool
;
import
com.viontech.keliu.model.Pool
;
import
com.viontech.match.config.Constant
;
import
com.viontech.match.entity.vo.RequestVo
;
import
com.viontech.match.entity.vo.RequestVo
;
import
com.viontech.match.entity.vo.ResponseVo
;
import
com.viontech.match.entity.vo.ResponseVo
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
...
@@ -116,10 +118,30 @@ public class PersonService {
...
@@ -116,10 +118,30 @@ public class PersonService {
if
(
faceFeatures
!=
null
&&
faceFeatures
.
size
()
>
0
)
{
if
(
faceFeatures
!=
null
&&
faceFeatures
.
size
()
>
0
)
{
for
(
FaceFeature
faceFeature
:
faceFeatures
)
{
for
(
FaceFeature
faceFeature
:
faceFeatures
)
{
Double
[]
feature
=
faceFeature
.
getFeature
();
Double
[]
feature
=
faceFeature
.
getFeature
();
String
fid
=
faceFeature
.
getFid
();
if
(
feature
!=
null
&&
feature
.
length
==
Constant
.
FACE_FEATURE_DIMS
)
{
String
fid
=
faceFeature
.
getFid
();
IndexRequest
indexRequest
=
new
IndexRequest
(
poolId
)
.
source
(
XContentType
.
JSON
,
"personId"
,
personId
,
"data"
,
feature
,
"fid"
,
fid
,
"age"
,
age
,
"gender"
,
gender
);
bulkRequest
.
add
(
indexRequest
);
}
}
}
List
<
BodyFeature
>
bodyFeatures
=
person
.
getBodyFeatures
();
if
(
bodyFeatures
!=
null
&&
bodyFeatures
.
size
()
>
0
)
{
for
(
BodyFeature
bodyFeature
:
bodyFeatures
)
{
Double
[]
feature
=
bodyFeature
.
getFeature
();
if
(
feature
==
null
||
feature
.
length
<
Constant
.
BODY_FEATURE_DIMS
)
{
continue
;
}
if
(
feature
.
length
>
Constant
.
BODY_FEATURE_DIMS
)
{
feature
=
Arrays
.
copyOf
(
feature
,
Constant
.
BODY_FEATURE_DIMS
);
}
String
fid
=
bodyFeature
.
getBid
();
IndexRequest
indexRequest
=
new
IndexRequest
(
poolId
)
IndexRequest
indexRequest
=
new
IndexRequest
(
poolId
)
.
source
(
XContentType
.
JSON
,
"personId"
,
personId
,
"
data
"
,
feature
,
"fid"
,
fid
,
"age"
,
age
,
"gender"
,
gender
);
.
source
(
XContentType
.
JSON
,
"personId"
,
personId
,
"
body
"
,
feature
,
"fid"
,
fid
,
"age"
,
age
,
"gender"
,
gender
);
bulkRequest
.
add
(
indexRequest
);
bulkRequest
.
add
(
indexRequest
);
}
}
}
}
...
@@ -142,48 +164,85 @@ public class PersonService {
...
@@ -142,48 +164,85 @@ public class PersonService {
public
List
<
Person
>
matchPerson
(
String
poolId
,
Person
person
)
throws
Exception
{
public
List
<
Person
>
matchPerson
(
String
poolId
,
Person
person
)
throws
Exception
{
List
<
Person
>
matchResult
=
new
ArrayList
<>();
List
<
FaceFeature
>
faceFeatures
=
person
.
getFaceFeatures
();
List
<
FaceFeature
>
faceFeatures
=
person
.
getFaceFeatures
();
List
<
Person
>
persons
=
new
ArrayList
<>();
matchFace
(
faceFeatures
,
poolId
,
matchResult
);
List
<
BodyFeature
>
bodyFeatures
=
person
.
getBodyFeatures
();
matchBody
(
bodyFeatures
,
poolId
,
matchResult
);
if
(
matchResult
.
size
()
>
Constant
.
MATCH_RESULT_SIZE
)
{
matchResult
=
matchResult
.
stream
().
sorted
(
Comparator
.
comparingInt
(
Person:
:
getScore
)).
limit
(
5
).
collect
(
Collectors
.
toList
());
}
return
matchResult
;
}
private
void
matchFace
(
List
<
FaceFeature
>
faceFeatures
,
String
poolId
,
List
<
Person
>
matchResult
)
throws
IOException
{
if
(
faceFeatures
!=
null
&&
faceFeatures
.
size
()
>
0
)
{
if
(
faceFeatures
!=
null
&&
faceFeatures
.
size
()
>
0
)
{
for
(
FaceFeature
faceFeature
:
faceFeatures
)
{
for
(
FaceFeature
faceFeature
:
faceFeatures
)
{
Double
[]
feature
=
faceFeature
.
getFeature
();
Double
[]
feature
=
faceFeature
.
getFeature
();
if
(
feature
.
length
<
512
)
{
if
(
feature
==
null
||
feature
.
length
!=
Constant
.
FACE_FEATURE_DIMS
)
{
continue
;
continue
;
}
}
Script
script
=
new
Script
(
Script
script
=
new
Script
(
ScriptType
.
INLINE
,
Script
.
DEFAULT_SCRIPT_LANG
,
ScriptType
.
INLINE
,
Script
.
DEFAULT_SCRIPT_LANG
,
"(cosineSimilarity(params.data, 'data') + 1) / 2 * 100"
,
Collections
.
singletonMap
(
"data"
,
feature
));
"(cosineSimilarity(params.face, 'data') + 1) / 2 * 100"
,
Collections
.
singletonMap
(
"face"
,
feature
));
ScriptScoreQueryBuilder
queryBuilder
=
QueryBuilders
.
scriptScoreQuery
(
QueryBuilders
.
matchAllQuery
(),
script
);
matchResult
.
addAll
(
match0
(
poolId
,
script
));
SearchSourceBuilder
builder
=
new
SearchSourceBuilder
()
.
size
(
5
)
.
query
(
queryBuilder
)
.
fetchSource
(
new
String
[]{
"personId"
,
"age"
,
"gender"
,
"fid"
},
null
);
SearchRequest
searchRequest
=
new
SearchRequest
(
poolId
)
.
source
(
builder
);
SearchResponse
search
=
client
.
search
(
searchRequest
,
RequestOptions
.
DEFAULT
);
SearchHits
hits
=
search
.
getHits
();
SearchHit
[]
hits1
=
hits
.
getHits
();
for
(
SearchHit
item
:
hits1
)
{
Map
<
String
,
Object
>
source
=
item
.
getSourceAsMap
();
Person
p
=
new
Person
();
p
.
setPersonId
((
String
)
source
.
get
(
"personId"
));
p
.
setAge
((
Integer
)
source
.
get
(
"age"
));
p
.
setGender
((
String
)
source
.
get
(
"gender"
));
p
.
setScore
((
int
)
item
.
getScore
());
p
.
setPersonPoolId
(
item
.
getIndex
());
persons
.
add
(
p
);
}
}
}
}
else
{
}
else
{
log
.
info
(
"no face feature"
);
log
.
info
(
"no face feature"
);
}
}
if
(
persons
.
size
()
>
5
)
{
}
persons
=
persons
.
stream
().
sorted
(
Comparator
.
comparingInt
(
Person:
:
getScore
)).
limit
(
5
).
collect
(
Collectors
.
toList
());
private
void
matchBody
(
List
<
BodyFeature
>
bodyFeatures
,
String
poolId
,
List
<
Person
>
matchResult
)
throws
IOException
{
if
(
bodyFeatures
!=
null
&&
bodyFeatures
.
size
()
>
0
)
{
for
(
BodyFeature
faceFeature
:
bodyFeatures
)
{
Double
[]
feature
=
faceFeature
.
getFeature
();
if
(
feature
==
null
||
feature
.
length
<
Constant
.
BODY_FEATURE_DIMS
)
{
continue
;
}
if
(
feature
.
length
>
Constant
.
BODY_FEATURE_DIMS
)
{
feature
=
Arrays
.
copyOf
(
feature
,
Constant
.
BODY_FEATURE_DIMS
);
}
Script
script
=
new
Script
(
ScriptType
.
INLINE
,
Script
.
DEFAULT_SCRIPT_LANG
,
"(cosineSimilarity(params.body, 'body') + 1) / 2 * 100"
,
Collections
.
singletonMap
(
"body"
,
feature
));
matchResult
.
addAll
(
match0
(
poolId
,
script
));
}
}
else
{
log
.
info
(
"no body feature"
);
}
}
private
List
<
Person
>
match0
(
String
poolId
,
Script
script
)
throws
IOException
{
List
<
Person
>
persons
=
new
ArrayList
<>();
ScriptScoreQueryBuilder
queryBuilder
=
QueryBuilders
.
scriptScoreQuery
(
QueryBuilders
.
matchAllQuery
(),
script
);
SearchSourceBuilder
builder
=
new
SearchSourceBuilder
()
.
size
(
Constant
.
MATCH_RESULT_SIZE
)
.
query
(
queryBuilder
)
.
fetchSource
(
new
String
[]{
"personId"
,
"age"
,
"gender"
,
"fid"
},
null
);
SearchRequest
searchRequest
=
new
SearchRequest
(
poolId
)
.
source
(
builder
);
SearchResponse
search
=
client
.
search
(
searchRequest
,
RequestOptions
.
DEFAULT
);
SearchHits
hits
=
search
.
getHits
();
SearchHit
[]
hits1
=
hits
.
getHits
();
for
(
SearchHit
item
:
hits1
)
{
Map
<
String
,
Object
>
source
=
item
.
getSourceAsMap
();
Person
p
=
new
Person
();
p
.
setPersonId
((
String
)
source
.
get
(
"personId"
));
p
.
setAge
((
Integer
)
source
.
get
(
"age"
));
p
.
setGender
((
String
)
source
.
get
(
"gender"
));
p
.
setScore
((
int
)
item
.
getScore
());
p
.
setPersonPoolId
(
item
.
getIndex
());
persons
.
add
(
p
);
}
}
return
persons
;
return
persons
;
}
}
...
...
src/main/java/com/viontech/match/service/PoolService.java
View file @
d0cf029
package
com
.
viontech
.
match
.
service
;
package
com
.
viontech
.
match
.
service
;
import
com.viontech.keliu.model.Person
;
import
com.viontech.keliu.model.Person
;
import
com.viontech.match.config.Constant
;
import
com.viontech.match.entity.PoolInfo
;
import
com.viontech.match.entity.PoolInfo
;
import
com.viontech.match.entity.vo.RequestVo
;
import
com.viontech.match.entity.vo.RequestVo
;
import
com.viontech.match.entity.vo.ResponseVo
;
import
com.viontech.match.entity.vo.ResponseVo
;
...
@@ -66,11 +67,10 @@ public class PoolService {
...
@@ -66,11 +67,10 @@ public class PoolService {
log
.
info
(
"特征池创建操作完成:[{}]"
,
poolId
);
log
.
info
(
"特征池创建操作完成:[{}]"
,
poolId
);
return
ResponseVo
.
success
(
rid
);
return
ResponseVo
.
success
(
rid
);
}
catch
(
ElasticsearchStatusException
e
)
{
}
catch
(
ElasticsearchStatusException
e
)
{
if
(
e
.
status
()
==
RestStatus
.
BAD_REQUEST
)
{
if
(
e
.
status
()
==
RestStatus
.
BAD_REQUEST
&&
e
.
getMessage
().
contains
(
Constant
.
STR_POOL_ID_ALREADY_EXISTS
)
)
{
return
ResponseVo
.
error
(
rid
,
20
,
"already exit poolId"
);
return
ResponseVo
.
error
(
rid
,
20
,
"already exit poolId"
);
}
else
{
}
else
{
log
.
error
(
"createPool"
,
e
);
throw
e
;
return
ResponseVo
.
error
(
rid
,
e
.
getDetailedMessage
());
}
}
}
}
}
}
...
@@ -174,7 +174,14 @@ public class PoolService {
...
@@ -174,7 +174,14 @@ public class PoolService {
builder
.
startObject
(
"data"
);
builder
.
startObject
(
"data"
);
{
{
builder
.
field
(
"type"
,
"dense_vector"
);
builder
.
field
(
"type"
,
"dense_vector"
);
builder
.
field
(
"dims"
,
512
);
builder
.
field
(
"dims"
,
Constant
.
FACE_FEATURE_DIMS
);
}
builder
.
endObject
();
builder
.
startObject
(
"body"
);
{
builder
.
field
(
"type"
,
"dense_vector"
);
builder
.
field
(
"dims"
,
Constant
.
BODY_FEATURE_DIMS
);
}
}
builder
.
endObject
();
builder
.
endObject
();
...
...
src/main/resources/application-option.properties
View file @
d0cf029
...
@@ -3,4 +3,5 @@ server.port=12000
...
@@ -3,4 +3,5 @@ server.port=12000
spring.jackson.time-
zone
=
GMT+8
spring.jackson.time-
zone
=
GMT+8
spring.jackson.date-
format
=
yyyy-MM-dd HH:mm:ss
spring.jackson.date-
format
=
yyyy-MM-dd HH:mm:ss
# es
# es
spring.elasticsearch.rest.uris
=
http://192.168.9.116:9200
\ No newline at end of file
\ No newline at end of file
#spring.elasticsearch.rest.uris=http://192.168.9.116:9200
spring.elasticsearch.rest.uris
=
http://127.0.0.1:9200
\ No newline at end of file
\ No newline at end of file
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment