Пример #1
0
    def add_new_brush_label_element(label_id: LabelID, slice_index: int,
                                    width: int, height: int, image: bytes,
                                    label_tag: LabelTag) -> LabelElementID:
        """Add new Brush Element for given Label.

        :param label_id: Label's ID
        :param width: width of the Label's image
        :param height: height of the Label's image
        :param image: bytes with image representation of a binary mask
        :param label_tag: Label Tag object
        :return: ID of a Element
        """  # pylint: disable=too-many-arguments
        with db_session() as session:
            brush_label_element = BrushLabelElement(slice_index, width, height,
                                                    label_tag)
            brush_label_element.label_id = label_id
            session.add(brush_label_element)
        BrushLabelElementStorage.create(id=brush_label_element.id, image=image)
        return brush_label_element.id
Пример #2
0
def test_add_brush_label(prepare_environment: Any,
                         synchronous_celery: Any) -> None:
    """Test for adding a Label made with Brush tool."""
    api_client = get_api_client()
    user_token = get_token_for_logged_in_user('admin')

    # Step 1. Add Scan to the system
    payload = {'category': 'KIDNEYS', 'number_of_slices': 3}
    response = api_client.post('/api/v1/scans/',
                               data=json.dumps(payload),
                               headers=get_headers(token=user_token,
                                                   json=True))
    assert response.status_code == 201
    json_response = json.loads(response.data)
    scan_id = json_response['scan_id']

    # Step 2. Label it with Brush
    create_tag_and_assign_to_category('EXAMPLE_TAG', 'Example tag', 'KIDNEYS')
    payload = {
        'elements': [{
            'slice_index': 0,
            'width': 128,
            'height': 128,
            'image_key': 'SLICE_1',
            'tag': 'EXAMPLE_TAG',
            'tool': 'BRUSH',
        }],
        'labeling_time':
        12.34,
    }
    with open('tests/assets/example_labels/binary_mask.png', 'rb') as image:
        data = {
            'label': json.dumps(payload),
            'SLICE_1': (image, 'slice_1'),
        }
        response = api_client.post('/api/v1/scans/{}/label'.format(scan_id),
                                   data=data,
                                   headers=get_headers(token=user_token,
                                                       multipart=True))
    assert response.status_code == 201
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    label_id = json_response['label_id']
    assert isinstance(label_id, str)
    assert len(label_id) >= 1

    # Step 3. Fetch details about above Label and check image storage
    response = api_client.get('/api/v1/labels/' + label_id,
                              headers=get_headers(token=user_token))
    assert response.status_code == 200
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    label_element_id = json_response['elements'][0]['label_element_id']
    brush_label_element = BrushLabelElement.get(id=label_element_id)
    assert brush_label_element.image
Пример #3
0
def get_predefined_brush_label_elements(scan_id: ScanID, task_id: int,
                                        begin: int, count: int) -> Iterable[Tuple[BrushLabelElement, bytes]]:
    """Fetch Predefined Brush Label Elements for given Scan and Task.

    :param scan_id: ID of a given Scan
    :param task_id: ID of a given Task
    :param begin: first Slice index
    :param count: number of Slices for which Label Elements will be returned
    :return: generator for Brush Label Elements and its images
    """
    label_elements = LabelsRepository.get_predefined_brush_label_elements(scan_id, task_id, begin, count)
    for label_element in label_elements:
        storage_brush_label_element = StorageBrushLabelElement.get(id=label_element.id)
        yield label_element, storage_brush_label_element.image
