Image annotation conversion from json format to YOLOv7 format - object-detection

I am trying object detection in YOLOv7. As I have downloaded some public dataset for training, I got annotations in JSON format.
{
"width": 4608,
"height": 3456,
"ispano": false,
"objects": [
{
"key": "o5a4uvvzxdp6dod5uiexhl",
"label": "regulatory--stop--g1",
"bbox": {
"xmin": 2496.375,
"ymin": 2449.40625,
"xmax": 2557.125,
"ymax": 2548.125
},
"properties": {
"barrier": false,
"occluded": false,
"out-of-frame": false,
"exterior": false,
"ambiguous": false,
"included": false,
"direction-or-information": false,
"highway": false,
"dummy": false
}
},
{
"key": "0f05h7prxavgpvxre68ml0",
"label": "warning--wild-animals--g4",
"bbox": {
"xmin": 1957.5,
"ymin": 2652.75,
"xmax": 1978.875,
"ymax": 2674.6875
},
"properties": {
"barrier": false,
"occluded": false,
"out-of-frame": false,
"exterior": false,
"ambiguous": false,
"included": false,
"direction-or-information": false,
"highway": false,
"dummy": false
}
},
{
"key": "bd43wshq6ayz0jowsxgp23",
"label": "other-sign",
"bbox": {
"xmin": 3211.875,
"ymin": 2170.96875,
"xmax": 3704.625,
"ymax": 2261.25
},
"properties": {
"barrier": false,
"occluded": false,
"out-of-frame": false,
"exterior": false,
"ambiguous": false,
"included": false,
"direction-or-information": true,
"highway": false,
"dummy": false
}
},
{
"key": "qzoqx6j766ovaw4x7zd6wi",
"label": "regulatory--reversible-lanes--g2",
"bbox": {
"xmin": 2250.0,
"ymin": 2481.46875,
"xmax": 2311.875,
"ymax": 2570.90625
},
"properties": {
"barrier": false,
"occluded": false,
"out-of-frame": false,
"exterior": false,
"ambiguous": false,
"included": false,
"direction-or-information": false,
"highway": false,
"dummy": false
}
},
{
"key": "q0g8osx48bubijrosgfpda",
"label": "warning--junction-with-a-side-road-perpendicular-left--g3",
"bbox": {
"xmin": 1990.125,
"ymin": 2609.71875,
"xmax": 2032.875,
"ymax": 2651.90625
},
"properties": {
"barrier": false,
"occluded": false,
"out-of-frame": false,
"exterior": false,
"ambiguous": false,
"included": false,
"direction-or-information": false,
"highway": false,
"dummy": false
}
},
{
"key": "do3wb1gql83q76xg9zmnkr",
"label": "other-sign",
"bbox": {
"xmin": 1929.375,
"ymin": 2662.03125,
"xmax": 1944.0,
"ymax": 2678.0625
},
"properties": {
"barrier": false,
"occluded": false,
"out-of-frame": false,
"exterior": false,
"ambiguous": true,
"included": false,
"direction-or-information": false,
"highway": false,
"dummy": false
}
}
]
}
I need the annotations in YOLOv7 PyTorch version. I tried the conversion in roboflow, but as I uploaded the the files with the annotations, it was saying none of the images are annotated. Is there a way I can convert these annotations to YOLOv7 PyTorch version?

I developed a library in order to convert from LabelMe to Yolov7 format you can download it here:
https://github.com/Tlaloc-Es/labelme2yolov7segmentation
And you can see how I do the conversion in order to that you can develop your version.

