OpenCV 错误:参数错误、重载解析失败、索引为 0 的序列项类型错误

jhe*_*e4x 2 python opencv

我正在做一个简单的项目来检测 QR 码并从网络摄像头捕获中绘制边界框。

import cv2
import numpy as np
import sys 
import time
#
# Sanity Check
print("QR Scanner initialized.")


# Utility function to get a video frame from webcam.
# @param: cap is a cv2.videoCapture object.
def captureFrame(cap):
    ret, frame = cap.read()
    if ret == False:
        print("Capture failed.")
    return frame

# Utility function to draw bounding box on frame.
def display(img, bbox):
    n = len(bbox)
    
    for j in range(n):
        cv2.line(img, 
                 tuple(bbox[j][0]), 
                 tuple(bbox[ (j+1) % n][0]), 
                 (255,0,0), 
                 3)
        cv2.imshow("Video", img)
    
# Function to detect QR code in an input image
def qrDetect(inputImage):
    # Create a qrCodeDetector Object.
    qrDecoder = cv2.QRCodeDetector()

    # Look for a qr code.    
    t = time.time()
    
    data, bbox, rectifiedImage = qrDecoder.detectAndDecode(inputImage)
    print("Time Taken for Detect and Decode : {:.3f} seconds.".format(time.time() - t))
    
    # Print output if applicable.
    if len(data) > 0:
        print("Decoded Data : {}".format(data))
        return 1, inputImage, bbox
    else:
        print("QR Code not detected")
        return 0, inputImage, 0


# Main function.  
def main():
    print("I'm alive!")
    
    # Stream webcam frames until 'q' is pressed.
    cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) 
    while True:
        frame = captureFrame(cap)
        ret, img, bbox = qrDetect(frame)
        
        if ret:
            display(img, bbox)
        else:
            cv2.imshow("Video", img)
        
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        
    cap.release()
    cv2.destroyAllWindows()
    
#
if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

我收到的错误如下:

cv2.error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function 'line'
> Overload resolution failed:
>  - Can't parse 'pt1'. Sequence item with index 0 has a wrong type
>  - Can't parse 'pt1'. Sequence item with index 0 has a wrong type
Run Code Online (Sandbox Code Playgroud)

从我从另一个线程中读到的内容来看,正在传递的元组 cv2.line 必须由整数组成。

我试过了:

  1. 迭代 bbox 并将每个值转换为整数
for j in range(n):
    cv2.line(img, 
             tuple(int(bbox[j][0])), 
             tuple(int(bbox[ (j+1) % n][0])), 
             (255,0,0), 
             3)
Run Code Online (Sandbox Code Playgroud)
  1. 使用 .astype(int)
bbox = bbox.astype(int)
for j in range(n):
    cv2.line(img, 
             tuple(bbox[j][0]), 
             tuple(bbox[ (j+1) % n][0]), 
             (255,0,0), 
             3)
Run Code Online (Sandbox Code Playgroud)

编辑:bbox(单个边界框的四个角)的内容如下:

[[[134.13043 150.     ]
  [362.3125  150.     ]
  [360.64886 362.94632]
  [143.58028 367.34634]]]
Run Code Online (Sandbox Code Playgroud)

任何建议将不胜感激!

Chr*_*itz 7

OpenCV 需要一个整数元组组,而你给它一个 numpy 浮点数元组。

是的,错误消息没有明确指出它需要整数。

OpenCV 的许多绘图函数都会发生此错误。常见的有cv.line, cv.rectangle,cv.circle ...

修复方法:使用 将数组转换为整数the_array.astype(int),即:

cv.line(..., pt1=bbox[j][0].astype(int), ...)
Run Code Online (Sandbox Code Playgroud)

您还可以添加适当的舍入并说the_array.round().astype(int)

这似乎适用于当前的OpenCV(使用 4.5.4 进行测试),因为它的绑定生成似乎已经学会了一些新技巧。以前,人们还必须做几件事:

  • 给它一个实际的元组,而不仅仅是一个 numpy 数组
  • 确保整数是 python 整数,而不是 numpy 整数

就像这样:

(x,y) = bbox[j][0]
cv.line(..., pt1=((int(x), int(y)), ...)
Run Code Online (Sandbox Code Playgroud)