Home > Back-end >  Faster method of copying bounding box content onto canvas with numpy
Faster method of copying bounding box content onto canvas with numpy

Time:11-17

I have an image with several detections with bounding boxes that overlap. I want to be able to extract different combinations of overlapping boxes onto a blank canvas, then save it as an image.

To visualise, if there are detections like this:

Example overlapping boxes

I want to be able to test boxes 1 2, 1 3, 2 3 with the box not included set to white. To do this I'm using the following code:

import numpy as np
import cv2
import time

#orig = cv2.imread("Orig.jpg")
orig = np.zeros((9536, 13480, 3), dtype=np.uint8) # dummy
print(orig.shape)
rects = [[1000,1000,1100,1100], [1100,1000,1200,1100],[1100,1100,1200,1200]]
loops = 10


starttime = time.perf_counter()
blankCanvas = np.full(orig.shape, (255,255,255), np.uint8)

for i in range(loops):
    canvas = blankCanvas.copy()
    for rect in rects:
        x1,y1,x2,y2 = rect
        canvas[y1:y2,x1:x2] = orig[y1:y2, x1:x2]
    xs = np.hstack((np.array(rects)[:,0],np.array(rects)[:,2]))
    ys = np.hstack((np.array(rects)[:,1],np.array(rects)[:,3]))
    cv2.imwrite(str(i)   ".jpg", canvas[min(ys):max(ys), min(xs):max(xs)])
fulltime = time.perf_counter()-starttime

looptime = fulltime/loops
recttime = looptime/len(rects)
print("Time taken per loop:: ", looptime)
print("Time taken per rect:: ", recttime)

Output:::
(9536, 13480, 3)
Time taken per loop::  0.22753073000000001
Time taken per rect::  0.07584357666666668

Each loop is taking roughly quarter a second, the issue is I have to do thousands of loops. I managed to speed it up by copying a blank canvas rather than reinitizializing the canvas every loop, but I'm not sure how else I can optimise the process of copying across sections to the canvas.

The majority of time in a loop is spend on this section:

canvas = blankCanvas.copy()
for rect in rects:
    x1,y1,x2,y2 = rect
    canvas[y1:y2,x1:x2] = orig[y1:y2, x1:x2]

Writing to disk doesn't seem to make any difference to timing.

Thanks in advance.

CodePudding user response:

Loop time is dominated by the np.full (~500 ms) and the .copy() (100 ms).

The actual calculations cost four orders of magnitude less time.

You introduced the .copy() operation purely for the time measurement, so your measurement method disturbed the thing you tried to measure.

You also included constant setup cost (the np.full) when you only tried to determine the cost of the actual calculation.

Please use a profiler: https://docs.python.org/3/library/profile.html

  • Related