import json
# Load the JSON file
with open('lables.json', 'r') as f:
data = json.load(f)
# Extract the necessary information from the JSON file
images = data['images']
annotations = data['annotations']
categories = {c['id']: c['name'] for c in data['categories']}
# Iterate through the images
for image in images:
# Get the file name for the image
file_name = image['file_name']
# Create an empty list of bounding boxes for category 1
bounding_boxes = []
# Iterate through the annotations
for annotation in annotations:
# If the annotation's image ID matches the current image's ID
if annotation['image_id'] == image['id']:
# Get the category ID for the annotation
category_id = annotation['category_id']
# If the category ID is 1
if category_id == 1:
# Get the bounding box coordinates
x, y, w, h = annotation['bbox']
# Convert the bounding box coordinates to normalized xywh
x = x / image['width']
y = y / image['height']
w = w / image['width']
h = h / image['height']
# Create a string with the class ID, center x, center y, width, and height values, separated by spaces
bounding_box_str = f"{category_id} {x + w/2} {y + h/2} {w} {h}"
# Add the string to the list of bounding boxes
bounding_boxes.append(bounding_box_str)
# Create a new text file with the same name as the image file, but with a .txt extension
with open(f"{file_name}.txt", 'w') as f:
# Write the bounding boxes to the text file
for bounding_box in bounding_boxes:
f.write(f"{bounding_box}\n")
1)This script only convert boundary box annotations of .json ot yolov7 pytorch format
2) in (if category_id == 1) "1" is for person class only you can change
according to your requirement

Related

jsonb_set not working as expected with nested collections, resulting in null value returned

