Przesyłanie obrazów
Oto przykład tworzenia nowego zbioru danych i przesyłania do niego obrazów z kategoriami i adnotacjami.
Tworzenie zbioru danych
Python
def create_dataset(dataset_name):
request = {
"name": dataset_name
}
response = requests.post(url=f'{OSAI_URL}/Datasets', headers=HEADERS, json=request).json()
dataset_id = response["id"]
return dataset_id
Tworzenie kategorii
Podczas korzystania z interfejsu API do przesyłania obrazów z kategorii należy wcześniej utworzyć potrzebne kategorie, aby podczas przesyłania obrazów podać prawidłowy identyfikator kategorii używanych w zestawie danych.
Python
def create_category(dataset_id, category_name):
request = {
"datasetId": dataset_id,
"name": category_name
}
response = requests.post(
f'{OSAI_URL}/Categories', headers=HEADERS, json=request
).json()
return respone
Przesyłanie
Rozpoczęcie i zakończenie przesyłania
Przesyłanie należy rozpocząć ręcznie. Zbiór danych zostanie wówczas zablokowany i będzie można przesyłać zdjęcia. Po zakończeniu przesyłania zdjęć należy zatrzymać przesyłanie, aby odblokować zbiór danych. Jeśli zapomnisz tego zrobić, zbiór danych odblokuje się automatycznie po pewnym czasie bez otrzymywania nowych zdjęć.
Python
def start_uploading(dataset_id):
response = requests.post(
f'{OSAI_URL}/Datasets/{dataset_id}/StartUploading', headers=HEADERS
).json()
return response
def finish_uploading(dataset_id, upload_id):
response = requests.post(
f'{OSAI_URL}/Datasets/{dataset_id}/FinishUploading', headers=HEADERS, params={"datasetUploadId": upload_id}
)
print(response)
Wysyłanie obrazów
Python
def send_images(dataset_id, upload_id, path):
images_data = get_images_data(path)
categories_id = create_categories_for_images_data(images_data, dataset_id)
for image in images_data:
response = upload_image(dataset_id, categories_id, upload_id, image)
print(response)
Zdjęcia są wysyłane jako multipart/form-data, które muszą zawierać:
- DatasetID
- DatasetUploadID
- ImagesMetadata - zawierające dane takie jak:
- name
- annotationType
- annotation
- classifyCategoryId
- ImagesFles
Python
def upload_image(dataset_id, categories_id, upload_id, image):
annotation = get_annotation(image)
encoded_content = base64.b64encode(bytes(annotation['content'], 'utf-8'))
file_name = image['name'] + image['extension']
file_path= image['path'] + os.sep + file_name
form_data = {
'datasetId': dataset_id,
'datasetUploadId': upload_id,
'imagesMetadata[0][name]': file_name,
'imagesMetadata[0][annotationType]': annotation['type'],
'imagesMetadata[0][annotation]': encoded_content,
'imagesMetadata[0][classifyCategoryId]': categories_id[image['category']],
}
files = {'imagesFiles': (file_name, open(file_path, 'rb'))}
response = requests.post(
f'{OSAI_URL}/Images/UploadChunk',headers=HEADERS,
params={'skipUnsupportedImages': False}, data=form_data, files=files
)
return response
Pobieranie metadanych obrazu
Aby ułatwić zarządzanie przesłanymi obrazami, można podzielić informacje o zdjęciu, przesyłając do niego klasyfikacje i adnotacje.
Python
def get_images_data(path):
image_list =[]
for root, _dirs, files in os.walk(path):
for file in files:
suffix = pathlib.Path(file).suffix
name = pathlib.Path(file).stem
if suffix == '.jpg' or suffix == '.png':
annotation = None
if os.path.isfile(root + os.sep + name + '.xml'):
annotation = '.xml'
image_list.append({'path': root, 'name': name, 'extension': suffix, 'category': os.path.basename(root), 'annotation_file':annotation})
return image_list
Dodawanie kategorii do przesyłania
W tym przykładzie używamy folderu nadrzędnego do przypisania klasyfikacji.
Python
def create_categories_for_images_data(images_data, dataset_id):
categories = []
categories_ids = {}
for image in images_data:
if image['category'] not in categories:
categories.append(image['category'])
for category in categories:
categories_ids[category] = create_category(dataset_id, category)['id']
return categories_ids
Dodawanie adnotacji .xml do przesyłanych plików
Pliki .xml wymagają, aby metadane obrazów zawierały prawidłowy typ adnotacji, aby serwer wiedział, jak zdekodować posiadane informacje. Plik .xml powinien zostać przesłany jako zakodowany ciąg znaków w base64.
Python
def get_annotation(image_data):
annotation = {}
if image_data['annotation_file'] == '.xml':
file_path = image_data['path']+ os.sep + image_data['name'] + image_data['annotation_file']
annotation['type']=0
with open(file_path) as file:
annotation['content'] = file.read()
else:
annotation['type']=None
annotation['content'] = ''
return annotation
Przykład
Python
import requests
import os
import pathlib
import base64
OSAI_URL = 'https://app-eu.onestepai.com/api'
API_TOKEN = 'OUR ACCESS TOKEN GENERATED IN OSAI'
HEADERS = {'Authorization': None}
def main():
token = sign_in()
global HEADERS
HEADERS = {'Authorization': f'Bearer {token.text}'}
print('------Create dataset------')
dataset_id = create_dataset('holy_hand_grenade')
print('-----Uploading------')
upload_id = start_uploading(dataset_id)
send_images(dataset_id, upload_id, "zdj")
finish_uploading(dataset_id, upload_id)
def sign_in():
response = requests.post(
url=f'{OSAI_URL}/Users/SignIn', json=API_TOKEN)
return response
def create_dataset(dataset_name):
request = {
'name': dataset_name
}
response = requests.post(url=f'{OSAI_URL}/Datasets', headers=HEADERS, json = request).json()
dataset_id = response['id']
print(f'Dataset created with id: {dataset_id}')
return dataset_id
def create_category(dataset_id, category_name):
request = {
'datasetId': dataset_id,
'name': category_name
}
response = requests.post(
f'{OSAI_URL}/Categories', headers=HEADERS, json=request
).json()
return response
def send_images(dataset_id, upload_id, path):
images_data = get_images_data(path)
categories_id = create_categories_for_images_data(images_data, dataset_id)
for image in images_data:
response = upload_image(dataset_id, categories_id, upload_id, image)
print(response)
def start_uploading(dataset_id):
response = requests.post(
f'{OSAI_URL}/Datasets/{dataset_id}/StartUploading', headers=HEADERS
).json()
return response
def finish_uploading(dataset_id, upload_id):
response = requests.post(
f'{OSAI_URL}/Datasets/{dataset_id}/FinishUploading', headers=HEADERS, params={'datasetUploadId': upload_id}
)
print(response)
def upload_image(dataset_id, categories_id, upload_id, image):
annotation = get_annotation(image)
encoded_content = base64.b64encode(bytes(annotation['content'], 'utf-8'))
file_name = image['name'] + image['extension']
file_path= image['path'] + os.sep + file_name
form_data = {
'datasetId': dataset_id,
'datasetUploadId': upload_id,
'imagesMetadata[0][name]': file_name,
'imagesMetadata[0][annotationType]': annotation['type'],
'imagesMetadata[0][annotation]': encoded_content,
'imagesMetadata[0][classifyCategoryId]': categories_id[image['category']],
}
files = {'imagesFiles': (file_name, open(file_path, 'rb'))}
response = requests.post(
f'{OSAI_URL}/Images/UploadChunk',headers=HEADERS,
params={'skipUnsupportedImages': False}, data=form_data, files=files
)
return response
def get_annotation(image_data):
annotation = {}
if image_data['annotation_file'] == '.xml':
file_path = image_data['path']+ os.sep + image_data['name'] + image_data['annotation_file']
annotation['type']=0
with open(file_path) as file:
annotation['content'] = file.read()
else:
annotation['type']=None
annotation['content'] = ''
return annotation
def create_categories_for_images_data(images_data, dataset_id):
categories = []
categories_ids = {}
for image in images_data:
if image['category'] not in categories:
categories.append(image['category'])
for category in categories:
categories_ids[category] = create_category(dataset_id, category)['id']
return categories_ids
def get_images_data(path):
image_list =[]
for root, _dirs, files in os.walk(path):
for file in files:
suffix = pathlib.Path(file).suffix
name = pathlib.Path(file).stem
if suffix == '.jpg' or suffix == '.png':
annotation = None
if os.path.isfile(root + os.sep + name + '.xml'):
annotation = '.xml'
image_list.append({'path': root, 'name': name, 'extension': suffix, 'category': os.path.basename(root), 'annotation_file': annotation})
return image_list
if __name__ == '__main__':
main()
Example output
------Create dataset------
Dataset created with id: 514
-----Uploading------
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>