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 6a0f781c
authored
Apr 08, 2021
by
xmh
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
人体比对结果改为每个特征池10个,人体特征存储和比对前进行权重计算
1 parent
ca25ceb7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
137 additions
and
36 deletions
pom.xml
src/main/java/com/viontech/match/XmhTestApplication.java → src/main/java/com/viontech/match/MatchApp.java
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/java/com/viontech/match/util/Utils.java
src/test/java/com/viontech/match/util/UtilsTest.java
pom.xml
View file @
6a0f781
...
...
@@ -28,6 +28,12 @@
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
<exclusions>
<exclusion>
<artifactId>
android-json
</artifactId>
<groupId>
com.vaadin.external.google
</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
com.viontech.keliu
</groupId>
...
...
@@ -57,7 +63,7 @@
<dependency>
<groupId>
com.viontech.keliu
</groupId>
<artifactId>
AlgApiClient
</artifactId>
<version>
6.0.
4
-SNAPSHOT
</version>
<version>
6.0.
5
-SNAPSHOT
</version>
<exclusions>
<exclusion>
<groupId>
javax
</groupId>
...
...
src/main/java/com/viontech/match/
XmhTestApplication
.java
→
src/main/java/com/viontech/match/
MatchApp
.java
View file @
6a0f781
...
...
@@ -5,10 +5,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import
org.springframework.context.annotation.ComponentScan
;
@SpringBootApplication
@ComponentScan
(
basePackages
=
{
"com.viontech"
})
public
class
XmhTestApplication
{
@ComponentScan
(
basePackages
=
{
"com.viontech"
})
public
class
MatchApp
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
XmhTestApplication
.
class
,
args
);
SpringApplication
.
run
(
MatchApp
.
class
,
args
);
}
}
\ No newline at end of file
src/main/java/com/viontech/match/config/Constant.java
View file @
6a0f781
...
...
@@ -12,7 +12,8 @@ public class Constant {
/** 人脸特征维数 */
public
final
static
int
FACE_FEATURE_DIMS
=
512
;
/** 人体特征维数 */
public
final
static
int
BODY_FEATURE_DIMS
=
2048
;
public
final
static
int
BODY_FEATURE_DIMS_2048
=
2048
;
public
final
static
int
BODY_FEATURE_DIMS_2110
=
2110
;
/** poolId不存在时es返回的message所包含的字段 */
public
final
static
String
STR_POOL_ID_ALREADY_EXISTS
=
"already_exists"
;
...
...
@@ -21,5 +22,7 @@ public class Constant {
public
final
static
String
CLASS_CAST_EXCEPTION
=
"class_cast_exception"
;
/** 人脸匹配结果的数量 */
public
final
static
int
MATCH_RESULT_SIZE
=
5
;
public
final
static
int
FACE_MATCH_RESULT_SIZE
=
5
;
/** 人体匹配结果的数量 */
public
final
static
int
BODY_MATCH_RESULT_SIZE
=
10
;
}
src/main/java/com/viontech/match/service/PersonService.java
View file @
6a0f781
...
...
@@ -8,6 +8,7 @@ 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.ResponseVo
;
import
com.viontech.match.util.Utils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.elasticsearch.ElasticsearchStatusException
;
import
org.elasticsearch.action.bulk.BulkRequest
;
...
...
@@ -79,7 +80,7 @@ public class PersonService {
pool
.
setPersonPoolId
(
id
);
if
(
poolService
.
existPool
(
id
))
{
pool
.
setStatus
(
0
);
List
<
Person
>
face
=
matchPerson
(
id
,
requestVo
.
getPerson
(),
0
);
List
<
Person
>
face
=
matchPerson
(
id
,
requestVo
.
getPerson
(),
0
);
matchFaces
.
addAll
(
face
);
List
<
Person
>
body
=
matchPerson
(
id
,
requestVo
.
getPerson
(),
1
);
matchBodies
.
addAll
(
body
);
...
...
@@ -167,11 +168,14 @@ public class PersonService {
if
(
bodyFeatures
!=
null
&&
bodyFeatures
.
size
()
>
0
)
{
for
(
BodyFeature
bodyFeature
:
bodyFeatures
)
{
Double
[]
feature
=
bodyFeature
.
getFeature
();
if
(
feature
==
null
||
feature
.
length
<
Constant
.
BODY_FEATURE_DIMS
)
{
if
(
feature
==
null
||
feature
.
length
<
Constant
.
BODY_FEATURE_DIMS
_2048
)
{
continue
;
}
else
if
(
feature
.
length
==
Constant
.
BODY_FEATURE_DIMS_2110
)
{
feature
=
Utils
.
transferBodyFeature
(
feature
);
}
if
(
feature
.
length
>
Constant
.
BODY_FEATURE_DIMS
)
{
feature
=
Arrays
.
copyOfRange
(
feature
,
3
,
Constant
.
BODY_FEATURE_DIMS
+
3
);
if
(
feature
.
length
>
Constant
.
BODY_FEATURE_DIMS_2048
)
{
feature
=
Arrays
.
copyOfRange
(
feature
,
3
,
Constant
.
BODY_FEATURE_DIMS_2048
+
3
);
}
String
fid
=
bodyFeature
.
getBid
();
...
...
@@ -201,20 +205,22 @@ public class PersonService {
}
public
List
<
Person
>
matchPerson
(
String
poolId
,
Person
person
,
int
type
)
throws
Exception
{
public
List
<
Person
>
matchPerson
(
String
poolId
,
Person
person
,
int
type
)
throws
Exception
{
List
<
Person
>
matchResult
=
new
ArrayList
<>();
int
matchResultSize
=
0
;
if
(
type
==
0
)
{
List
<
FaceFeature
>
faceFeatures
=
person
.
getFaceFeatures
();
matchFace
(
faceFeatures
,
poolId
,
matchResult
);
}
else
{
matchResultSize
=
Constant
.
FACE_MATCH_RESULT_SIZE
;
}
else
{
List
<
BodyFeature
>
bodyFeatures
=
person
.
getBodyFeatures
();
matchBody
(
bodyFeatures
,
poolId
,
matchResult
);
matchResultSize
=
Constant
.
BODY_MATCH_RESULT_SIZE
;
}
Stream
<
Person
>
stream
=
matchResult
.
stream
().
sorted
(
Comparator
.
comparingInt
(
Person:
:
getScore
).
reversed
());
if
(
matchResult
.
size
()
>
Constant
.
MATCH_RESULT_SIZE
)
{
stream
=
stream
.
limit
(
5
);
if
(
matchResult
.
size
()
>
matchResultSize
)
{
stream
=
stream
.
limit
(
matchResultSize
);
}
matchResult
=
stream
.
collect
(
Collectors
.
toList
());
return
matchResult
;
...
...
@@ -247,12 +253,15 @@ public class PersonService {
if
(
bodyFeatures
!=
null
&&
bodyFeatures
.
size
()
>
0
)
{
for
(
BodyFeature
faceFeature
:
bodyFeatures
)
{
Double
[]
feature
=
faceFeature
.
getFeature
();
if
(
feature
==
null
||
feature
.
length
<
Constant
.
BODY_FEATURE_DIMS
)
{
if
(
feature
==
null
||
feature
.
length
<
Constant
.
BODY_FEATURE_DIMS
_2048
)
{
log
.
info
(
"人体特征维数小于2048,跳过比对"
);
continue
;
}
else
if
(
feature
.
length
==
Constant
.
BODY_FEATURE_DIMS_2110
)
{
feature
=
Utils
.
transferBodyFeature
(
feature
);
}
if
(
feature
.
length
>
Constant
.
BODY_FEATURE_DIMS
)
{
feature
=
Arrays
.
copyOfRange
(
feature
,
3
,
Constant
.
BODY_FEATURE_DIMS
+
3
);
if
(
feature
.
length
>
Constant
.
BODY_FEATURE_DIMS_2048
)
{
feature
=
Arrays
.
copyOfRange
(
feature
,
3
,
Constant
.
BODY_FEATURE_DIMS_2048
+
3
);
}
Script
script
=
new
Script
(
...
...
@@ -260,16 +269,20 @@ public class PersonService {
"(cosineSimilarity(params.body, 'body') + 1) / 2 * 100"
,
Collections
.
singletonMap
(
"body"
,
feature
));
ScriptScoreQueryBuilder
queryBuilder
=
QueryBuilders
.
scriptScoreQuery
(
QueryBuilders
.
existsQuery
(
"body"
),
script
);
matchResult
.
addAll
(
match0
(
poolId
,
queryBuilder
));
matchResult
.
addAll
(
match0
(
poolId
,
queryBuilder
,
Constant
.
BODY_MATCH_RESULT_SIZE
));
}
}
}
private
List
<
Person
>
match0
(
String
poolId
,
ScriptScoreQueryBuilder
scriptScoreQueryBuilder
)
throws
IOException
{
return
match0
(
poolId
,
scriptScoreQueryBuilder
,
Constant
.
FACE_MATCH_RESULT_SIZE
);
}
private
List
<
Person
>
match0
(
String
poolId
,
ScriptScoreQueryBuilder
scriptScoreQueryBuilder
,
Integer
matchResultSize
)
throws
IOException
{
List
<
Person
>
persons
=
new
ArrayList
<>();
SearchSourceBuilder
builder
=
new
SearchSourceBuilder
()
.
size
(
Constant
.
MATCH_RESULT_SIZE
)
.
size
(
matchResultSize
)
.
query
(
scriptScoreQueryBuilder
)
.
fetchSource
(
new
String
[]{
"personId"
,
"age"
,
"gender"
,
"fid"
},
null
);
SearchRequest
searchRequest
=
new
SearchRequest
(
poolId
)
...
...
src/main/java/com/viontech/match/service/PoolService.java
View file @
6a0f781
...
...
@@ -196,7 +196,7 @@ public class PoolService {
builder
.
startObject
(
"body"
);
{
builder
.
field
(
"type"
,
"dense_vector"
);
builder
.
field
(
"dims"
,
Constant
.
BODY_FEATURE_DIMS
);
builder
.
field
(
"dims"
,
Constant
.
BODY_FEATURE_DIMS
_2048
);
}
builder
.
endObject
();
// 人员id
...
...
src/main/java/com/viontech/match/util/Utils.java
View file @
6a0f781
package
com
.
viontech
.
match
.
util
;
import
java.awt.*
;
import
java.awt.image.BufferedImage
;
import
lombok.extern.slf4j.Slf4j
;
import
java.util.Arrays
;
/**
* .
...
...
@@ -9,24 +10,68 @@ import java.awt.image.BufferedImage;
* @author 谢明辉
* @date 2020/11/23
*/
@Slf4j
@SuppressWarnings
(
"ALL"
)
public
class
Utils
{
public
static
BufferedImage
convertImg2Jpg
(
BufferedImage
image
)
{
BufferedImage
newBufferedImage
;
//防止图片变色
int
width
=
image
.
getWidth
();
int
height
=
image
.
getHeight
();
if
(
width
>
600
||
height
>
600
)
{
newBufferedImage
=
new
BufferedImage
(
600
,
600
,
BufferedImage
.
TYPE_INT_RGB
);
Graphics2D
graphics
=
newBufferedImage
.
createGraphics
();
graphics
.
drawImage
(
image
,
0
,
0
,
600
,
600
,
Color
.
WHITE
,
null
);
/**
* 将 2110 维的人体特征加权计算得到 2048 维特征数据
*
* @param f1 2110 维的人体特征数据
*
* @return 加权计算后的结果
*/
public
static
Double
[]
transferBodyFeature
(
Double
[]
f1
)
{
try
{
int
featureLen
=
f1
[
0
].
intValue
();
int
npiece
=
f1
[
1
].
intValue
();
Double
[]
vec1
=
Arrays
.
copyOfRange
(
f1
,
3
,
2048
+
3
);
Double
[]
temp
=
Arrays
.
copyOfRange
(
f1
,
3
+
featureLen
+
npiece
,
f1
.
length
);
Double
[]
wt1
=
getWeights
(
temp
);
Double
normCoeF1
=
0
D
;
for
(
int
i
=
0
;
i
<
8
;
i
++)
{
normCoeF1
+=
wt1
[
i
]
*
wt1
[
i
]
*
f1
[
3
+
2048
+
i
];
}
normCoeF1
=
1
/
Math
.
sqrt
(
normCoeF1
);
for
(
int
i
=
0
;
i
<
2048
;
i
++)
{
vec1
[
i
]
=
vec1
[
i
]
*
wt1
[
i
/
256
]
*
normCoeF1
;
}
return
vec1
;
}
catch
(
Throwable
e
)
{
log
.
error
(
"转换出错"
,
e
);
}
return
f1
;
}
private
static
Double
[]
getWeights
(
Double
[]
landmarks
)
{
Double
[]
wt
=
new
Double
[
8
];
Arrays
.
fill
(
wt
,
1
D
);
if
(
landmarks
[
15
*
3
+
2
]
>
0.8
&&
landmarks
[
16
*
3
+
2
]
>
0.8
)
{
}
else
if
(
landmarks
[
15
*
3
+
2
]
>
0.8
||
landmarks
[
16
*
3
+
2
]
>
0.8
)
{
wt
[
7
]
=
0.7
;
}
else
if
(
landmarks
[
13
*
3
+
2
]
>
0.8
&&
landmarks
[
14
*
3
+
2
]
>
0.8
)
{
wt
[
7
]
=
0.2
;
wt
[
3
]
=
0.7
;
}
else
if
(
landmarks
[
13
*
3
+
2
]
>
0.8
||
landmarks
[
14
*
3
+
2
]
>
0.8
)
{
wt
[
7
]
=
0.1
;
wt
[
3
]
=
0.4
;
}
else
if
(
landmarks
[
11
*
3
+
2
]
>
0.7
&&
landmarks
[
12
*
3
+
2
]
>
0.7
)
{
wt
[
7
]
=
0
D
;
wt
[
3
]
=
0.2
;
wt
[
6
]
=
0.8
;
wt
[
2
]
=
1.1
;
wt
[
5
]
=
1.1
;
}
else
{
newBufferedImage
=
new
BufferedImage
(
width
,
height
,
BufferedImage
.
TYPE_INT_RGB
);
Graphics2D
graphics
=
newBufferedImage
.
createGraphics
();
graphics
.
drawImage
(
image
,
0
,
0
,
Color
.
WHITE
,
null
);
wt
[
7
]
=
0
D
;
wt
[
3
]
=
0
D
;
wt
[
6
]
=
0.3
;
wt
[
2
]
=
1.2
;
wt
[
5
]
=
1.4
;
}
return
newBufferedImage
;
return
wt
;
}
}
src/test/java/com/viontech/match/util/UtilsTest.java
0 → 100644
View file @
6a0f781
package
com
.
viontech
.
match
.
util
;
import
com.viontech.keliu.utils.JsonUtil
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.junit.jupiter.api.Test
;
import
java.nio.file.Files
;
import
java.nio.file.Paths
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* .
*
* @author 谢明辉
* @date 2021/4/6
*/
class
UtilsTest
{
@Test
void
transferBodyFeature
()
throws
Exception
{
List
<
String
>
strings
=
Files
.
readAllLines
(
Paths
.
get
(
"C:\\Users\\vion\\Desktop\\body.feature"
));
String
s
=
strings
.
get
(
0
);
JSONObject
jsonObject
=
JsonUtil
.
toObject
(
s
);
JSONArray
datas
=
jsonObject
.
getJSONArray
(
"datas"
);
JSONObject
obj
=
datas
.
getJSONObject
(
0
);
JSONArray
data
=
obj
.
getJSONArray
(
"data"
);
List
<
Object
>
objects
=
data
.
toList
();
Double
[]
feature
=
objects
.
toArray
(
new
Double
[]{});
Double
[]
doubles
=
Utils
.
transferBodyFeature
(
feature
);
System
.
out
.
println
(
Arrays
.
toString
(
doubles
));
}
}
\ 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