I am trying to update a nested collection in my Postgres table using json_set, however, my approach is resulting in a collection of null values.
id
payload
row_version
fbfd3b9d-bb20-4c1b-985f-0979890472ec
{ "slots": [ { "bannerXCreatorSettings": { "additionalFields": [ { "label": "test-label", "enabled": true, "mandatory": false, "additionalFieldId": "label", "maxCharacterLimit": 22, "additionalFieldType": "TEXT", "colorHexOptionsList": [] }, { "label": "test-label-2", "enabled": true, "mandatory": false, "additionalFieldId": "label2", "maxCharacterLimit": 55, "additionalFieldType": "TEXT", "colorHexOptionsList": [] } ] } } ]}
1
I have the following json payload stored in my table:
{
"slots": [
{
"bannerXCreatorSettings": {
"additionalFields": [
{
"label": "test-label",
"enabled": true,
"mandatory": false,
"additionalFieldId": "label",
"maxCharacterLimit": 22,
"additionalFieldType": "TEXT",
"colorHexOptionsList": []
},
{
"label": "test-label-2",
"enabled": true,
"mandatory": false,
"additionalFieldId": "label2",
"maxCharacterLimit": 55,
"additionalFieldType": "TEXT",
"colorHexOptionsList": []
}
]
}
}
]
}
Within the additionalFields collections, I want to add selectOptions. Like this:
{
"slots": [
{
"bannerXCreatorSettings": {
"additionalFields": [
{
"label": "test-label",
"enabled": true,
"mandatory": false,
"additionalFieldId": "label",
"maxCharacterLimit": 22,
"additionalFieldType": "TEXT",
"colorHexOptionsList": [],
"selectOptions": [] <-- new field
},
{
"label": "test-label-2",
"enabled": true,
"mandatory": false,
"additionalFieldId": "label2",
"maxCharacterLimit": 55,
"additionalFieldType": "TEXT",
"colorHexOptionsList": [],
"selectOptions": [] <-- new field
}
]
}
}
]
}
I have written the following SQL to try update the JSON payload within my table:
select
id,
payload,
row_version,
jsonb_set(
payload,
'{slots}',
(select
jsonb_agg(
jsonb_set(
slot_elem,
'{bannerXCreatorSettings}',
jsonb_set(
slot_elem -> 'bannerXCreatorSettings',
'{additionalFields}',
(
select
jsonb_agg(
jsonb_set(
field_element,
'{selectOptions}',
jsonb_build_array()))
from jsonb_array_elements(
slot_elem -> '{bannerXCreatorSettings}' #>'{additionalFields}') WITH ORDINALITY a_t(field_element, idx_1))
)
)
)
FROM
jsonb_array_elements(
payload #> '{slots}') WITH ORDINALITY t(slot_elem, idx))) as payload_update
My understanding of SQL is limited, however, I feel as though this should work. Unfortunally the above query results in the following:
{
"slots": [
null,
null
]
}

Parsing Dynamic response in Karate

I want to verify the value of "RequestedName" in the following response, where the keys for different drugs is dynamic:
{
"requestId": "c826bee1-610e-4dee-b998-1fe4f8c15a1b",
"requestSource": "",
"responseSource": "client",
"status": 200,
"responseCodes": [
{
"code": "S00001",
"message": "Success.",
"params": {
"entity": ""
}
}
],
"context": null,
"payload": {
"0113ccf86ba79b698b8e7a8fb9effc4b": {
"RequestedName": "paracetamol",
"SearchKey": "0113ccf86ba79b698b8e7a8fb9effc4b",
"Name": "Genexa Acetaminophen Extra Strength",
"PrescribableName": "",
"ProductCodes": [
"69676-0059"
],
"DosageForm": "Tablet, coated",
"Route": "Oral",
"Approved": false,
"UnApproved": false,
"Generic": false,
"Allergen": false,
"Vaccine": false,
"Strength": {
"Number": "500",
"Unit": "mg/1"
},
"Purposes": {},
"SideEffects": {}
},
"0349fa4ea29da419c46745bc7e2a6c07": {
"RequestedName": "paracetamol",
"SearchKey": "0349fa4ea29da419c46745bc7e2a6c07",
"Name": "Pain Reliever",
"PrescribableName": "",
"ProductCodes": [
"70677-0168"
],
"DosageForm": "Tablet, extended release",
"Route": "Oral",
"Approved": true,
"UnApproved": false,
"Generic": true,
"Allergen": false,
"Vaccine": false,
"Strength": {
"Number": "650",
"Unit": "mg/1"
},
"Purposes": {},
"SideEffects": {}
},
"060cfbde5d82d947c56aac304c136fd3": {
"RequestedName": "paracetamol",
"SearchKey": "060cfbde5d82d947c56aac304c136fd3",
"Name": "Betr Pain Relief",
"PrescribableName": "Acetaminophen 500 mg Oral Tablet",
"ProductCodes": [
"80267-0484"
],
"DosageForm": "Tablet",
"Route": "Oral",
"Approved": false,
"UnApproved": false,
"Generic": false,
"Allergen": false,
"Vaccine": false,
"Strength": {
"Number": "500",
"Unit": "mg/1"
},
"Purposes": {},
"SideEffects": {}
},
"0950fcbac262c1c1d3a9e6630615a5f9": {
"RequestedName": "paracetamol",
"SearchKey": "0950fcbac262c1c1d3a9e6630615a5f9",
"Name": "Acetaminophen",
I tired this:
* def list = []
* def fun = function(k, v){ karate.appendTo('list', { key: k, val: v } )}
* karate.forEach(response, fun)
* def keys = $list[?(#.val.payload.RequestedName==drugName)].key
but not working, getting error as below:
def keys = $list[?(#.val.payload.RequestedName==drugName)].key
Failed to parse filter: [?(#.val.payload.RequestedName==drugName)], error on position: 32, char: d
testsuite/GetDrugs.feature:20
Here is the approach you can use:
* def response =
"""
{
dynamicKey1: {
fixedKey: 'fixedValue1',
dataKey: 'dataValue2'
},
dynamicKey2: {
fixedKey: 'fixedValue2',
dataKey: 'dataValue2'
}
}
"""
* def keys = []
* def fun = function(k, v){ if (v.fixedKey == 'fixedValue2') keys.push(k) }
* karate.forEach(response, fun)
* match keys == ['dynamicKey2']

azure search exact match of file name not returning exact results

I am indexing all the file names into the index. But when I search with exact file name in the search query it is returning all other file names also. below is my index definition.
{
"fields": [
{
"name": "id",
"type": "Edm.String",
"facetable": true,
"filterable": true,
"key": true,
"retrievable": true,
"searchable": false,
"sortable": false,
"analyzer": null,
"indexAnalyzer": null,
"searchAnalyzer": null,
"synonymMaps": [],
"fields": []
},
{
"name": "FileName",
"type": "Edm.String",
"facetable": false,
"filterable": false,
"key": false,
"retrievable": true,
"searchable": true,
"sortable": false,
"analyzer": "keyword-analyzer",
"indexAnalyzer": null,
"searchAnalyzer": null,
"synonymMaps": [],
"fields": []
}
],
"scoringProfiles": [],
"defaultScoringProfile": null,
"corsOptions": null,
"analyzers": [
{
"name": "keyword-analyzer",
"#odata.type": "#Microsoft.Azure.Search.CustomAnalyzer",
"charFilters": [],
"tokenizer": "keyword_v2",
"tokenFilters": ["lowercase", "my_asciifolding", "my_word_delimiter"]
}
],
"tokenFilters": [
{
"#odata.type": "#Microsoft.Azure.Search.AsciiFoldingTokenFilter",
"name": "my_asciifolding",
"preserveOriginal": true
},
{
"#odata.type": "#Microsoft.Azure.Search.WordDelimiterTokenFilter",
"name": "my_word_delimiter",
"generateWordParts": true,
"generateNumberParts": false,
"catenateWords": false,
"catenateNumbers": false,
"catenateAll": false,
"splitOnCaseChange": true,
"preserveOriginal": true,
"splitOnNumerics": true,
"stemEnglishPossessive": false,
"protectedWords": []
}
],
"#odata.etag": "\"0x8D6FB2F498F9AD2\""
}
Below is my sample data
{
"value": [
{
"id": "1",
"FileName": "SamplePSDFile_1psd2680.psd"
},
{
"id": "2",
"FileName": "SamplePSDFile-1psd260.psd"
},
{
"id": "3",
"FileName": "SamplePSDFile_1psd2689.psd"
},
{
"id": "4",
"FileName": "SamplePSDFile-1psdxx2680.psd"
}
]
}
Below is the Analyze API results
{
"tokens": [
{
"token": "samplepsdfile_1psd2689.psd",
"startOffset": 0,
"endOffset": 26,
"position": 0
},
{
"token": "samplepsdfile",
"startOffset": 0,
"endOffset": 13,
"position": 0
},
{
"token": "psd",
"startOffset": 15,
"endOffset": 18,
"position": 1
},
{
"token": "psd",
"startOffset": 23,
"endOffset": 26,
"position": 2
}
]
}
When I search with the keyword "SamplePSDFile_1psd2689.psd", Azure search returning three records in the results instead of only document 3. Below is my search query and the results.
?search="SamplePSDFile_1psd2689.psd"&api-version=2019-05-06&$count=true&queryType=full&searchMode=All
{
"#odata.count": 3,
"value": [
{
"#search.score": 2.3387241,
"id": "2",
"FileName": "SamplePSDFile-1psd260.psd"
},
{
"#search.score": 2.2493405,
"id": "3",
"FileName": "SamplePSDFile_1psd2689.psd"
},
{
"#search.score": 2.2493405,
"id": "1",
"FileName": "SamplePSDFile_1psd2680.psd"
}
]
}
How I can achieve my expected results. I tried with and without double quotes around the keyword all other options, but no luck. What I am doing wrong here in this case?
Some body suggested to use $filter, but that field wasn't filterable in our case.
Please help me on this.
If you are looking for exact match then you probably don't want any analyzer involved. Give it a try with this line
"analyzer": "keyword-analyzer"
changed to
"analyzer": null
If you need to be able to do exact match on the field and also support partial keyword searches then you need to index the field twice with different names. Maybe append “Exact” to the exact match field name and don’t use an analyzer for that one. The name without exact can have an analyzer. Then search on the field using the right field name index depending on the type of search.

Karate - How to extract from Json Response and use as data driven data in Outline Scenario

Using the below response, I want to extract the ID fields where created_by.$oid is equal to '5bf6d22a60664323c10676cf' and use the extracted Ids as data driven data for Outline Scenarios. Which is the most effective way to do so?
[
{
"deleted": false,
"processing": false,
"id": "5ffff5b36bdfca2cb8f11135",
"created_by": {
"$oid": "3bf6d24a60664343c10676cf"
}
},
{
"deleted": false,
"processing": false,
"id": "600070616bdfca4f2045824f",
"created_by": {
"$oid": "5bf6d22a60664323c10676cf"
}
},
{
"deleted": false,
"processing": false,
"id": "6001907f38d61400080376f4",
"created_by": {
"$oid": "5bf6d22a60664323c10676cf"
}
}
]
Here you go, and please refer to the docs for how this works: https://github.com/intuit/karate#jsonpath-filters
* def fun = function(x){ return x.created_by['$oid'] == '5bf6d22a60664323c10676cf' }
* def filtered = karate.filter(response, fun)
* def ids = $filtered[*].id
* print ids

Sort icon not changing in Datatable server side processing

When I use server side processing in datatable the sorting works but the sort icon does not change and stays in same direction. Below is the code snippet of my datatable configuration.
$('#dtSearchResult').DataTable({
"filter": false,
"pagingType": "simple_numbers",
"orderClasses": false,
"order": [[0, "asc"]],
"info": true,
"scrollY": "450px",
"scrollCollapse": true,
"bLengthChange": false,
"searching": true,
"bStateSave": false,
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": VMCreateExtraction.AppSecurity.websiteNode() + "/api/Collection/SearchCustIndividual",
"fnServerData": function (sSource, aoData, fnCallback) {
aoData.push({ "name": "ccUid", "value": ccUid });
//Below i am getting the echo that i will be sending to Server side
var echo = null;
for (var i = 0; i < aoData.length; i++) {
switch (aoData[i].name) {
case 'sEcho':
echo = aoData[i].value;
break;
default:
break;
}
}
$.ajax({
"dataType": 'json',
"contentType": "application/json; charset=utf-8",
"type": "GET",
"url": sSource,
"data": aoData,
success: function (msg, a, b) {
$.unblockUI();
var mappedCusNames = $.map(msg.Table, function (Item) {
return new searchGridListObj(Item);
});
var data = {
"draw": echo,
"recordsTotal": msg.Table2[0].TOTAL_NUMBER_OF_RECORDS,
"recordsFiltered": msg.Table1[0].FILTERED_RECORDS,
"data": mappedCusNames
};
fnCallback(data);
$("#dtSearchResult").show();
ko.cleanNode($('#dtSearchResult')[0]);
ko.applyBindings(VMCreateExtraction, $('#dtSearchResult')[0]);
}
})
},
"aoColumns": [{
"mDataProp": "C_UID"
}, {
"mDataProp": "C_LAST_NAME"
}, {
"mDataProp": "C_FIRST_NAME"
}, {
"mDataProp": "C_USER_ID"
}, {
"mDataProp": "C_EMAIL"
}, {
"mDataProp": "C_COMPANY"
}],
"aoColumnDefs": [{ "defaultContent": "", "targets": "_all" },
//I create a link in 1 st column
]
});
There is some configuration that I am missing here. I read on datatable forums and the only issue highlighted by people was that draw should be same as what we send on server side.
For anyone looking for an answer to this. Sad but i had to write my own function as below:
function sortIconHandler(thArray, sortCol, sortDir) {
for (i = 0; i < thArray.length; i++) {
if (thArray[i].classList.contains('sorting_asc')) {
thArray[i].classList.remove('sorting_asc');
thArray[i].classList.add("sorting");
}
else if (thArray[i].classList.contains('sorting_desc')) {
thArray[i].classList.remove('sorting_desc');
thArray[i].classList.add("sorting");
}
if (i == sortCol) {
if (sortDir == 'asc') {
thArray[i].classList.remove('sorting');
thArray[i].classList.add("sorting_asc");
}
else {
thArray[i].classList.remove('sorting');
thArray[i].classList.add("sorting_desc");
}
}
}
}
tharrray-> The array of all row headers(You can just write a jquery selector for this).
sortCol->Column on which sort is clicked (Datatable param iSortCol_0)
sortDir -> Sorting direction (Datatable param sSortDir_0)
I know this is an old thread, but make sure you don't have an .off() somewhere associated with the tables capture group in jQuery. I had a click event that (for some reason) I attached an off function to.. Took me 3 days to find it.