0

I need to sort boxes array from top left to bottom right, and I am using the solution here How can I sort contours from left to right and top to bottom?. Which works fine. But I have another array which keep the box label, I need to use this label after sorting tmp_box array. So how can sort box_label or keep the original index of tmp_box like this How can I save the original index after sorting a list? which I can use to access the box_label.

box_label = ["box1","box2","box3"]
tmp_box = []
tmp_box.append([100,90,20,30]) #x,y,w,h
tmp_box.append([90,80,25,30]) #x,y,w,h
tmp_box.append([190,180,25,30]) #x,y,w,h

tmp_box_np = np.array(tmp_box)
max_height = np.max(tmp_box_np[::, 3])
nearest = max_height * 1.4
tmp_box.sort(key=lambda r: [int(nearest * round(float(r[1]) / nearest)), r[0]])
CodeDezk
  • 1,230
  • 1
  • 12
  • 40

3 Answers3

2

there are tones of ways to do it,

1. inserting the name in the list:

box_list = [[100, 90, 20, 30, "box1"],
            [90, 80, 25, 30, "box2"]
            [190, 180, 25, 30, "box3"]]
# your code won't change but the name is linked to the properties

2. using a lib:

ps: only works if all boxes are different!!!

box_labels = ["box1", "box2", "box3"]
box_properties = [
    [100,90,20,30],
    [90,80,25,30],
    [190,180,25,30] 
]

l = {}

for i in range(len(box_labels)):
    l[str(box_properties[i])] = box_labels[i]

box_prop = box_properties[0]

return l[box_prop]
#return box1

3. using a class:

class box:
    def __init__(self, l):
        self.label = l
        self.x = x
        self.y = y
        self.w = w
        self.h = h

# when sorting, use lambda box : (box.x, box.y, box.w, box.h)

All solutions are viable, just pick the one that fit your problem

Ren
  • 157
  • 12
1

You can do what has been suggested in another answer (and you have already refered to): use sorted with enumerate.

In code:

box_labels = ["box1", "box2", "box3"]
box_properties = [
    [100,90,20,30],
    [90,80,25,30],
    [190,180,25,30] 
]

max_height = max([properties[3] for properties in box_properties])
nearest = max_height * 1.4

sorted_index_boxes = sorted(enumerate(box_properties), key=lambda r: int(nearest * round(float(r[1][1]))))

print(sorted_index_boxes)

NOTE: I've renamed variables to improve readability and removed numpy since I don't think is necessary for this small example.

This outputs:

[(1, [90, 80, 25, 30]), (0, [100, 90, 20, 30]), (2, [190, 180, 25, 30])]

You can then use the indexes to get the box labels.

I hope this helps. Let me know if you need clarification.

Beni Trainor
  • 346
  • 1
  • 11
0

I resolved it by keeping a copy of tmp_box before sorting, to an array tmp_box_original

Then using arry.index() get the index like,

for box in tmp_box:
    index = tmp_box_original.index(box)
CodeDezk
  • 1,230
  • 1
  • 12
  • 40