You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次使用YOLO目标检测,OpenCV读入图片后触发TypeError问题

解决YOLO Darknet与OpenCV图像格式不兼容导致的TypeError

看起来你踩了Darknet Python绑定的一个常见坑——你传入detect函数的是OpenCV读取的numpy数组,但Darknet的load_image接口根本不支持这种格式。从报错信息里的ctypes.ArgumentError就能看出来:它期望的是图像路径字符串或者Darknet自己的image结构体,而不是numpy.ndarray。

下面给你两种针对性的解决方案,根据你的需求选就行:

方案1:直接传图像路径(最简单快捷)

如果你的预处理操作可以调整到Darknet加载图像之后,或者根本不需要提前预处理,直接把图像路径传给detect函数就好,完全绕开格式问题:

def ocr_function(image_path):  # 把参数改成图像路径,和内部变量统一
    start = time()
    try:
        ocr_threshold = 0.4
        ocr_weights = b'data/ocr/ocr-net.weights'
        ocr_netcfg = b'data/ocr/ocr-net.cfg'
        ocr_dataset = b'data/ocr/ocr-net.data'
        ocr_net = dn.load_net(ocr_netcfg, ocr_weights, 0)
        ocr_meta = dn.load_meta(ocr_dataset)
        print("performing OCR at: ", os.getcwd())
        print("\tScanning %s" % image_path)
        
        # 直接传路径给detect,不需要cv2.imread
        R,(width,height) = detect(ocr_net, ocr_meta, image_path, thresh=ocr_threshold, nms=None)
        
        if len(R):
            L = dknet_label_conversion(R,width,height)
            L = nms(L,.45)
            L.sort(key=lambda x: x.tl()[0])
            lp_str = ''.join([chr(l.cl()) for l in L])
            print ('\t\tLP: %s' % lp_str)

方案2:把OpenCV图像转成Darknet兼容格式(适合需要预处理的场景)

如果你必须用OpenCV做预处理(比如你的preprocess函数依赖numpy数组),那就需要把处理后的numpy图像转换成Darknet能识别的image结构体。我帮你写了个转换函数,直接用就行:

def cv2_to_darknet(image):
    # OpenCV读的是BGR,Darknet用的是RGB,必须转颜色空间
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    height, width, channel = image_rgb.shape
    # 创建Darknet的image结构体,然后把numpy数据拷贝进去
    darknet_image = dn.make_image(width, height, channel)
    dn.copy_image_from_bytes(darknet_image, image_rgb.tobytes())
    return darknet_image

def ocr_function(image_path):
    start = time()
    try:
        ocr_threshold = 0.4
        ocr_weights = b'data/ocr/ocr-net.weights'
        ocr_netcfg = b'data/ocr/ocr-net.cfg'
        ocr_dataset = b'data/ocr/ocr-net.data'
        ocr_net = dn.load_net(ocr_netcfg, ocr_weights, 0)
        ocr_meta = dn.load_meta(ocr_dataset)
        print("performing OCR at: ", os.getcwd())
        print("\tScanning %s" % image_path)
        
        # 用OpenCV读取并预处理
        image = cv2.imread(image_path)
        image = preprocess(image)
        show(image, "provided image")
        
        # 转换为Darknet兼容的图像对象
        darknet_img = cv2_to_darknet(image)
        # 传入转换后的图像进行检测
        R,(width,height) = detect(ocr_net, ocr_meta, darknet_img, thresh=ocr_threshold, nms=None)
        
        # 重要:用完后释放Darknet图像的内存,避免内存泄漏
        dn.free_image(darknet_img)
        
        if len(R):
            L = dknet_label_conversion(R,width,height)
            L = nms(L,.45)
            L.sort(key=lambda x: x.tl()[0])
            lp_str = ''.join([chr(l.cl()) for l in L])
            print ('\t\tLP: %s' % lp_str)

额外提醒

  • 你代码里有个小bug:函数参数是image,但内部却用了未定义的image_path,记得把参数名和内部变量统一起来,不然会报变量未定义的错误。
  • 颜色空间转换一定要做,不然Darknet检测出来的结果会完全不对(因为BGR和RGB的通道顺序反了)。
  • 用dn.make_image创建的图像对象一定要用dn.free_image释放,不然程序跑久了会内存溢出。

内容的提问来源于stack exchange,提问作者Anant Patankar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:51:58