Skip to content

Commit 130ff41

Browse files
EFRS-1333: Implemented the ability to verify embedding by id with other embeddings
1 parent 475f750 commit 130ff41

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

java/api/src/main/java/com/exadel/frs/core/trainservice/controller/EmbeddingController.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
import com.exadel.frs.core.trainservice.aspect.WriteEndpoint;
3030
import com.exadel.frs.core.trainservice.dto.Base64File;
3131
import com.exadel.frs.core.trainservice.dto.EmbeddingDto;
32+
import com.exadel.frs.core.trainservice.dto.EmbeddingsRecognitionRequest;
33+
import com.exadel.frs.core.trainservice.dto.EmbeddingsVerificationProcessResponse;
34+
import com.exadel.frs.core.trainservice.dto.ProcessEmbeddingsParams;
3235
import com.exadel.frs.core.trainservice.dto.ProcessImageParams;
3336
import com.exadel.frs.core.trainservice.dto.VerificationResult;
3437
import com.exadel.frs.core.trainservice.mapper.EmbeddingMapper;
@@ -69,7 +72,7 @@
6972

7073
@Validated
7174
@RestController
72-
@RequestMapping(API_V1 + "/recognition/faces")
75+
@RequestMapping(API_V1 + "/recognition")
7376
@RequiredArgsConstructor
7477
public class EmbeddingController {
7578

@@ -81,7 +84,7 @@ public class EmbeddingController {
8184

8285
@WriteEndpoint
8386
@ResponseStatus(CREATED)
84-
@PostMapping
87+
@PostMapping("/faces")
8588
public EmbeddingDto addEmbedding(
8689
@ApiParam(value = IMAGE_WITH_ONE_FACE_DESC, required = true)
8790
@RequestParam
@@ -112,7 +115,7 @@ public EmbeddingDto addEmbedding(
112115

113116
@WriteEndpoint
114117
@ResponseStatus(CREATED)
115-
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
118+
@PostMapping(value = "/faces", consumes = MediaType.APPLICATION_JSON_VALUE)
116119
public EmbeddingDto addEmbeddingBase64(
117120
@ApiParam(value = API_KEY_DESC, required = true)
118121
@RequestHeader(X_FRS_API_KEY_HEADER)
@@ -142,7 +145,7 @@ public EmbeddingDto addEmbeddingBase64(
142145
}
143146

144147
@ResponseBody
145-
@GetMapping(value = "/{embeddingId}/img", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
148+
@GetMapping(value = "/faces/{embeddingId}/img", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
146149
public byte[] downloadImg(HttpServletResponse response,
147150
@ApiParam(value = API_KEY_DESC, required = true)
148151
@RequestHeader(name = X_FRS_API_KEY_HEADER)
@@ -157,7 +160,7 @@ public byte[] downloadImg(HttpServletResponse response,
157160
.orElse(new byte[]{});
158161
}
159162

160-
@GetMapping
163+
@GetMapping("/faces")
161164
public Faces listEmbeddings(
162165
@ApiParam(value = API_KEY_DESC, required = true)
163166
@RequestHeader(name = X_FRS_API_KEY_HEADER)
@@ -172,7 +175,7 @@ public Faces listEmbeddings(
172175
}
173176

174177
@WriteEndpoint
175-
@DeleteMapping
178+
@DeleteMapping("/faces")
176179
public Map<String, Object> removeAllSubjectEmbeddings(
177180
@ApiParam(value = API_KEY_DESC, required = true)
178181
@RequestHeader(name = X_FRS_API_KEY_HEADER)
@@ -190,7 +193,7 @@ public Map<String, Object> removeAllSubjectEmbeddings(
190193
}
191194

192195
@WriteEndpoint
193-
@DeleteMapping("/{embeddingId}")
196+
@DeleteMapping("/faces/{embeddingId}")
194197
public EmbeddingDto deleteEmbeddingById(
195198
@ApiParam(value = API_KEY_DESC, required = true)
196199
@RequestHeader(name = X_FRS_API_KEY_HEADER)
@@ -204,7 +207,7 @@ public EmbeddingDto deleteEmbeddingById(
204207
}
205208

206209
@WriteEndpoint
207-
@PostMapping("/delete")
210+
@PostMapping("/faces/delete")
208211
public List<EmbeddingDto> deleteEmbeddingsById(
209212
@ApiParam(value = API_KEY_DESC, required = true)
210213
@RequestHeader(name = X_FRS_API_KEY_HEADER)
@@ -220,7 +223,7 @@ public List<EmbeddingDto> deleteEmbeddingsById(
220223
return dtoList;
221224
}
222225

223-
@PostMapping(value = "/{embeddingId}/verify", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
226+
@PostMapping(value = "/faces/{embeddingId}/verify", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
224227
public VerificationResult recognizeFile(
225228
@ApiParam(value = API_KEY_DESC, required = true)
226229
@RequestHeader(X_FRS_API_KEY_HEADER)
@@ -263,7 +266,7 @@ public VerificationResult recognizeFile(
263266
);
264267
}
265268

266-
@PostMapping(value = "/{embeddingId}/verify", consumes = MediaType.APPLICATION_JSON_VALUE)
269+
@PostMapping(value = "/faces/{embeddingId}/verify", consumes = MediaType.APPLICATION_JSON_VALUE)
267270
public VerificationResult recognizeBase64(
268271
@ApiParam(value = API_KEY_DESC, required = true)
269272
@RequestHeader(X_FRS_API_KEY_HEADER)
@@ -307,6 +310,28 @@ public VerificationResult recognizeBase64(
307310
);
308311
}
309312

313+
@PostMapping(value = "/embeddings/faces/{embeddingId}/verify", consumes = MediaType.APPLICATION_JSON_VALUE)
314+
public EmbeddingsVerificationProcessResponse recognizeEmbeddings(
315+
@ApiParam(value = API_KEY_DESC, required = true)
316+
@RequestHeader(X_FRS_API_KEY_HEADER)
317+
final String apiKey,
318+
@ApiParam(value = IMAGE_ID_DESC, required = true)
319+
@PathVariable
320+
final UUID embeddingId,
321+
@RequestBody
322+
@Valid
323+
final EmbeddingsRecognitionRequest recognitionRequest
324+
) {
325+
ProcessEmbeddingsParams processParams =
326+
ProcessEmbeddingsParams.builder()
327+
.apiKey(apiKey)
328+
.embeddings(recognitionRequest.getEmbeddings())
329+
.additionalParams(Map.of(IMAGE_ID, embeddingId))
330+
.build();
331+
332+
return subjectService.verifyEmbedding(processParams);
333+
}
334+
310335
@RequiredArgsConstructor
311336
private static final class Faces {
312337

java/api/src/main/java/com/exadel/frs/core/trainservice/service/SubjectService.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.exadel.frs.commonservice.entity.Subject;
55
import com.exadel.frs.commonservice.exception.EmbeddingNotFoundException;
66
import com.exadel.frs.commonservice.exception.TooManyFacesException;
7+
import com.exadel.frs.commonservice.exception.WrongEmbeddingCountException;
78
import com.exadel.frs.commonservice.sdk.faces.FacesApiClient;
89
import com.exadel.frs.commonservice.sdk.faces.feign.dto.FindFacesResponse;
910
import com.exadel.frs.commonservice.sdk.faces.feign.dto.FindFacesResult;
@@ -13,11 +14,17 @@
1314
import com.exadel.frs.core.trainservice.component.classifiers.EuclideanDistanceClassifier;
1415
import com.exadel.frs.core.trainservice.dao.SubjectDao;
1516
import com.exadel.frs.core.trainservice.dto.EmbeddingInfo;
17+
import com.exadel.frs.core.trainservice.dto.EmbeddingVerificationProcessResult;
18+
import com.exadel.frs.core.trainservice.dto.EmbeddingsVerificationProcessResponse;
1619
import com.exadel.frs.core.trainservice.dto.FaceVerification;
20+
import com.exadel.frs.core.trainservice.dto.ProcessEmbeddingsParams;
1721
import com.exadel.frs.core.trainservice.dto.ProcessImageParams;
1822
import com.exadel.frs.core.trainservice.system.global.Constants;
23+
import java.util.stream.Collectors;
24+
import java.util.stream.IntStream;
1925
import lombok.RequiredArgsConstructor;
2026
import lombok.extern.slf4j.Slf4j;
27+
import org.apache.commons.lang3.ArrayUtils;
2128
import org.apache.commons.lang3.StringUtils;
2229
import org.apache.commons.lang3.tuple.Pair;
2330
import org.springframework.stereotype.Service;
@@ -36,6 +43,7 @@
3643
@Slf4j
3744
public class SubjectService {
3845

46+
private static final int MINIMUM_EMBEDDING_COUNT = 1;
3947
private static final int MAX_FACES_TO_SAVE = 1;
4048
public static final int MAX_FACES_TO_RECOGNIZE = 2;
4149

@@ -272,4 +280,28 @@ public Pair<List<FaceVerification>, PluginsVersions> verifyFace(ProcessImagePara
272280
Boolean.TRUE.equals(processImageParams.getStatus()) ? findFacesResponse.getPluginsVersions() : null
273281
);
274282
}
283+
284+
public EmbeddingsVerificationProcessResponse verifyEmbedding(ProcessEmbeddingsParams processEmbeddingsParams) {
285+
double[][] targets = processEmbeddingsParams.getEmbeddings();
286+
if (ArrayUtils.isEmpty(targets)) {
287+
throw new WrongEmbeddingCountException(MINIMUM_EMBEDDING_COUNT, 0);
288+
}
289+
290+
UUID sourceId = (UUID) processEmbeddingsParams.getAdditionalParams().get(Constants.IMAGE_ID);
291+
String apiKey = processEmbeddingsParams.getApiKey();
292+
293+
List<EmbeddingVerificationProcessResult> results =
294+
Arrays.stream(targets)
295+
.map(target -> processTarget(target, sourceId, apiKey))
296+
.sorted((e1, e2) -> Float.compare(e2.getSimilarity(), e1.getSimilarity()))
297+
.collect(Collectors.toList());
298+
299+
return new EmbeddingsVerificationProcessResponse(results);
300+
}
301+
302+
private EmbeddingVerificationProcessResult processTarget(double[] target, UUID sourceId, String apiKey) {
303+
double similarity = predictor.verify(apiKey, target, sourceId);
304+
float scaledSimilarity = BigDecimal.valueOf(similarity).setScale(5, HALF_UP).floatValue();
305+
return new EmbeddingVerificationProcessResult(target, scaledSimilarity);
306+
}
275307
}

0 commit comments

Comments
 (0)