5

After running my object detection model, it outputs a .json file with the results. In order to actually use the results of the model in my python I need to parse the .json file, but nothing I have tried in order to do it works. I tried just to open and then print the results but I got the error:

json.decoder.JSONDecodeError: Invalid \escape: line 4 column 41 (char 60)

If you have any idea what I did wrong, the help would be very much appreciated. My code:

with open(r'C:\Yolo_v4\darknet\build\darknet\x64\result.json') as result:
    data = json.load(result)
    result.close()

print(data)

My .json file

[
{
 "frame_id":1, 
 "filename":"C:\Yolo_v4\darknet\build\darknet\x64\f047.png", 
 "objects": [ 
  {"class_id":32, "name":"right", "relative_coordinates":{"center_x":0.831927, "center_y":0.202225, "width":0.418463, "height":0.034752}, "confidence":0.976091}, 
  {"class_id":19, "name":"h", "relative_coordinates":{"center_x":0.014761, "center_y":0.873551, "width":0.041723, "height":0.070544}, "confidence":0.484339}, 
  {"class_id":24, "name":"left", "relative_coordinates":{"center_x":0.285694, "center_y":0.200752, "width":0.619584, "height":0.032149}, "confidence":0.646595}, 
 ] 
}
]

(There are several more detected objects but did not include them)

3
  • 1
    How did you create the JSON data? Looks like whatever you used does not properly handle backslashes in string values. Commented Jan 26, 2021 at 22:39
  • 1
    Yes basically the problem is that the file is not valid JSON. Those \ in the file paths should be doubled - this as written as invalid JSON by whatever created the file. Commented Jan 26, 2021 at 22:44
  • Does this answer your question? json reading error json.decoder.JSONDecodeError: Invalid \escape Commented Feb 17, 2021 at 11:29

5 Answers 5

11

The other responders are of course right. This is not valid JSON. But sometimes you don't have the option to change the format, e.g. because you are working with a broken data dump where the original source is no longer available.

The only way to deal with that is to sanitize it somehow. This is of course not ideal, because you have to put a lot of expectations into your sanitizer code, i.e. you need to know exactly what kind of errors the json file has.

However, a solution using regular expressions could look like this:

import json
import re

class LazyDecoder(json.JSONDecoder):
    def decode(self, s, **kwargs):
        regex_replacements = [
            (re.compile(r'([^\\])\\([^\\])'), r'\1\\\\\2'),
            (re.compile(r',(\s*])'), r'\1'),
        ]
        for regex, replacement in regex_replacements:
            s = regex.sub(replacement, s)
        return super().decode(s, **kwargs)

with open(r'C:\Yolo_v4\darknet\build\darknet\x64\result.json') as result:
    data = json.load(result, cls=LazyDecoder)

print(data)

This is by subclassing the standard JSONDecoder and using that one for loading.

Sign up to request clarification or add additional context in comments.

Comments

4

the function uses the encode method to encode the string as UTF-8, and the decode method with the unicode_escape codec to decode the string, removing any escape sequences in the process.

def remove_escape_sequences(string):
    return string.encode('utf-8').decode('unicode_escape')

Comments

3

Hi you need to use double (backslashes), remove the last comma in the objects property and finally you dont need close the file inside the with block

[
{
 "frame_id":1, 
 "filename":"C:\\Yolo_v4\\darknet\\build\\darknet\\x64\\f047.png", 
 "objects": [ 
    {"class_id":32, "name":"right", "relative_coordinates":{"center_x":0.831927,     "center_y":0.202225, "width":0.418463, "height":0.034752}, "confidence":0.976091}, 
    {"class_id":19, "name":"h", "relative_coordinates":{"center_x":0.014761,     "center_y":0.873551, "width":0.041723, "height":0.070544}, "confidence":0.484339}, 
    {"class_id":24, "name":"left", "relative_coordinates":{"center_x":0.285694,     "center_y":0.200752, "width":0.619584, "height":0.032149}, "confidence":0.646595}
 ] 
}
]

Comments

2

The "\" character is used not only in Windows filepaths but also as an escape character for things like newlines (you can use "\n" instead of an actual newline, for example). To escape the escape, you simply have to put a second backslash before it, like this:

"C:\\Yolo_v4\\darknet\\build\\darknet\\x64\\f047.png"

As someone said in the comments, json.dump should do this automatically for you, so it sounds like something internal is messed up (unless this wasn't created using that).

4 Comments

It wasn't created using json.dump, it was created as the output of a command run on command line. The problem is every time I run the command I will have to find a way to change those slashes into double slashes. Also, is there anyway to convert this to a dictionary?
How are you formatting the string? Also, json.load and json.dump are the only things you should really need. One converts an object into a JSON file, and the other takes a file and converts it back into the object.
json.load() will take the .json file and converts it into an object?
Yes, that's true.
-2
data=text.replace("\\"," ")
js_data = json.loads(data)

2 Comments

data=response.text.replace("\\"," ") js_data = json.loads(data)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.