Пример #4
0
def test_add_brush_label(prepare_environment: Any,
                         synchronous_celery: Any) -> None:
    """Test for adding a Label made with Brush tool."""
    api_client = get_api_client()
    user_token = get_token_for_logged_in_user('admin')

    # Step 1. Prepare a structure for the test
    DatasetsRepository.add_new_dataset('KIDNEYS', 'Kidneys')
    task = TasksRepository.add_task('MARK_KIDNEYS', 'Mark Kidneys',
                                    'path/to/image', ['KIDNEYS'], [])
    LabelTagsRepository.add_new_tag('EXAMPLE_TAG', 'Example Tag',
                                    [LabelTool.BRUSH], task.id)

    # Step 2. Add Scan to the system
    payload = {'dataset': 'KIDNEYS', 'number_of_slices': 3}
    response = api_client.post('/api/v1/scans',
                               data=json.dumps(payload),
                               headers=get_headers(token=user_token,
                                                   json=True))
    assert response.status_code == 201
    json_response = json.loads(response.data)
    scan_id = json_response['scan_id']

    # Step 3. Label it with Brush
    payload = {
        'elements': [{
            'slice_index': 0,
            'width': 128,
            'height': 128,
            'image_key': 'SLICE_1',
            'tag': 'EXAMPLE_TAG',
            'tool': LabelTool.BRUSH.value,
        }],
        'labeling_time':
        12.34,
        'task_id':
        TasksRepository.get_task_by_key('MARK_KIDNEYS').id,
    }
    with open('tests/assets/example_labels/binary_mask.png', 'rb') as image:
        data = {
            'label': json.dumps(payload),
            'SLICE_1': (image, 'slice_1'),
        }
        response = api_client.post(
            '/api/v1/scans/{}/MARK_KIDNEYS/label'.format(scan_id),
            data=data,
            headers=get_headers(token=user_token, multipart=True))
    assert response.status_code == 201
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    label_id = json_response['label_id']
    assert isinstance(label_id, str)
    assert len(label_id) >= 1

    # Step 4. Fetch details about above Label and check image storage
    response = api_client.get('/api/v1/labels/' + label_id,
                              headers=get_headers(token=user_token))
    assert response.status_code == 200
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    label_element_id = json_response['elements'][0]['label_element_id']
    brush_label_element = BrushLabelElement.get(id=label_element_id)
    assert brush_label_element.image
Пример #5
0
def delete_brush_element_from_storage(mapper: Mapper, connection: Connection, target: Slice) -> None:
    """Delete BrushLabelElement from storage."""
    brush_label_element = StorageBrushLabelElement.get(id=target.id)
    brush_label_element.delete()
