Hello!
I'm trying to prepare preprocessing pipeline for MMPose network - specifically for hrnet48.
Logic of preprocessing without DALI:
For mmpose operation, an additional object detector is used.
Object detections are then cropped from the main image. Then a batch is formed from these cropped out detections and fed into the hrnet48 network.
The point is that the batch depends on the number of people in the frame - it is always different, dynamic. That is why I read it from fn.external_source along with an image.
I try to crop a one big image with some count of persons on it using fn.crop operation with parameters crop_pos_x and crop_pos_y. It works fine for one person (when I use crop_pos_x=persons_list[0][0]/1920, crop_pos_y=persons_list[0][3]/1080 instead of crop_pos_x=persons_list[0]/1920, crop_pos_y=persons_list[3]/1080, for example), but how to pass list of coordinates to crop to cut multiple bboxes from image?
According DALI documentation it is possible, for example, crop_pos_x (float or TensorList of float, optional, default = 0.5). But list does not work for me.
So the question is - how to use fn.crop function to crop many images from original image? How to pass a list of coordinates into fn.crop?
Source code:
class ExternalInputIterator(object):
def __init__(self, image, persons):
self.image = image
self.persons = persons
def __iter__(self):
return self
def __next__(self):
return self.image, self.persons
def update(self, image, persons):
self.image = image
self.persons = persons
Code from loop over video:
global eii
# make batch image of (1, 1920, 1080, 3) shape
dali_image = np.expand_dims(image, axis=0).astype(np.uint8)
# make batch persons of (1, N, 5) shape, where N - count of persons detected on frame. 5 - x1,y1,x2,y2,confidence.
dali_persons = np.expand_dims(np.stack(persons_result, axis=0), axis=0).astype(np.float32)
eii.update(image=dali_image, persons=dali_persons)
batch_dali = dali_pipeline.run()
out_images = batch_dali[0].as_array()
cv2.imwrite(f"dali_images/img_{i}.jpg", out_images[0])
out_persons = batch_dali[1].as_array()
Error, when I try to pass list of coordinates into fn.crop:
dummy_img = np.random.randint(2, size=(1, 1920, 1080))
dummy_img = dummy_img.astype(np.uint8)
eii = ExternalInputIterator(image=dummy_img, persons=np.expand_dims(np.array([1, 2], dtype=np.float32), axis=0))
@pipeline_def(batch_size=1, num_threads=4, device_id=0)
def mmpose_preprocess_pipeline():
"""
Prepares pipeline of operations.
:param batch_size: size of maximum batch for new DALI model.
:param num_threads: number of CPU threads to be used.
:param device_id: ID of GPU.
:return: preprocessed images.
"""
crop = (256, 192)
image, persons_list = fn.external_source(source=eii, num_outputs=2, dtype=[types.UINT8, types.FLOAT])
cropped = fn.crop(image, crop_pos_x=persons_list[0]/1920, crop_pos_y=persons_list[3]/1080, crop=crop, out_of_bounds_policy="pad", device="cpu")
return cropped, persons_list
def create_pipeline(batch_size: int = 256, num_threads: int = 4, device_id: int = 0):
"""
Builds and serialize pipeline of operations to DALI model.
:param model_func_obj: function object pf model pipeline.
:param path_to_save: path to save DALI model.
:param batch_size: size of maximum batch for new DALI model.
:param num_threads: number of CPU threads to be used.
:param device_id: ID of GPU.
:return: NoReturn.
"""
print('Building pipeline...')
pipeline = mmpose_preprocess_pipeline(batch_size=batch_size, num_threads=num_threads, device_id=device_id)
pipeline.build()
print('Done!')
return pipeline
Building pipeline...
Done!
/usr/local/lib/python3.8/dist-packages/torch/nn/functional.py:718: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at /pytorch/c10/core/TensorImpl.h:1156.)
return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode)
Traceback (most recent call last):
File "/home/user/mmpose/pe_solutions/mmpose/dali_demo.py", line 189, in <module>
img_det, fps, person_count = process_img(pose_model, det_model, img, dali_pipeline=pipe, i=i)
File "/home/user/mmpose/pe_solutions/mmpose/dali_demo.py", line 94, in process_img
batch_dali = dali_pipeline.run()
File "/usr/local/lib/python3.8/dist-packages/nvidia/dali/pipeline.py", line 922, in run
return self.outputs()
File "/usr/local/lib/python3.8/dist-packages/nvidia/dali/pipeline.py", line 821, in outputs
return self._outputs()
File "/usr/local/lib/python3.8/dist-packages/nvidia/dali/pipeline.py", line 905, in _outputs
return self._pipe.Outputs()
RuntimeError: Critical error in pipeline:
Error when executing CPU operator TensorSubscript, instance name: "__TensorSubscript_4", encountered:
[/opt/dali/dali/operators/generic/slice/subscript.h:214] Index 3 is out of range for axis 0 of length 3
Detected while processing sample #0 of shape (3 x 5)
Stacktrace (11 entries):
[frame 0]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali_operators.so(+0x594bc2) [0x7fc06292cbc2]
[frame 1]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali_operators.so(+0xfa60bb) [0x7fc06333e0bb]
[frame 2]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali_operators.so(+0xfa6b57) [0x7fc06333eb57]
[frame 3]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali.so(void dali::Executor<dali::AOT_WS_Policy<dali::UniformQueuePolicy>, dali::UniformQueuePolicy>::RunHelper<dali::HostWorkspace>(dali::OpNode&, dali::HostWorkspace&)+0x7bd) [0x7fc08256d2cd]
[frame 4]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali.so(dali::Executor<dali::AOT_WS_Policy<dali::UniformQueuePolicy>, dali::UniformQueuePolicy>::RunCPUImpl()+0x218) [0x7fc0825720e8]
[frame 5]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali.so(dali::Executor<dali::AOT_WS_Policy<dali::UniformQueuePolicy>, dali::UniformQueuePolicy>::RunCPU()+0xe) [0x7fc082572bae]
[frame 6]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali.so(+0xb778d) [0x7fc08252978d]
[frame 7]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali.so(+0x12f8bc) [0x7fc0825a18bc]
[frame 8]: /usr/local/lib/python3.8/dist-packages/nvidia/dali/libdali.so(+0x712b6f) [0x7fc082b84b6f]
[frame 9]: /usr/lib/x86_64-linux-gnu/libpthread.so.0(+0x8609) [0x7fc1f2198609]
[frame 10]: /usr/lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x7fc1f22d2133]
Current pipeline object is no longer valid.
Process finished with exit code 1
Hello!
I'm trying to prepare preprocessing pipeline for MMPose network - specifically for hrnet48.
Logic of preprocessing without DALI:
For mmpose operation, an additional object detector is used.
Object detections are then cropped from the main image. Then a batch is formed from these cropped out detections and fed into the hrnet48 network.
The point is that the batch depends on the number of people in the frame - it is always different, dynamic. That is why I read it from
fn.external_sourcealong with an image.I try to crop a one big image with some count of persons on it using
fn.cropoperation with parameterscrop_pos_xandcrop_pos_y. It works fine for one person (when I usecrop_pos_x=persons_list[0][0]/1920,crop_pos_y=persons_list[0][3]/1080instead ofcrop_pos_x=persons_list[0]/1920,crop_pos_y=persons_list[3]/1080, for example), but how to pass list of coordinates to crop to cut multiple bboxes from image?According DALI documentation it is possible, for example, crop_pos_x (float or TensorList of float, optional, default = 0.5). But list does not work for me.
So the question is - how to use
fn.cropfunction to crop many images from original image? How to pass a list of coordinatesinto fn.crop?Source code:
Code from loop over video:
Error, when I try to pass list of coordinates into
fn.crop: