tinyvision / DAMO-YOLO

DAMO-YOLO: a fast and accurate object detection method with some new techs, including NAS backbones, efficient RepGFPN, ZeroHead, AlignedOTA, and distillation enhancement.
Apache License 2.0
3.75k stars 470 forks source link

[Bug]: cv2.error: OpenCV(4.9.0) :-1: error: (-5:Bad argument) in function 'rectangle' #138

Open xmdszzz opened 4 months ago

xmdszzz commented 4 months ago

Before Reporting

Search before reporting

OS

Windows

Device

Nvidia 4070Ti

CUDA version

11.8

TensorRT version

8.6.1.6

Python version

3.8

PyTorch version

2.2.2

torchvision version

0.17.2

Describe the bug

运行推理时,在damo/utils/visualize.py中报错,显示numpy数组是只读的不允许操作。 ` File "E:\proj\DAMO-YOLO\damo\utils\visualize.py", line 30, in vis cv2.rectangle(img, (x0, y0), (x1, y1), color, 2) │ │ │ │ │ │ │ └ [0, 113, 188] │ │ │ │ │ │ └ 261 │ │ │ │ │ └ 322 │ │ │ │ └ 229 │ │ │ └ 309 │ │ └ array([[[255, 255, 255], │ │ [255, 255, 255], │ │ [255, 255, 255], │ │ ..., │ │ [255, 255, 255], │ │ [255... │ └ └ <module 'cv2' from 'C:\Users\chonpsk\.conda\envs\DAMO-YOLO\lib\site-packages\cv2\init.py'>

cv2.error: OpenCV(4.9.0) :-1: error: (-5:Bad argument) in function 'rectangle'

Overload resolution failed:

  • img marked as output argument, but provided NumPy array marked as readonly
  • Expected Ptr for argument 'img'
  • img marked as output argument, but provided NumPy array marked as readonly
  • Expected Ptr for argument 'img' `

To Reproduce

python demo.py image -f ./configs/damoyolo_tinynasL20_T.py --engine workdirs/damoyolo_tinynasL20_T/epoch_300_ckpt.pth --conf 0.1 --inf er_size 640 640 --device cuda --path datasets/Custom_coco/images/val/66_crop_0.jpg

Hyper-parameters/Configs

使用默认超参数

Logs

2024-04-11 10:13:31.168 | ERROR | main::356 - An error has been caught in function '', process 'MainProcess' (980), thread 'MainThread' (23684): Traceback (most recent call last):

File "demo.py", line 356, in main() └ <function main at 0x000001C91010F820>

