Я пишу простую вспомогательную функцию, которая перебирает все найденные контуры и выполняет с ними определенные операции. Мой вопрос: есть ли способ векторизовать этот цикл for, чтобы сделать код более эффективным.

def TL(contours):
    k = 0
    for j, cnt in enumerate(contours):
        k =+ 1
        # x,y,w,h = cv2.boundingRect(cnt)
        area = cv2.contourArea(cnt)
        # r = w/h
        # if r <= 1.2*2.142 and r >= 0.8*2.142:
        approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt, True), True)

        if area > 50 and cv2.isContourConvex(cnt) == False and len(approx)<=15 and len(approx)>=8: # and len(approx)>=8  
            # cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
            (xc,yc),radius = cv2.minEnclosingCircle(cnt)
            # cv2.circle(frame,(int(xc),int(yc)),int(radius*0.9),(0,255,0),2)
            # TARGET = (xc,yc-radius-1)
            # nearest = find_nearest_white(TARGET)
            h = int(radius*4)
            w = int(h*2.25)
            x = int(xc-(1/3)*w)
            y = int(yc-h/2)

            if w*h <= 4000:
                cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
            continue

    return frame
-1
Wael Karkoub 24 Дек 2017 в 11:21

1 ответ

Лучший ответ

У вас есть набор контуров, и самая медленная часть вашего кода (согласно вашему комментарию) - cv2.minEnclosingCircle().

Я вижу два основных подхода:

  1. Посмотрите на реализацию cv2.minEnclosingCircle() и посмотрите, сможете ли вы создать более быструю (для ваших входных данных). Здесь упоминаются некоторые алгоритмы: Как я могу найти минимальный круг, включающий некоторые заданные точки?

  2. Используйте несколько потоков (с выпущенным GIL) или несколько процессов. Вызовы cv2.minEnclosingCircle() могут выполняться параллельно (возможно, заранее), поскольку все они независимы.

0
John Zwinck 24 Дек 2017 в 09:43