diff --git a/README.md b/README.md index 6c3b0ab..68d9aa8 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ RectVision is a No code / Low code AI platform that helps users to build end to end computer vision/ NLP projects, from data to production. ## Installation -Rectvision supports an installation of Python 3.6 and above. It is available on Windows, MacOS and Linux Systems. +Rectvision supports an installation of Python 3.9 and above. It is available on Windows, MacOS and Linux Systems. ### pip (Recommended) -To install the current `rectvision` you'll need at least Python 3.6.1. If you have an older version of Python, you will not be able to use `rectvision`. +To install the current `rectvision` you'll need at least Python 3.9.0. If you have an older version of Python, you will not be able to use `rectvision`. ```shell $ pip install --upgrade rectvision diff --git a/setup.cfg b/setup.cfg index 9acd57b..23f5c49 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = rectvision -version = 3.0.19 +version = 3.0.22 author = Rectlabs author_email = rectanglenet@gmail.com description = Rectvision package diff --git a/src/rectvision/data/converters/labelmeToXml.py b/src/rectvision/data/converters/labelmeToXml.py index 5a6109b..24ff555 100644 --- a/src/rectvision/data/converters/labelmeToXml.py +++ b/src/rectvision/data/converters/labelmeToXml.py @@ -65,11 +65,8 @@ def valid_path(self, path): return path def json_to_xml(self): - self.get_xml_template() print('Starting conversion...') - tree = ET.parse('template.xml') - root = tree.getroot() - #checkk validity of output text dir and create one if it doesn't exist + #check validity of output text dir and create one if it doesn't exist self.out_xml_dir = self.valid_path(self.out_xml_dir) #iterate over all json files in self.ann_dir and extract required info from each for ann_path in glob.glob(os.path.join(self.ann_dir, '*.json')): @@ -80,30 +77,40 @@ def json_to_xml(self): #get output xml file out_xml_path = os.path.splitext(os.path.join(self.out_xml_dir, self.current_img_path))[0] + '.xml' - #modify xml template - folder = root.find('folder') + #create xml enteries + root = ET.Element('annotation') + #append folder + folder = ET.SubElement(root, 'folder') folder.text = self.ann_dir + ET.indent(folder, space='\t', level=1) - fname = root.find('filename') + fname = ET.SubElement(root, 'filename') fname.text = self.current_img_path + ET.indent(fname, space='\t', level=1) - src = root.find('source') - database = src.find('database') + src = ET.SubElement(root, 'source') + database = ET.SubElement(src, 'database') database.text = self.database + ET.indent(src, space='\t', level=1) - size = root.find('size') - width = size.find('width') + size = ET.SubElement(root, 'size') + width = ET.SubElement(size, 'width') width.text = str(self.current_img_width) - height = size.find('height') + height = ET.SubElement(size, 'height') height.text = str(self.current_img_height) - depth = size.find('depth') + depth = ET.SubElement(size, 'depth') depth.text = str(self.current_img_depth) + ET.indent(size, space='\t', level=1) + + segmented = ET.SubElement(root, 'segmented') + segmented.text = str(0) + ET.indent(segmented, space='\t', level=1) #write objects as specific annotations for ppt in self.ppts: #append new object obj = ET.SubElement(root, 'object') - + name = ET.SubElement(obj, 'name') name.text = str(ppt[0]) @@ -121,10 +128,17 @@ def json_to_xml(self): ymax = ET.SubElement(bndbox, 'ymax') ymax.text = str(int(ppt[4])) + ET.indent(obj, space='\t', level=1) + ET.indent(root, space='\t', level=0) + #convert xml to byte object + b_xml = ET.tostring(root) #save annotation to out_xml_path - tree.write(out_xml_path) + with open(out_xml_path, 'wb') as f: + f.write(b_xml) print('All done!') + + diff --git a/src/rectvision/data/converters/labelmetococo.py b/src/rectvision/data/converters/labelmetococo.py index 8371eab..aff3a45 100644 --- a/src/rectvision/data/converters/labelmetococo.py +++ b/src/rectvision/data/converters/labelmetococo.py @@ -110,11 +110,11 @@ def annotation(self, points, label, num): # area = 0.5 * np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))) # annotation["segmentation"] = [[list(np.asarray(points).flatten())]] annotation["iscrowd"] = 0 - # annotation["area"] = area annotation["image_id"] = num [[xmin, ymin], [xmax, ymax]] = points o_width = xmax - xmin o_height = ymax - ymin + annotation["area"] = o_width * o_height annotation["bbox"] = [xmin, ymin, o_width, o_height] annotation["category_id"] = label # self.getcatid(label) diff --git a/src/rectvision/data/converters/rectvisConverterHelper.py b/src/rectvision/data/converters/rectvisConverterHelper.py index 741c91a..35d5813 100644 --- a/src/rectvision/data/converters/rectvisConverterHelper.py +++ b/src/rectvision/data/converters/rectvisConverterHelper.py @@ -483,15 +483,12 @@ def get_xml_template(self): open('template.xml', 'wb').write(response.content) def rectjson_to_xml(self): - #get template - self.get_xml_template() print('Starting conversion...') #get all image info self.extract_info_from_json() #split to train, test, validation self.ppts_train, self.ppts_test, self.ppts_valid = self.split(self.ppts, self.train_ratio, self.test_ratio, self.valid_ratio) - tree = ET.parse('template.xml') - root = tree.getroot() + for image_ppt in self.ppts_train: #download image image_name = image_ppt[0][0] @@ -501,24 +498,34 @@ def rectjson_to_xml(self): #write to xml file train_out_annotation_dir = self.valid_path(os.path.join(self.train_path, 'annotations')) out_annotation_path = os.path.join(train_out_annotation_dir, self.replace_extension(img_path, '.xml')) - #modify xml template - folder = root.find('folder') - folder.text = train_out_annotation_dir - - fname = root.find('filename') + #create xml enteries + root = ET.Element('annotation') + #append folder + folder = ET.SubElement(root, 'folder') + folder.text = self.valid_path(os.path.join(self.train_path, 'images')) + ET.indent(folder, space='\t', level=1) + + fname = ET.SubElement(root, 'filename') fname.text = img_path + ET.indent(fname, space='\t', level=1) - src = root.find('source') - database = src.find('database') + src = ET.SubElement(root, 'source') + database = ET.SubElement(src, 'database') database.text = self.database + ET.indent(src, space='\t', level=1) - size = root.find('size') - width = size.find('width') + size = ET.SubElement(root, 'size') + width = ET.SubElement(size, 'width') width.text = str(img_width) - height = size.find('height') + height = ET.SubElement(size, 'height') height.text = str(img_height) - depth = size.find('depth') + depth = ET.SubElement(size, 'depth') depth.text = str(img_depth) + ET.indent(size, space='\t', level=1) + + segmented = ET.SubElement(root, 'segmented') + segmented.text = str(0) + ET.indent(segmented, space='\t', level=1) for ppt in image_ppt: #append new object @@ -540,9 +547,14 @@ def rectjson_to_xml(self): ymin.text = str(int(ppt[8])) ymax = ET.SubElement(bndbox, 'ymax') ymax.text = str(int(ppt[9])) - - #save annotation to xml file - tree.write(out_annotation_path) + + ET.indent(obj, space='\t', level=1) + ET.indent(root, space='\t', level=0) + #convert xml to byte object + b_xml = ET.tostring(root) + #save annotation to out_xml_path + with open(out_annotation_path, 'wb') as f: + f.write(b_xml) for image_ppt in self.ppts_test: #download image @@ -553,24 +565,34 @@ def rectjson_to_xml(self): #write to xml file test_out_annotation_dir = self.valid_path(os.path.join(self.test_path, 'annotations')) out_annotation_path = os.path.join(test_out_annotation_dir, self.replace_extension(img_path, '.xml')) - #modify xml template - folder = root.find('folder') - folder.text = test_out_annotation_dir - - fname = root.find('filename') + #create xml enteries + root = ET.Element('annotation') + #append folder + folder = ET.SubElement(root, 'folder') + folder.text = self.valid_path(os.path.join(self.test_path, 'images')) + ET.indent(folder, space='\t', level=1) + + fname = ET.SubElement(root, 'filename') fname.text = img_path + ET.indent(fname, space='\t', level=1) - src = root.find('source') - database = src.find('database') + src = ET.SubElement(root, 'source') + database = ET.SubElement(src, 'database') database.text = self.database + ET.indent(src, space='\t', level=1) - size = root.find('size') - width = size.find('width') + size = ET.SubElement(root, 'size') + width = ET.SubElement(size, 'width') width.text = str(img_width) - height = size.find('height') + height = ET.SubElement(size, 'height') height.text = str(img_height) - depth = size.find('depth') + depth = ET.SubElement(size, 'depth') depth.text = str(img_depth) + ET.indent(size, space='\t', level=1) + + segmented = ET.SubElement(root, 'segmented') + segmented.text = str(0) + ET.indent(segmented, space='\t', level=1) for ppt in image_ppt: #append new object @@ -592,9 +614,14 @@ def rectjson_to_xml(self): ymin.text = str(int(ppt[8])) ymax = ET.SubElement(bndbox, 'ymax') ymax.text = str(int(ppt[9])) - - #save annotation to xml file - tree.write(out_annotation_path) + + ET.indent(obj, space='\t', level=1) + ET.indent(root, space='\t', level=0) + #convert xml to byte object + b_xml = ET.tostring(root) + #save annotation to out_xml_path + with open(out_annotation_path, 'wb') as f: + f.write(b_xml) for image_ppt in self.ppts_valid: #download image @@ -605,24 +632,34 @@ def rectjson_to_xml(self): #write to xml file validation_out_annotation_dir = self.valid_path(os.path.join(self.validation_path, 'annotations')) out_annotation_path = os.path.join(validation_out_annotation_dir, self.replace_extension(img_path, '.xml')) - #modify xml template - folder = root.find('folder') - folder.text = validation_out_annotation_dir - - fname = root.find('filename') + #create xml enteries + root = ET.Element('annotation') + #append folder + folder = ET.SubElement(root, 'folder') + folder.text = self.valid_path(os.path.join(self.validation_path, 'images')) + ET.indent(folder, space='\t', level=1) + + fname = ET.SubElement(root, 'filename') fname.text = img_path + ET.indent(fname, space='\t', level=1) - src = root.find('source') - database = src.find('database') + src = ET.SubElement(root, 'source') + database = ET.SubElement(src, 'database') database.text = self.database + ET.indent(src, space='\t', level=1) - size = root.find('size') - width = size.find('width') + size = ET.SubElement(root, 'size') + width = ET.SubElement(size, 'width') width.text = str(img_width) - height = size.find('height') + height = ET.SubElement(size, 'height') height.text = str(img_height) - depth = size.find('depth') + depth = ET.SubElement(size, 'depth') depth.text = str(img_depth) + ET.indent(size, space='\t', level=1) + + segmented = ET.SubElement(root, 'segmented') + segmented.text = str(0) + ET.indent(segmented, space='\t', level=1) for ppt in image_ppt: #append new object @@ -644,9 +681,14 @@ def rectjson_to_xml(self): ymin.text = str(int(ppt[8])) ymax = ET.SubElement(bndbox, 'ymax') ymax.text = str(int(ppt[9])) - - #save annotation to xml file - tree.write(out_annotation_path) + + ET.indent(obj, space='\t', level=1) + ET.indent(root, space='\t', level=0) + #convert xml to byte object + b_xml = ET.tostring(root) + #save annotation to out_xml_path + with open(out_annotation_path, 'wb') as f: + f.write(b_xml) print('All done!') def rectjson_to_kerasRetinanetCsv(self): diff --git a/src/rectvision/data/converters/xmlToCoco.py b/src/rectvision/data/converters/xmlToCoco.py index baec12d..8a4030f 100644 --- a/src/rectvision/data/converters/xmlToCoco.py +++ b/src/rectvision/data/converters/xmlToCoco.py @@ -128,6 +128,7 @@ def annotation(self, points, label, num): [[xmin, ymin], [xmax, ymax]] = points o_width = xmax - xmin o_height = ymax - ymin + annotation["area"] = o_width * o_height annotation["bbox"] = [xmin, ymin, o_width, o_height] annotation["category_id"] = label # self.getcatid(label) diff --git a/src/rectvision/models/yolov5.py b/src/rectvision/models/yolov5.py index c920184..55be008 100644 --- a/src/rectvision/models/yolov5.py +++ b/src/rectvision/models/yolov5.py @@ -113,7 +113,8 @@ def get_map(self): "--weights", self.model_weights, "--data", self.data_yaml, "--task", "test", - "--name", self.project_name + '_performance'], capture_output=True, text=True) + "--name", self.project_name + '_performance', + "--save-json"], capture_output=True, text=True) # !python {self.test_model} --weights {self.model_weights} --data {self.data_yaml} --task test --name {self.project_name + '_performance'} if process.returncode == 0: print('Evaluated successfully!')