File "demo.py", line 321, in main vis_res = infer_engine.visualize(origin_img, bboxes, scores, cls_inds, conf=args.conf, save_name=os.path.basename(args.path), save_result=args.save_result) │ │ │ │ │ │ │ │ │ │ │ │ │ │ └ True │ │ │ │ │ │ │ │ │ │ │ │ │ └ Namespace(camid=0, conf=0.6, confi g_file='./configs/damoyolo_tinynasL20_T.py', device='cuda', end2end=False, engine='workdirs... │ │ │ │ │ │ │ │ │ │ │ │ └ 'datasets/Custom_coco/images/val/66_crop_0.jpg'
│ │ │ │ │ │ │ │ │ │ │ └ Namespace(camid=0, conf=0.6, config_file='./configs/damoyo lo_tinynasL20_T.py', device='cuda', end2end=False, engine='workdirs... │ │ │ │ │ │ │ │ │ │ └ <function basename at 0x000001C95AD39EE0> │ │ │ │ │ │ │ │ │ └ <module 'ntpath' from 'C:\Users\chonpsk\.conda\envs\DAMO-YOLO\lib\ \ntpath.py'> │ │ │ │ │ │ │ │ └ <module 'os' from 'C:\Users\chonpsk\.conda\envs\DAMO-YOLO\lib\os.py'

│ │ │ │ │ │ │ └ 0.6 │ │ │ │ │ │ └ Namespace(camid=0, conf=0.6, config_file='./configs/damoyolo_tinynasL20_T.py', device='cuda', en d2end=False, engine='workdirs... │ │ │ │ │ └ tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
│ │ │ │ │ 0., 0., 0., 0... │ │ │ │ └ tensor([0.6785, 0.6641, 0.6581, 0.6514, 0.6470, 0.6399, 0.5757, 0.5683, 0.5609, │ │ │ │ 0.5585, 0.5564, 0.5532, 0.5524, 0.521... │ │ │ └ tensor([[309.0302, 229.5414, 322.8981, 261.2090], │ │ │ [267.1926, 28.5143, 280.6399, 46.0551], │ │ │ [307.3100, 135.57... │ │ └ array([[[255, 255, 255], │ │ [255, 255, 255], │ │ [255, 255, 255], │ │ ..., │ │ [255, 255, 255], │ │ [255... │ └ <function Infer.visualize at 0x000001C91010F700> └ <main.Infer object at 0x000001C95AE46550>

File "demo.py", line 249, in visualize vis_img = vis(image, bboxes, scores, cls_inds, conf, self.class_names) │ │ │ │ │ │ │ └ ['qx'] │ │ │ │ │ │ └ <main.Infer object at 0x000001C95AE46550> │ │ │ │ │ └ 0.6 │ │ │ │ └ tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., │ │ │ │ 0., 0., 0., 0... │ │ │ └ tensor([0.6785, 0.6641, 0.6581, 0.6514, 0.6470, 0.6399, 0.5757, 0.5683, 0.5609, │ │ │ 0.5585, 0.5564, 0.5532, 0.5524, 0.521... │ │ └ tensor([[309.0302, 229.5414, 322.8981, 261.2090], │ │ [267.1926, 28.5143, 280.6399, 46.0551], │ │ [307.3100, 135.57... │ └ array([[[255, 255, 255], │ [255, 255, 255], │ [255, 255, 255], │ ..., │ [255, 255, 255], │ [255... └ <function vis at 0x000001C910064DC0>

File "E:\proj\DAMO-YOLO\damo\utils\visualize.py", line 30, in vis cv2.rectangle(img, (x0, y0), (x1, y1), color, 2) │ │ │ │ │ │ │ └ [0, 113, 188] │ │ │ │ │ │ └ 261 │ │ │ │ │ └ 322 │ │ │ │ └ 229 │ │ │ └ 309 │ │ └ array([[[255, 255, 255], │ │ [255, 255, 255], │ │ [255, 255, 255], │ │ ..., │ │ [255, 255, 255], │ │ [255... │ └ └ <module 'cv2' from 'C:\Users\chonpsk\.conda\envs\DAMO-YOLO\lib\site-packages\cv2\init.py'>

cv2.error: OpenCV(4.9.0) :-1: error: (-5:Bad argument) in function 'rectangle'

Overload resolution failed:

  • img marked as output argument, but provided NumPy array marked as readonly
  • Expected Ptr for argument 'img'
  • img marked as output argument, but provided NumPy array marked as readonly
  • Expected Ptr for argument 'img'

Screenshots

No response

Additional

将 vis内对numpy数组拷贝后进行操作解决该问题: `def vis(img, boxes, scores, cls_ids, conf=0.5, class_names=None):

for i in range(len(boxes)):
    box = boxes[i]
    cls_id = int(cls_ids[i])
    score = scores[i]
    if score < conf:
        continue
    x0 = int(box[0])
    y0 = int(box[1])
    x1 = int(box[2])
    y1 = int(box[3])

    color = (_COLORS[cls_id] * 255).astype(np.uint8).tolist()
    text = '{}:{:.1f}%'.format(class_names[cls_id], score * 100)
    txt_color = (0, 0, 0) if np.mean(_COLORS[cls_id]) > 0.5 else (255, 255,
                                                                  255)
    font = cv2.FONT_HERSHEY_SIMPLEX

    txt_size = cv2.getTextSize(text, font, 0.4, 1)[0]
    img_copy = np.copy(img)
    cv2.rectangle(img_copy, (x0, y0), (x1, y1), color, 2)
    # cv2.rectangle(img, (x0, y0), (x1, y1), color, 2)

    txt_bk_color = (_COLORS[cls_id] * 255 * 0.7).astype(np.uint8).tolist()
    # cv2.rectangle(img, (x0, y0 + 1),
    #               (x0 + txt_size[0] + 1, y0 + int(1.5 * txt_size[1])),
    #               txt_bk_color, -1)
    cv2.rectangle(img_copy, (x0, y0 + 1),
                  (x0 + txt_size[0] + 1, y0 + int(1.5 * txt_size[1])),
                  txt_bk_color, -1)
    # cv2.putText(img,
    #             text, (x0, y0 + txt_size[1]),
    #             font,
    #             0.4,
    #             txt_color,
    #             thickness=1)
    cv2.putText(img_copy,
                text, (x0, y0 + txt_size[1]),
                font,
                0.4,
                txt_color,
                thickness=1)

# return img
return img_copy`
adkbbx commented 4 months ago

@xmdszzz I had the same issue and used the code above to fix it but there is a small problem with the vis() function as it isn't working as expected is because you're creating a new copy of the image img inside the for loop for each bounding box. As a result, each bounding box is drawn on a new copy of the original image, and only the last one is returned.

To fix this, you need to move the line img_copy = np.copy(img) outside the loop, so that you're drawing all bounding boxes on the same image copy.

Here's the corrected version of the vis() function which worked for me:


def vis(img, boxes, scores, cls_ids, conf=0.5, class_names=None):

    img_copy = np.copy(img)
    for i in range(len(boxes)):   
        box = boxes[i]
        cls_id = int(cls_ids[i])
        score = scores[i]
        if score < conf:
            continue
        x0 = int(box[0])
        y0 = int(box[1])
        x1 = int(box[2])
        y1 = int(box[3])

        color = (_COLORS[cls_id] * 255).astype(np.uint8).tolist()
        text = '{}:{:.1f}%'.format(class_names[cls_id], score * 100)
        txt_color = (0, 0, 0) if np.mean(_COLORS[cls_id]) > 0.5 else (255, 255,
                                                                      255)
        font = cv2.FONT_HERSHEY_SIMPLEX

        txt_size = cv2.getTextSize(text, font, 0.4, 1)[0]

        cv2.rectangle(img_copy, (x0, y0), (x1, y1), color, 2)

        txt_bk_color = (_COLORS[cls_id] * 255 * 0.7).astype(np.uint8).tolist()
        cv2.rectangle(img_copy, (x0, y0 + 1),
                     (x0 + txt_size[0] + 1, y0 + int(1.5 * txt_size[1])),
                     txt_bk_color, -1)

        cv2.putText(img_copy,
                    text, (x0, y0 + txt_size[1]),
                    font,
                    0.4,
                    txt_color,
                    thickness=1)

    return img_copy

Hope it helps!

xmdszzz commented 4 months ago

@adkbbx Yes! Thanks for pointing this out and providing a solution.That's very helpful.

yachunchen commented 4 months ago

@adkbbx problem solved. Thansk!