Пример #6
0
def test_delete_scan_with_labels(prepare_environment: Any,
                                 synchronous_celery: Any) -> None:
    """Test deleting scan with at least 1 slice and with labels made with all tools."""
    api_client = get_api_client()
    web_socket_client = get_web_socket_client(namespace='/slices')
    user_token = get_token_for_logged_in_user('admin')

    # Step 1. Prepare a structure for the test
    DatasetsRepository.add_new_dataset('KIDNEYS', 'Kidneys')
    task = TasksRepository.add_task('MARK_KIDNEYS', 'Mark Kidneys',
                                    'path/to/image', ['KIDNEYS'], [])
    LabelTagsRepository.add_new_tag('EXAMPLE_TAG', 'Example Tag', [
        LabelTool.RECTANGLE, LabelTool.CHAIN, LabelTool.POINT, LabelTool.BRUSH
    ], task.id)

    # Step 2. Add Scan to the system
    payload = {'dataset': 'KIDNEYS', 'number_of_slices': 1}
    response = api_client.post('/api/v1/scans',
                               data=json.dumps(payload),
                               headers=get_headers(token=user_token,
                                                   json=True))
    assert response.status_code == 201
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    scan_id: ScanID = json_response['scan_id']
    assert isinstance(scan_id, str)
    assert len(scan_id) >= 1

    # Step 3. Send slices
    with open('tests/assets/example_scan/slice_1.dcm', 'rb') as image:
        response = api_client.post('/api/v1/scans/{}/slices'.format(scan_id),
                                   data={
                                       'image': (image, 'slice_1.dcm'),
                                   },
                                   content_type='multipart/form-data',
                                   headers=get_headers(token=user_token))
        assert response.status_code == 201
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    slice_id: SliceID = json_response['slice_id']
    assert isinstance(slice_id, str)
    assert len(slice_id) >= 1

    # Step 4. Get scan
    response = api_client.get('/api/v1/scans/{}'.format(scan_id),
                              headers=get_headers(token=user_token))
    assert response.status_code == 200
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    assert json_response['scan_id'] == scan_id
    assert json_response['number_of_slices'] == 1
    assert json_response['width'] == 512
    assert json_response['height'] == 512

    # Step 5. Get slices from the server
    payload = {
        'scan_id': scan_id,
        'task_key': 'MARK_KIDNEYS',
        'begin': 0,
        'count': 1
    }
    web_socket_client.emit('request_slices', payload, namespace='/slices')
    responses = web_socket_client.get_received(namespace='/slices')
    assert len(responses) == 1
    response = responses[0]
    assert response['name'] == 'slice'
    assert response['args'][0]['scan_id'] == scan_id
    assert response['args'][0]['index'] == 0
    assert isinstance(response['args'][0]['image'], bytes)

    # Step 6. Label it with all available tools
    payload = {
        'elements': [{
            'x': 0.5,
            'y': 0.5,
            'slice_index': 0,
            'width': 0.1,
            'height': 0.1,
            'tag': 'EXAMPLE_TAG',
            'tool': LabelTool.RECTANGLE.value,
        }, {
            'slice_index': 0,
            'width': 128,
            'height': 128,
            'image_key': 'SLICE_1',
            'tag': 'EXAMPLE_TAG',
            'tool': LabelTool.BRUSH.value,
        }, {
            'slice_index': 0,
            'x': 0.25,
            'y': 0.5,
            'tag': 'EXAMPLE_TAG',
            'tool': LabelTool.POINT.value,
        }, {
            'slice_index':
            0,
            'points': [
                {
                    'x': 0.2,
                    'y': 0.3,
                },
                {
                    'x': 0.5,
                    'y': 0.8,
                },
            ],
            'tag':
            'EXAMPLE_TAG',
            'tool':
            LabelTool.CHAIN.value,
            'loop':
            False,
        }],
        'labeling_time':
        12.34,
    }
    with open('tests/assets/example_labels/binary_mask.png', 'rb') as image:
        data = {
            'label': json.dumps(payload),
            'SLICE_1': (image, 'slice_1'),
        }
        response = api_client.post(
            '/api/v1/scans/{}/MARK_KIDNEYS/label'.format(scan_id),
            data=data,
            headers=get_headers(token=user_token, multipart=True))
    assert response.status_code == 201
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    label_id = json_response['label_id']
    assert isinstance(label_id, str)
    assert len(label_id) >= 1

    # Step 7. Fetch details about above Label and check image storage
    response = api_client.get('/api/v1/labels/' + label_id,
                              headers=get_headers(token=user_token))
    assert response.status_code == 200
    json_response = json.loads(response.data)
    assert isinstance(json_response, dict)
    label_element_id = json_response['elements'][1]['label_element_id']
    brush_label_element = BrushLabelElement.get(id=label_element_id)
    assert brush_label_element.image

    # Step 7. Delete scan from the system
    ScansRepository.delete_scan_by_id(scan_id)

    # Step 8. Check that scan has been deleted
    response = api_client.get('/api/v1/scans/{}'.format(scan_id),
                              headers=get_headers(token=user_token))
    assert response.status_code == 404

    # Step 9. Check that slices has been deleted
    with pytest.raises(NoResultFound):
        SliceRepository.get_slice_by_id(slice_id)

    # Step 10. Check that slices original image has been deleted from storage
    with pytest.raises(DoesNotExist):
        OriginalSlice.get(id=slice_id)

    # Step 11. Check that slices processed image has been deleted from storage
    with pytest.raises(DoesNotExist):
        ProcessedSlice.get(id=slice_id)

    # Step 12. Check that labels has been deleted
    response = api_client.get('/api/v1/labels/{}'.format(label_id),
                              headers=get_headers(token=user_token))
    assert response.status_code == 404

    # Step 13. Check that Brush Label was deleted from storage
    with pytest.raises(DoesNotExist):
        BrushLabelElement.get(id=label_element_id)