Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial working version of VOC XML import #280

Merged
merged 7 commits into from
Oct 10, 2022
Prev Previous commit
Next Next commit
add some error wrapping to indicate file problems
  • Loading branch information
hartmannr76 committed Oct 6, 2022
commit c99b940004fd7837e468eb2da494a02bb843283c
70 changes: 54 additions & 16 deletions src/logic/import/voc/VOCImporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ type VOCImportResult = {
fileParseResults: FileParseResult[],
};

class DocumentParsingError extends Error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SkalskiP These types of errors are likely similar to existing YOLO and COCO errors and could be genericized but since I'm only using them in this file at the moment just to indicate what imported file had the issue, I was planning to just keep them here for now. Let me know if you'd like me to move it out

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We can keep them here for now. But you are right, long term we could centrally think about the standardization of error types for different label formats, where possible.

constructor(message?: string) {
super(message);
this.name = "DocumentParsingError";
}
}
class AnnotationParsingError extends Error {
constructor(message?: string) {
super(message);
this.name = "AnnotationParsingError";
}
}

const parser = new DOMParser();

export class VOCImporter extends AnnotationImporter {
public import(
filesData: File[],
Expand Down Expand Up @@ -40,31 +55,54 @@ export class VOCImporter extends AnnotationImporter {
}

private loadAndParseFiles(files: File[]): Promise<VOCImportResult> {
const parser = new DOMParser();

return Promise.all(files.map((file: File) => file.text())).then((fileTexts: string[]) =>
fileTexts.reduce((current: VOCImportResult, fileText: string) =>
VOCImporter.parseDocumentIntoImageData(parser.parseFromString(fileText, 'application/xml'), current),
{
labelNames: {},
fileParseResults: [],
} as VOCImportResult)
fileTexts.reduce((current: VOCImportResult, fileText: string, currentIndex: number) =>
{
const fileName = files[currentIndex].name;
try {
return VOCImporter.parseDocumentIntoImageData(VOCImporter.tryParseVOCDocument(fileText), current);
} catch (e) {
if (e instanceof DocumentParsingError) {
throw new DocumentParsingError(`Failed trying to parse ${fileName} as VOC XML document.`)
} else if (e instanceof AnnotationParsingError) {
throw new AnnotationParsingError(`Failed trying to find required VOC annotations for ${fileName}.`)
} else {
throw e;
}
}
},
{
labelNames: {},
fileParseResults: [],
} as VOCImportResult)
);
}

private static tryParseVOCDocument(fileText: string): Document {
try {
return parser.parseFromString(fileText, 'application/xml');
} catch {
throw new DocumentParsingError();
}
}

protected static parseDocumentIntoImageData(document: Document, { fileParseResults, labelNames }: VOCImportResult): VOCImportResult {
const root = document.getElementsByTagName('annotation')[0];
const filename = root.getElementsByTagName('filename')[0].textContent;

const [labeledBoxes, newLabelNames] = this.parseAnnotationsFromFileString(document, labelNames);
try {
const [labeledBoxes, newLabelNames] = this.parseAnnotationsFromFileString(document, labelNames);

return {
labelNames: newLabelNames,
fileParseResults: fileParseResults.concat({
filename,
labeledBoxes
}),
};
return {
labelNames: newLabelNames,
fileParseResults: fileParseResults.concat({
filename,
labeledBoxes
}),
};
} catch {
throw new AnnotationParsingError();
}
}

protected static parseAnnotationsFromFileString(document: Document, labelNames: Record<string, LabelName>):
Expand Down