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)

  • 1
    How did you create the JSON data? Looks like whatever you used does not properly handle backslashes in string values. – jasonharper Jan 26 '21 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. – DisappointedByUnaccountableMod Jan 26 '21 at 22:44
  • Does this answer your question? [json reading error json.decoder.JSONDecodeError: Invalid \escape](https://stackoverflow.com/questions/44687525/json-reading-error-json-decoder-jsondecodeerror-invalid-escape) – user202729 Feb 17 '21 at 11:29

5 Answers5

9

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.

Chr1s
  • 258
  • 3
  • 14
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}
 ] 
}
]
George Poliovei
  • 1,009
  • 10
  • 12
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).

fluffyyboii
  • 635
  • 6
  • 15
  • 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? –  Jan 26 '21 at 23:21
  • 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. – fluffyyboii Jan 27 '21 at 12:10
  • json.load() will take the .json file and converts it into an object? –  Jan 27 '21 at 16:11
  • Yes, that's true. – fluffyyboii Jan 27 '21 at 18:00
1

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')
Yug Damor
  • 11
  • 1
  • 1
0
data=text.replace("\\"," ")
js_data = json.loads(data)
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • data=response.text.replace("\\"," ") js_data = json.loads(data) – DERANGULA JAGADEESH May 09 '23 at 06:43
  • 1
    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](/help/how-to-answer). – Community May 09 '23 at 11:49