|
|
@@ -38,37 +38,37 @@ The face recognition pipeline is an end-to-end system dedicated to solving face
|
|
|
<tr>
|
|
|
<td>BlazeFace-FPN-SSH</td><td><a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0b2/BlazeFace-FPN-SSH_infer.tar">Inference Model</a>/<a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_pretrained_model/BlazeFace-FPN-SSH_pretrained.pdparams">Trained Model</a></td>
|
|
|
<td>83.2/80.5/60.5</td>
|
|
|
-<td></td>
|
|
|
-<td></td>
|
|
|
+<td>52.4</td>
|
|
|
+<td>73.2</td>
|
|
|
<td>0.606</td>
|
|
|
<td>Improved BlazeFace with FPN and SSH structures</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>PicoDet_LCNet_x2_5_face</td><td><a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0b2/PicoDet_LCNet_x2_5_face_infer.tar">Inference Model</a>/<a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_pretrained_model/PicoDet_LCNet_x2_5_face_pretrained.pdparams">Trained Model</a></td>
|
|
|
<td>93.7/90.7/68.1</td>
|
|
|
-<td></td>
|
|
|
-<td></td>
|
|
|
+<td>33.7</td>
|
|
|
+<td>185.1</td>
|
|
|
<td>28.9</td>
|
|
|
<td>Face detection model based on PicoDet_LCNet_x2_5</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>PP-YOLOE_plus-S_face</td><td><a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0b2/PP-YOLOE_plus-S_face_infer.tar">Inference Model</a>/<a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_pretrained_model/PP-YOLOE_plus-S_face_pretrained.pdparams">Trained Model</a></td>
|
|
|
<td>93.9/91.8/79.8</td>
|
|
|
-<td></td>
|
|
|
-<td></td>
|
|
|
+<td>25.8</td>
|
|
|
+<td>159.9</td>
|
|
|
<td>26.5</td>
|
|
|
<td>Face detection model based on PP-YOLOE_plus-S</td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
-<p>Note: The above accuracy metrics are evaluated on the WIDER-FACE validation set with an input size of 640x640. All GPU inference times are based on an NVIDIA Tesla T4 machine with FP32 precision. CPU inference speeds are based on an Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz with 8 threads and FP32 precision.</p>
|
|
|
+<p>Note: The above accuracy metrics are evaluated on the WIDER-FACE validation set with an input size of 640x640. All GPU inference times are based on an NVIDIA V100 machine with FP32 precision. CPU inference speeds are based on an Intel(R) Xeon(R) Gold 6271C CPU @ 2.60GHz and FP32 precision.</p>
|
|
|
<p><b>Face Recognition Module</b>:</p>
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th>Model</th><th>Model Download Link</th>
|
|
|
<th>Output Feature Dimension</th>
|
|
|
-<th>AP (%)<br/>AgeDB-30/CFP-FP/LFW</th>
|
|
|
+<th>Acc (%)<br/>AgeDB-30/CFP-FP/LFW</th>
|
|
|
<th>GPU Inference Time (ms)</th>
|
|
|
<th>CPU Inference Time</th>
|
|
|
<th>Model Size (M)</th>
|
|
|
@@ -80,8 +80,8 @@ The face recognition pipeline is an end-to-end system dedicated to solving face
|
|
|
<td>MobileFaceNet</td><td><a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0b2/MobileFaceNet_infer.tar">Inference Model</a>/<a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_pretrained_model/MobileFaceNet_pretrained.pdparams">Trained Model</a></td>
|
|
|
<td>128</td>
|
|
|
<td>96.28/96.71/99.58</td>
|
|
|
-<td></td>
|
|
|
-<td></td>
|
|
|
+<td>5.7</td>
|
|
|
+<td>101.6</td>
|
|
|
<td>4.1</td>
|
|
|
<td>Face recognition model trained on MS1Mv3 based on MobileFaceNet</td>
|
|
|
</tr>
|
|
|
@@ -89,8 +89,8 @@ The face recognition pipeline is an end-to-end system dedicated to solving face
|
|
|
<td>ResNet50_face</td><td><a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0b2/ResNet50_face_infer.tar">Inference Model</a>/<a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/official_pretrained_model/ResNet50_face_pretrained.pdparams">Trained Model</a></td>
|
|
|
<td>512</td>
|
|
|
<td>98.12/98.56/99.77</td>
|
|
|
-<td></td>
|
|
|
-<td></td>
|
|
|
+<td>8.7</td>
|
|
|
+<td>200.7</td>
|
|
|
<td>87.2</td>
|
|
|
<td>Face recognition model trained on MS1Mv3 based on ResNet50</td>
|
|
|
</tr>
|
|
|
@@ -128,9 +128,10 @@ from paddlex import create_pipeline
|
|
|
|
|
|
pipeline = create_pipeline(pipeline="face_recognition")
|
|
|
|
|
|
-pipeline.build_index(data_root="face_demo_gallery", index_dir="face_gallery_index")
|
|
|
+index_data = pipeline.build_index(gallery_imgs="face_demo_gallery", gallery_label="face_demo_gallery/gallery.txt")
|
|
|
+index_data.save("face_index")
|
|
|
|
|
|
-output = pipeline.predict("friends1.jpg")
|
|
|
+output = pipeline.predict("friends1.jpg", index=index_data)
|
|
|
for res in output:
|
|
|
res.print()
|
|
|
res.save_to_img("./output/")
|
|
|
@@ -183,19 +184,41 @@ In the above Python script, the following steps are executed:
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr>
|
|
|
-<td><code>data_root</code></td>
|
|
|
-<td>The root directory of the dataset, with data organization referring to <a href="#2.3-Data-Organization-for-Building-a-Feature-Library">Section 2.3: Data Organization for Building a Feature Library</a></td>
|
|
|
+<td><code>gallery_imgs</code></td>
|
|
|
+<td>Base library images to be added, supported formats: 1. <code>str</code> type representing the root directory of images, with data organization consistent with the method used when constructing the index library, refer to <a href="#2.3-Data-Organization-for-Building-a-Feature-Library">Section 2.3: Data Organization for Building a Feature Library</a>; 2. <code>[numpy.ndarray, numpy.ndarray, ..]</code> type base library image data.</td>
|
|
|
+<td><code>str</code>|<code>list</code></td>
|
|
|
+<td>None</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>gallery_label</code></td>
|
|
|
+<td>Annotation information for base library images, supported formats: 1. <code>str</code> type representing the path to the annotation file, with data organization consistent with the method used when constructing the feature library, refer to <a href="#2.3-Data-Organization-for-Building-a-Feature-Library">Section 2.3: Data Organization for Building a Feature Library</a>; 2. <code>[str, str, ..]</code> type representing the annotations of base library images.</td>
|
|
|
<td><code>str</code></td>
|
|
|
<td>None</td>
|
|
|
</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+
|
|
|
+The feature library object `index` supports the `save` method, which is used to save the feature library to disk:
|
|
|
+
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Parameter</th>
|
|
|
+<th>Description</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Default Value</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
<tr>
|
|
|
-<td><code>index_dir</code></td>
|
|
|
-<td>The save path for the feature library. After successfully calling the <code>build_index</code> method, two files will be generated in this path:<br/> <code>"id_map.pkl"</code> saves the mapping relationship between image IDs and image feature labels;<br/> <code>"vector.index"</code> stores the feature vectors of each image.</td>
|
|
|
+<td><code>save_path</code></td>
|
|
|
+<td>The directory to save the feature library file, e.g., <code>drink_index</code>.</td>
|
|
|
<td><code>str</code></td>
|
|
|
<td>None</td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
+
|
|
|
(3) Call the `predict` method of the face recognition pipeline object for inference prediction: The `predict` method parameter is `x`, used to input data to be predicted, supporting multiple input methods, as shown in the following examples:
|
|
|
|
|
|
<table>
|
|
|
@@ -216,7 +239,7 @@ In the above Python script, the following steps are executed:
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><code>str</code></td>
|
|
|
-<td>Supports passing in the URL of the data file to be predicted, such as the network URL of an image file: <a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/general_ocr_001.png">Example</a>.</td>
|
|
|
+<td>Supports passing in the URL of the data file to be predicted, such as the network URL of an image file: <a href="https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/friends1.jpg">Example</a>.</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><code>str</code></td>
|
|
|
@@ -268,8 +291,8 @@ For example, if your configuration file is saved at `./my_path/face_recognition.
|
|
|
|
|
|
```python
|
|
|
from paddlex import create_pipeline
|
|
|
-pipeline = create_pipeline(pipeline="./my_path/face_recognition.yaml")
|
|
|
-pipeline.build_index(data_root="face_demo_gallery", index_dir="face_gallery_index")
|
|
|
+pipeline = create_pipeline(pipeline="./my_path/face_recognition.yaml", index="face_index")
|
|
|
+
|
|
|
output = pipeline.predict("friends1.jpg")
|
|
|
for res in output:
|
|
|
res.print()
|
|
|
@@ -278,16 +301,17 @@ for res in output:
|
|
|
|
|
|
#### 2.2.3 Adding and Deleting Operations in the Face Feature Library
|
|
|
|
|
|
-If you wish to add more face images to the feature library, you can call the `add_index` method; to delete face image features, you can call the `delete_index` method.
|
|
|
+If you wish to add more face images to the feature library, you can call the `append_index` method; to delete face image features, you can call the `remove_index` method.
|
|
|
|
|
|
```python
|
|
|
from paddlex import create_pipeline
|
|
|
|
|
|
pipeline = create_pipeline(pipeline="face_recognition")
|
|
|
|
|
|
-pipeline.add_index(data_root="add_gallery", index_dir="face_gallery_index")
|
|
|
-
|
|
|
-pipeline.delete_index(data_root="delete_gallery", index_dir="face_gallery_index")
|
|
|
+index_data = pipeline.build_index(gallery_imgs="face_demo_gallery", gallery_label="face_demo_gallery/gallery.txt", index_type="IVF", metric_type="IP")
|
|
|
+index_data = pipeline.append_index(gallery_imgs="face_demo_gallery", gallery_label="face_demo_gallery/gallery.txt", index=index_data)
|
|
|
+index_data = pipeline.remove_index(remove_ids="face_demo_gallery/remove_ids.txt", index=index_data)
|
|
|
+index_data.save("face_index")
|
|
|
```
|
|
|
|
|
|
The `add_index` method parameters are described as follows:
|
|
|
@@ -303,45 +327,44 @@ The `add_index` method parameters are described as follows:
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr>
|
|
|
-<td><code>data_root</code></td>
|
|
|
-<td>The root directory of the dataset to be added. The data organization method is the same as when building the feature library. Refer to <a href="###2.3-Data-Organization-for-Feature-Library-Construction">Section 2.3 Data Organization for Feature Library Construction</a>.</td>
|
|
|
-<td><code>str</code></td>
|
|
|
+<td><code>gallery_imgs</code></td>
|
|
|
+<td>Base library images to be added, supported formats: 1. <code>str</code> type representing the root directory of images, with data organization consistent with the method used when constructing the index library, refer to <a href="#2.3-Data-Organization-for-Building-a-Feature-Library">Section 2.3: Data Organization for Building a Feature Library</a>; 2. <code>[numpy.ndarray, numpy.ndarray, ..]</code> type base library image data.</td>
|
|
|
+<td><code>str</code>|<code>list</code></td>
|
|
|
<td>None</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
-<td><code>index_dir</code></td>
|
|
|
-<td>The save path of the feature library to which features are added. After successfully calling the <code>add_index</code> method, the face image features in <code>data_root</code> will be added to the face feature library originally saved at <code>index_dir</code>.</td>
|
|
|
-<td><code>str</code></td>
|
|
|
+<td><code>gallery_label</code></td>
|
|
|
+<td>Annotation information for base library images, supported formats: 1. <code>str</code> type representing the path to the annotation file, with data organization consistent with the method used when constructing the feature library, refer to <a href="#2.3-Data-Organization-for-Building-a-Feature-Library">Section 2.3: Data Organization for Building a Feature Library</a>; 2. <code>[str, str, ..]</code> type representing the annotations of base library images.</td>
|
|
|
+<td><code>str</code>|<code>list</code></td>
|
|
|
<td>None</td>
|
|
|
</tr>
|
|
|
-</tbody>
|
|
|
-</table>
|
|
|
-The `delete_index` method parameters are described as follows:
|
|
|
-
|
|
|
-<table>
|
|
|
-<thead>
|
|
|
<tr>
|
|
|
-<th>Parameter</th>
|
|
|
-<th>Description</th>
|
|
|
-<th>Type</th>
|
|
|
-<th>Default</th>
|
|
|
+<td><code>remove_ids</code></td>
|
|
|
+<td>Index numbers to be removed, supported formats: 1. <code>str</code> type representing the path of a txt file, with content being the IDs of indexes to be removed, one "id" per line; 2. <code>[int, int, ..]</code> type representing the index numbers to be removed. Only effective in <code>remove_index</code>.</td>
|
|
|
+<td><code>str</code>|<code>list</code></td>
|
|
|
+<td>None</td>
|
|
|
</tr>
|
|
|
-</thead>
|
|
|
-<tbody>
|
|
|
<tr>
|
|
|
-<td><code>data_root</code></td>
|
|
|
-<td>The root directory of the dataset to be deleted. The data organization method is the same as when building the feature library. Refer to <a href="#2.3-Data-Organization-for-Feature-Library-Construction">Section 2.3 Data Organization for Feature Library Construction</a>.</td>
|
|
|
-<td><code>str</code></td>
|
|
|
+<td><code>index</code></td>
|
|
|
+<td>Feature library, supported formats: 1. The path to the directory containing the feature library files (<code>vector.index</code> and <code>index_info.yaml</code>); 2. <code>IndexData</code> type feature library object, only effective in <code>append_index</code> and <code>remove_index</code>, representing the feature library to be modified.</td>
|
|
|
+<td><code>str</code>|<code>IndexData</code></td>
|
|
|
<td>None</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
-<td><code>index_dir</code></td>
|
|
|
-<td>The save path of the feature library from which features are deleted. After successfully calling the <code>delete_index</code> method, the face image features in <code>data_root</code> will be deleted from the face feature library originally saved at <code>index_dir</code>.</td>
|
|
|
+<td><code>index_type</code></td>
|
|
|
+<td>Supports <code>HNSW32</code>, <code>IVF</code>, <code>Flat</code>. Among them, <code>HNSW32</code> offers fast retrieval speed and high accuracy, but does not support the <code>remove_index()</code> operation; <code>IVF</code> offers fast retrieval speed but relatively lower accuracy, supporting both <code>append_index()</code> and <code>remove_index()</code> operations; <code>Flat</code> offers lower retrieval speed but higher accuracy, supporting both <code>append_index()</code> and <code>remove_index()</code> operations.</td>
|
|
|
<td><code>str</code></td>
|
|
|
-<td>None</td>
|
|
|
+<td><code>HNSW32</code></td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>metric_type</code></td>
|
|
|
+<td>Supports: <code>IP</code>, Inner Product; <code>L2</code>, Euclidean Distance.</td>
|
|
|
+<td><code>str</code></td>
|
|
|
+<td><code>IP</code></td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
+
|
|
|
### 2.3 Data Organization for Feature Library Construction
|
|
|
|
|
|
The face recognition pipeline example in PaddleX requires a pre-constructed feature library for face feature retrieval. If you wish to build a face feature library with private data, you need to organize the data as follows:
|
|
|
@@ -354,7 +377,10 @@ data_root # Root directory of the dataset, the directory name can be
|
|
|
│ │ ├── xxx.jpg # Image, nested directories are supported
|
|
|
│ │ ...
|
|
|
│ ├── ID1 # Identity ID name, preferably meaningful, such as a person's name
|
|
|
-│ │ ...
|
|
|
+│ │ ├── xxx.jpg # Image, nested directories are supported
|
|
|
+│ │ ├── xxx.jpg # Image, nested directories are supported
|
|
|
+│ │ ...
|
|
|
+│ ...
|
|
|
└── gallery.txt # Annotation file for the feature library dataset, the file name cannot be changed. Each line gives the path of the face image to be retrieved and the image feature label, separated by a space. Example content: images/Chandler/Chandler00037.jpg Chandler
|
|
|
```
|
|
|
|
|
|
@@ -373,73 +399,217 @@ Below are the API reference and multi-language service invocation examples:
|
|
|
|
|
|
<details><summary>API Reference</summary>
|
|
|
|
|
|
-<p>For main operations provided by the service:</p>
|
|
|
+<p>The main operations provided by the service are as follows:</p>
|
|
|
+<ul>
|
|
|
+<li><b><code>buildIndex</code></b></li>
|
|
|
+</ul>
|
|
|
+<p>Build feature vector index.</p>
|
|
|
+<p><code>POST /face-recognition-index-build</code></p>
|
|
|
<ul>
|
|
|
-<li>The HTTP request method is POST.</li>
|
|
|
-<li>The request body and the response body are both JSON data (JSON objects).</li>
|
|
|
-<li>When the request is successfully processed, the response status code is <code>200</code>, and the attributes of the response body are as follows:</li>
|
|
|
+<li>The properties of the request body are as follows:</li>
|
|
|
</ul>
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th>Name</th>
|
|
|
<th>Type</th>
|
|
|
-<th>Meaning</th>
|
|
|
+<th>Description</th>
|
|
|
+<th>Required</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr>
|
|
|
-<td><code>errorCode</code></td>
|
|
|
-<td><code>integer</code></td>
|
|
|
-<td>Error code. Fixed to <code>0</code>.</td>
|
|
|
+<td><code>imageLabelPairs</code></td>
|
|
|
+<td><code>array</code></td>
|
|
|
+<td>Image-label pairs used to build the index.</td>
|
|
|
+<td>Yes</td>
|
|
|
</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<p>Each element in <code>imageLabelPairs</code> is an <code>object</code> with the following properties:</p>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>image</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>The URL of the image file accessible to the service or the Base64 encoded content of the image file.</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>label</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>Label.</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<ul>
|
|
|
+<li>When the request is successfully processed, the <code>result</code> in the response body has the following properties:</li>
|
|
|
+</ul>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
<tr>
|
|
|
-<td><code>errorMsg</code></td>
|
|
|
+<td><code>indexKey</code></td>
|
|
|
<td><code>string</code></td>
|
|
|
-<td>Error description. Fixed to <code>"Success"</code>.</td>
|
|
|
+<td>The key corresponding to the index, used to identify the established index. Can be used as input for other operations.</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>idMap</code></td>
|
|
|
+<td><code>object</code></td>
|
|
|
+<td>Mapping from vector ID to label.</td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
-<p>The response body may also have a <code>result</code> attribute of type <code>object</code>, which stores the operation result information.</p>
|
|
|
<ul>
|
|
|
-<li>When the request is not successfully processed, the attributes of the response body are as follows:</li>
|
|
|
+<li><b><code>addImagesToIndex</code></b></li>
|
|
|
+</ul>
|
|
|
+<p>Add images (corresponding feature vectors) to the index.</p>
|
|
|
+<p><code>POST /face-recognition-index-add</code></p>
|
|
|
+<ul>
|
|
|
+<li>The properties of the request body are as follows:</li>
|
|
|
</ul>
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th>Name</th>
|
|
|
<th>Type</th>
|
|
|
-<th>Meaning</th>
|
|
|
+<th>Description</th>
|
|
|
+<th>Required</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr>
|
|
|
-<td><code>errorCode</code></td>
|
|
|
-<td><code>integer</code></td>
|
|
|
-<td>Error code. Same as the response status code.</td>
|
|
|
+<td><code>imageLabelPairs</code></td>
|
|
|
+<td><code>array</code></td>
|
|
|
+<td>Image-label pairs used to build the index.</td>
|
|
|
+<td>Yes</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
-<td><code>errorMsg</code></td>
|
|
|
+<td><code>indexKey</code></td>
|
|
|
<td><code>string</code></td>
|
|
|
-<td>Error description.</td>
|
|
|
+<td>The key corresponding to the index. Provided by the <code>buildIndex</code> operation.</td>
|
|
|
+<td>Yes</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<p>Each element in <code>imageLabelPairs</code> is an <code>object</code> with the following properties:</p>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>image</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>The URL of the image file accessible to the service or the Base64 encoded content of the image file.</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>label</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>Label.</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<ul>
|
|
|
+<li>When the request is successfully processed, the <code>result</code> in the response body has the following properties:</li>
|
|
|
+</ul>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>idMap</code></td>
|
|
|
+<td><code>object</code></td>
|
|
|
+<td>Mapping from vector ID to label.</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<ul>
|
|
|
+<li><b><code>removeImagesFromIndex</code></b></li>
|
|
|
+</ul>
|
|
|
+<p>Remove images (corresponding feature vectors) from the index.</p>
|
|
|
+<p><code>POST /face-recognition-index-remove</code></p>
|
|
|
+<ul>
|
|
|
+<li>The properties of the request body are as follows:</li>
|
|
|
+</ul>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+<th>Required</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>ids</code></td>
|
|
|
+<td><code>array</code></td>
|
|
|
+<td>IDs of vectors to be removed from the index.</td>
|
|
|
+<td>Yes</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>indexKey</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>The key corresponding to the index. Provided by the <code>buildIndex</code> operation.</td>
|
|
|
+<td>Yes</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<ul>
|
|
|
+<li>When the request is successfully processed, the <code>result</code> in the response body has the following properties:</li>
|
|
|
+</ul>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>idMap</code></td>
|
|
|
+<td><code>object</code></td>
|
|
|
+<td>Mapping from vector ID to label.</td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
-<p>The main operations provided by the service are as follows:</p>
|
|
|
<ul>
|
|
|
<li><b><code>infer</code></b></li>
|
|
|
</ul>
|
|
|
-<p>Obtain OCR results for an image.</p>
|
|
|
-<p><code>POST /ocr</code></p>
|
|
|
+<p>Perform image recognition.</p>
|
|
|
+<p><code>POST /face-recognition-infer</code></p>
|
|
|
<ul>
|
|
|
-<li>The attributes of the request body are as follows:</li>
|
|
|
+<li>The properties of the request body are as follows:</li>
|
|
|
</ul>
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th>Name</th>
|
|
|
<th>Type</th>
|
|
|
-<th>Meaning</th>
|
|
|
+<th>Description</th>
|
|
|
<th>Required</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
@@ -447,357 +617,173 @@ Below are the API reference and multi-language service invocation examples:
|
|
|
<tr>
|
|
|
<td><code>image</code></td>
|
|
|
<td><code>string</code></td>
|
|
|
-<td>The URL of an accessible image file or the Base64 encoded result of the image file content.</td>
|
|
|
+<td>The URL of the image file accessible to the service or the Base64 encoded content of the image file.</td>
|
|
|
<td>Yes</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
-<td><code>inferenceParams</code></td>
|
|
|
-<td><code>object</code></td>
|
|
|
-<td>Inference parameters.</td>
|
|
|
+<td><code>indexKey</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>The key corresponding to the index. Provided by the <code>buildIndex</code> operation.</td>
|
|
|
<td>No</td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
-<p>The attributes of```markdown</p>
|
|
|
-<details>
|
|
|
-<summary>Python</summary>
|
|
|
+<ul>
|
|
|
+<li>When the request is successfully processed, the <code>result</code> in the response body has the following properties:</li>
|
|
|
+</ul>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>faces</code></td>
|
|
|
+<td><code>array</code></td>
|
|
|
+<td>Information about detected faces.</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>image</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>Recognition result image. The image is in JPEG format and encoded using Base64.</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<p>Each element in <code>faces</code> is an <code>object</code> with the following properties:</p>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>bbox</code></td>
|
|
|
+<td><code>array</code></td>
|
|
|
+<td>Face target position. The elements in the array are the x-coordinate of the top-left corner, the y-coordinate of the top-left corner, the x-coordinate of the bottom-right corner, and the y-coordinate of the bottom-right corner, in order.</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>recResults</code></td>
|
|
|
+<td><code>array</code></td>
|
|
|
+<td>Recognition results.</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>score</code></td>
|
|
|
+<td><code>number</code></td>
|
|
|
+<td>Detection score.</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+<p>Each element in <code>recResults</code> is an <code>object</code> with the following properties:</p>
|
|
|
+<table>
|
|
|
+<thead>
|
|
|
+<tr>
|
|
|
+<th>Name</th>
|
|
|
+<th>Type</th>
|
|
|
+<th>Description</th>
|
|
|
+</tr>
|
|
|
+</thead>
|
|
|
+<tbody>
|
|
|
+<tr>
|
|
|
+<td><code>label</code></td>
|
|
|
+<td><code>string</code></td>
|
|
|
+<td>Label.</td>
|
|
|
+</tr>
|
|
|
+<tr>
|
|
|
+<td><code>score</code></td>
|
|
|
+<td><code>number</code></td>
|
|
|
+<td>Recognition score.</td>
|
|
|
+</tr>
|
|
|
+</tbody>
|
|
|
+</table>
|
|
|
+</details>
|
|
|
|
|
|
+<details><summary>Multilingual Service Invocation Examples</summary>
|
|
|
|
|
|
<pre><code class="language-python">import base64
|
|
|
+import pprint
|
|
|
+import sys
|
|
|
+
|
|
|
import requests
|
|
|
|
|
|
-API_URL = "http://localhost:8080/ocr" # Service URL
|
|
|
-image_path = "./demo.jpg"
|
|
|
+API_BASE_URL = "http://0.0.0.0:8080"
|
|
|
+
|
|
|
+base_image_label_pairs = [
|
|
|
+ {"image": "./demo0.jpg", "label": "ID0"},
|
|
|
+ {"image": "./demo1.jpg", "label": "ID1"},
|
|
|
+ {"image": "./demo2.jpg", "label": "ID2"},
|
|
|
+]
|
|
|
+image_label_pairs_to_add = [
|
|
|
+ {"image": "./demo3.jpg", "label": "ID2"},
|
|
|
+]
|
|
|
+ids_to_remove = [1]
|
|
|
+infer_image_path = "./demo4.jpg"
|
|
|
output_image_path = "./out.jpg"
|
|
|
|
|
|
-# Encode the local image to Base64
|
|
|
-with open(image_path, "rb") as file:
|
|
|
+for pair in base_image_label_pairs:
|
|
|
+ with open(pair["image"], "rb") as file:
|
|
|
+ image_bytes = file.read()
|
|
|
+ image_data = base64.b64encode(image_bytes).decode("ascii")
|
|
|
+ pair["image"] = image_data
|
|
|
+
|
|
|
+payload = {"imageLabelPairs": base_image_label_pairs}
|
|
|
+resp_index_build = requests.post(f"{API_BASE_URL}/face-recognition-index-build", json=payload)
|
|
|
+if resp_index_build.status_code != 200:
|
|
|
+ print(f"Request to face-recognition-index-build failed with status code {resp_index_build}.")
|
|
|
+ pprint.pp(resp_index_build.json())
|
|
|
+ sys.exit(1)
|
|
|
+result_index_build = resp_index_build.json()["result"]
|
|
|
+print(f"Number of images indexed: {len(result_index_build['idMap'])}")
|
|
|
+
|
|
|
+for pair in image_label_pairs_to_add:
|
|
|
+ with open(pair["image"], "rb") as file:
|
|
|
+ image_bytes = file.read()
|
|
|
+ image_data = base64.b64encode(image_bytes).decode("ascii")
|
|
|
+ pair["image"] = image_data
|
|
|
+
|
|
|
+payload = {"imageLabelPairs": image_label_pairs_to_add, "indexKey": result_index_build["indexKey"]}
|
|
|
+resp_index_add = requests.post(f"{API_BASE_URL}/face-recognition-index-add", json=payload)
|
|
|
+if resp_index_add.status_code != 200:
|
|
|
+ print(f"Request to face-recognition-index-add failed with status code {resp_index_add}.")
|
|
|
+ pprint.pp(resp_index_add.json())
|
|
|
+ sys.exit(1)
|
|
|
+result_index_add = resp_index_add.json()["result"]
|
|
|
+print(f"Number of images indexed: {len(result_index_add['idMap'])}")
|
|
|
+
|
|
|
+payload = {"ids": ids_to_remove, "indexKey": result_index_build["indexKey"]}
|
|
|
+resp_index_remove = requests.post(f"{API_BASE_URL}/face-recognition-index-remove", json=payload)
|
|
|
+if resp_index_remove.status_code != 200:
|
|
|
+ print(f"Request to face-recognition-index-remove failed with status code {resp_index_remove}.")
|
|
|
+ pprint.pp(resp_index_remove.json())
|
|
|
+ sys.exit(1)
|
|
|
+result_index_remove = resp_index_remove.json()["result"]
|
|
|
+print(f"Number of images indexed: {len(result_index_remove['idMap'])}")
|
|
|
+
|
|
|
+with open(infer_image_path, "rb") as file:
|
|
|
image_bytes = file.read()
|
|
|
image_data = base64.b64encode(image_bytes).decode("ascii")
|
|
|
|
|
|
-payload = {"image": image_data} # Base64 encoded file content or image URL
|
|
|
+payload = {"image": image_data, "indexKey": result_index_build["indexKey"]}
|
|
|
+resp_infer = requests.post(f"{API_BASE_URL}/face-recognition-infer", json=payload)
|
|
|
+if resp_infer.status_code != 200:
|
|
|
+ print(f"Request to face-recogntion-infer failed with status code {resp_infer}.")
|
|
|
+ pprint.pp(resp_infer.json())
|
|
|
+ sys.exit(1)
|
|
|
+result_infer = resp_infer.json()["result"]
|
|
|
|
|
|
-# Call the API
|
|
|
-response = requests.post(API_URL, json=payload)
|
|
|
-
|
|
|
-# Process the response data
|
|
|
-assert response.status_code == 200
|
|
|
-result = response.json()["result"]
|
|
|
with open(output_image_path, "wb") as file:
|
|
|
- file.write(base64.b64decode(result["image"]))
|
|
|
+ file.write(base64.b64decode(result_infer["image"]))
|
|
|
print(f"Output image saved at {output_image_path}")
|
|
|
-print("\nDetected texts:")
|
|
|
-print(result["texts"])
|
|
|
-</code></pre></details>
|
|
|
-
|
|
|
-<details><summary>C++</summary>
|
|
|
-
|
|
|
-<pre><code class="language-cpp">#include <iostream>
|
|
|
-#include "cpp-httplib/httplib.h" // https://github.com/Huiyicc/cpp-httplib
|
|
|
-#include "nlohmann/json.hpp" // https://github.com/nlohmann/json
|
|
|
-#include "base64.hpp" // https://github.com/tobiaslocker/base64
|
|
|
-
|
|
|
-int main() {
|
|
|
- httplib::Client client("localhost:8080");
|
|
|
- const std::string imagePath = "./demo.jpg";
|
|
|
- const std::string outputImagePath = "./out.jpg";
|
|
|
-
|
|
|
- httplib::Headers headers = {
|
|
|
- {"Content-Type", "application/json"}
|
|
|
- };
|
|
|
-
|
|
|
- // Encode the local image to Base64
|
|
|
- std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
|
|
|
- std::streamsize size = file.tellg();
|
|
|
- file.seekg(0, std::ios::beg);
|
|
|
-
|
|
|
- std::vector<char> buffer(size);
|
|
|
- if (!file.read(buffer.data(), size)) {
|
|
|
- std::cerr << "Error reading file." << std::endl;
|
|
|
- return 1;
|
|
|
- }
|
|
|
- std::string bufferStr(reinterpret_cast<const char*>(buffer.data()), buffer.size());
|
|
|
- std::string encodedImage = base64::to_base64(bufferStr);
|
|
|
-
|
|
|
- nlohmann::json jsonObj;
|
|
|
- jsonObj["image"] = encodedImage;
|
|
|
- std::string body = jsonObj.dump();
|
|
|
-
|
|
|
- // Call the API
|
|
|
- auto response = client.Post("/ocr", headers, body, "application/json");
|
|
|
- // Process the response data
|
|
|
- if (response && response->status == 200) {
|
|
|
- nlohmann::json jsonResponse = nlohmann::json::parse(response->body);
|
|
|
- auto result = jsonResponse["result"];
|
|
|
-
|
|
|
- encodedImage = result["image"];
|
|
|
- std::string decodedString = base64::from_base64(encodedImage);
|
|
|
- std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
|
|
|
- std::ofstream outputImage(outputImagePath, std::ios::binary | std::ios::out);
|
|
|
- if (outputImage.is_open()) {
|
|
|
- outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
|
|
|
- outputImage.close();
|
|
|
- std::cout << "Output image saved at " << outputImagePath << std::endl;
|
|
|
- } else {
|
|
|
- std::cerr << "Unable to open file for writing: " << outputImagePath << std::endl;
|
|
|
- }
|
|
|
-
|
|
|
- auto texts = result["texts"];
|
|
|
- std::cout << "\nDetected texts:" << std::endl;
|
|
|
- for (const auto& text : texts) {
|
|
|
- std::cout << text << std::endl;
|
|
|
- }
|
|
|
- } else {
|
|
|
- std::cout << "Failed to send HTTP request." << std::endl;
|
|
|
- return 1;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-</code></pre></details>
|
|
|
-``````markdown
|
|
|
-# Tutorial on Artificial Intelligence and Computer Vision
|
|
|
-
|
|
|
-This tutorial, intended for numerous developers, covers the basics and applications of AI and Computer Vision.
|
|
|
-
|
|
|
-<details><summary>Java</summary>
|
|
|
-
|
|
|
-<pre><code class="language-java">import okhttp3.*;
|
|
|
-import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
-import com.fasterxml.jackson.databind.JsonNode;
|
|
|
-import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.util.Base64;
|
|
|
-
|
|
|
-public class Main {
|
|
|
- public static void main(String[] args) throws IOException {
|
|
|
- String API_URL = "http://localhost:8080/ocr"; // Service URL
|
|
|
- String imagePath = "./demo.jpg"; // Local image path
|
|
|
- String outputImagePath = "./out.jpg"; // Output image path
|
|
|
-
|
|
|
- // Encode the local image to Base64
|
|
|
- File file = new File(imagePath);
|
|
|
- byte[] fileContent = java.nio.file.Files.readAllBytes(file.toPath());
|
|
|
- String imageData = Base64.getEncoder().encodeToString(fileContent);
|
|
|
-
|
|
|
- ObjectMapper objectMapper = new ObjectMapper();
|
|
|
- ObjectNode params = objectMapper.createObjectNode();
|
|
|
- params.put("image", imageData); // Base64-encoded file content or image URL
|
|
|
-
|
|
|
- // Create an OkHttpClient instance
|
|
|
- OkHttpClient client = new OkHttpClient();
|
|
|
- MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
|
|
- RequestBody body = RequestBody.create(params.toString(), JSON);
|
|
|
- Request request = new Request.Builder()
|
|
|
- .url(API_URL)
|
|
|
- .post(body)
|
|
|
- .build();
|
|
|
-
|
|
|
- // Call the API and process the response
|
|
|
- try (Response response = client.newCall(request).execute()) {
|
|
|
- if (response.isSuccessful()) {
|
|
|
- String responseBody = response.body().string();
|
|
|
- JsonNode resultNode = objectMapper.readTree(responseBody);
|
|
|
- JsonNode result = resultNode.get("result");
|
|
|
- String base64Image = result.get("image").asText();
|
|
|
- JsonNode texts = result.get("texts");
|
|
|
-
|
|
|
- byte[] imageBytes = Base64.getDecoder().decode(base64Image);
|
|
|
- try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
|
|
|
- fos.write(imageBytes);
|
|
|
- }
|
|
|
- System.out.println("Output image saved at " + outputImagePath);
|
|
|
- System.out.println("\nDetected texts: " + texts.toString());
|
|
|
- } else {
|
|
|
- System.err.println("Request failed with code: " + response.code());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</code></pre></details>
|
|
|
-
|
|
|
-<details><summary>Go</summary>
|
|
|
-
|
|
|
-<pre><code class="language-go">package main
|
|
|
-
|
|
|
-import (
|
|
|
- "bytes"
|
|
|
- "encoding/base64"
|
|
|
- "encoding/json"
|
|
|
- "fmt"
|
|
|
- "io/ioutil"
|
|
|
- "net/http"
|
|
|
-)
|
|
|
-
|
|
|
-func main() {
|
|
|
- API_URL := "http://localhost:8080/ocr"
|
|
|
- imagePath := "./demo.jpg"
|
|
|
- outputImagePath := "./out.jpg"
|
|
|
-
|
|
|
- // Encode the local image to Base64
|
|
|
- imageBytes, err := ioutil.ReadFile(imagePath)
|
|
|
- if err != nil {
|
|
|
- fmt.Println("Error reading image file:", err)
|
|
|
- return
|
|
|
- }
|
|
|
- imageData := base64.StdEncoding.EncodeToString(imageBytes)
|
|
|
-
|
|
|
- payload := map[string]string{"image": imageData} // Base64-encoded file content or image URL
|
|
|
- payloadBytes, err := json.Marshal(payload)
|
|
|
- if err != nil {
|
|
|
- fmt.Println("Error marshaling payload:", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // Call the API
|
|
|
- client := &http.Client{}
|
|
|
- req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
|
|
|
- if err != nil {
|
|
|
- fmt.Println("Error creating request:", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- res, err := client.Do(req)
|
|
|
- if err != nil {
|
|
|
- fmt.Println("Error sending request:", err)
|
|
|
- return
|
|
|
- }
|
|
|
- defer res.Body.Close()
|
|
|
-
|
|
|
- // Process the response
|
|
|
- body, err := ioutil.ReadAll(res.Body)
|
|
|
- if err != nil {
|
|
|
- fmt.Println("Error reading response body:", err)
|
|
|
- return
|
|
|
- }```markdown
|
|
|
-# An English Tutorial on Artificial Intelligence and Computer Vision
|
|
|
-
|
|
|
-This tutorial document is intended for numerous developers and covers content related to artificial intelligence and computer vision.
|
|
|
-
|
|
|
-<details>
|
|
|
-<summary>C#</summary>
|
|
|
-
|
|
|
-```csharp
|
|
|
-using System;
|
|
|
-using System.IO;
|
|
|
-using System.Net.Http;
|
|
|
-using System.Net.Http.Headers;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
-using Newtonsoft.Json.Linq;
|
|
|
-
|
|
|
-class Program
|
|
|
-{
|
|
|
-static readonly string API_URL = "http://localhost:8080/ocr";
|
|
|
-static readonly string imagePath = "./demo.jpg";
|
|
|
-static readonly string outputImagePath = "./out.jpg";
|
|
|
-
|
|
|
-static async Task Main(string[] args)
|
|
|
-{
|
|
|
-var httpClient = new HttpClient();
|
|
|
-
|
|
|
-// Encode the local image to Base64
|
|
|
-byte[] imageBytes = File.ReadAllBytes(imagePath);
|
|
|
-string image_data = Convert.ToBase64String(imageBytes);
|
|
|
-
|
|
|
-var payload = new JObject{ { "image", image_data } }; // Base64 encoded file content or image URL
|
|
|
-var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
|
|
|
-
|
|
|
-// Call the API
|
|
|
-HttpResponseMessage response = await httpClient.PostAsync(API_URL, content);
|
|
|
-response.EnsureSuccessStatusCode();
|
|
|
-
|
|
|
-// Process the API response
|
|
|
-string responseBody = await response.Content.ReadAsStringAsync();
|
|
|
-JObject jsonResponse = JObject.Parse(responseBody);
|
|
|
-
|
|
|
-string base64Image = jsonResponse["result"]["image"].ToString();
|
|
|
-byte[] outputImageBytes = Convert.FromBase64String(base64Image);
|
|
|
-
|
|
|
-File.WriteAllBytes(outputImagePath, outputImageBytes);
|
|
|
-Console.WriteLine($"Output image saved at {outputImagePath}");
|
|
|
-Console.WriteLine("\nDetected texts:");
|
|
|
-Console.WriteLine(jsonResponse["result"]["texts"].ToString());
|
|
|
-}
|
|
|
-}
|
|
|
-</code></pre></details>
|
|
|
-
|
|
|
-<details><summary>Node.js</summary>
|
|
|
-
|
|
|
-<pre><code class="language-js">const axios = require('axios');
|
|
|
-const fs = require('fs');
|
|
|
-
|
|
|
-const API_URL = 'http://localhost:8080/ocr';
|
|
|
-const imagePath = './demo.jpg';
|
|
|
-const outputImagePath = "./out.jpg";
|
|
|
-
|
|
|
-let config = {
|
|
|
- method: 'POST',
|
|
|
- maxBodyLength: Infinity,
|
|
|
- url: API_URL,
|
|
|
- data: JSON.stringify({
|
|
|
- 'image': encodeImageToBase64(imagePath) // Base64 encoded file content or image URL
|
|
|
- })
|
|
|
-};
|
|
|
-
|
|
|
-// Encode the local image to Base64
|
|
|
-function encodeImageToBase64(filePath) {
|
|
|
- const bitmap = fs.readFileSync(filePath);
|
|
|
- return Buffer.from(bitmap).toString('base64');
|
|
|
-}
|
|
|
-
|
|
|
-// Call the API
|
|
|
-axios.request(config)
|
|
|
-.then((response) => {
|
|
|
- // Process the API response
|
|
|
- const result = response.data["result"];
|
|
|
- const imageBuffer = Buffer.from(result["image"], 'base64');
|
|
|
- fs.writeFile(outputImagePath, imageBuffer, (err) => {
|
|
|
- if (err) throw err;
|
|
|
- console.log(`Output image saved at ${outputImagePath}`);
|
|
|
- });
|
|
|
- console.log("\nDetected texts:");
|
|
|
- console.log(result["texts"]);
|
|
|
-})
|
|
|
-.catch((error) => {
|
|
|
- console.log(error);
|
|
|
-});
|
|
|
-</code></pre></details>
|
|
|
-
|
|
|
-<details>
|
|
|
-<summary>PHP</summary>
|
|
|
-
|
|
|
-```php
|
|
|
-<?php
|
|
|
-
|
|
|
-$API_URL = "http://localhost:8080/ocr"; // Service URL
|
|
|
-$image_path = "./demo.jpg";
|
|
|
-$output_image_path = "./out.jpg";
|
|
|
-
|
|
|
-// Encode the local image to Base64
|
|
|
-$image_data = base64_encode(file_get_contents($image_path));
|
|
|
-$payload = array("image" => $image_data); // Base64 encoded file content or image URL
|
|
|
-
|
|
|
-// Call the API
|
|
|
-$ch = curl_init($API_URL);
|
|
|
-curl_setopt($ch, CURLOPT_POST, true);
|
|
|
-curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
|
|
-curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
|
|
-curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
-$response = curl_exec($ch);
|
|
|
-curl_close($ch);
|
|
|
-
|
|
|
-// Process the API response
|
|
|
-$result = json_decode($response, true)["result"];
|
|
|
-file_put_contents($output
|
|
|
-```
|
|
|
-
|
|
|
-<details>
|
|
|
-<details>
|
|
|
+print("\nDetected faces:")
|
|
|
+pprint.pp(result_infer["faces"])
|
|
|
+</code></pre>
|
|
|
+</details>
|
|
|
+</details>
|
|
|
<br/>
|
|
|
|
|
|
📱 <b>Edge Deployment</b>: Edge deployment is a method where computing and data processing functions are placed on the user's device itself, allowing the device to process data directly without relying on remote servers. PaddleX supports deploying models on edge devices such as Android. For detailed edge deployment procedures, please refer to the [PaddleX Edge Deployment Guide](../../../pipeline_deploy/edge_deploy.en.md).
|