Я использую OpenCV 4.1 на Python3. мне нужно получить среднюю сумму пикселей от мата. по координатам x и y, но он считается слишком медленным, в среднем (частота, задержка или время, я думаю) 0,06-0,07 на ПК (на Raspberry Pi 3B 0,6)

Вот мой код:

import cv2 as cv
import numpy as np

id = 1
cap = cv.VideoCapture(id)
if not cap.isOpened():
    print('cannot open camera ' + id)

while True:
    e1 = cv.getTickCount()
    sx = 0
    px = 1
    _, frame = cap.read()
    frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    _, frame = cv.threshold(frame, 50, 255, cv.THRESH_BINARY)
    for x in range(0, 640):
        for y in range(230, 250):
            if frame[y, x] == 0:
                sx += x
                px += 1
    print(sx / px)
    e2 = cv.getTickCount()
    print('average = ' + str((e2-e1) / cv.getTickFrequency()))
    cv.imshow('video', frame)
    if cv.waitKey(10) & 0xFF == ord('q'):
        break
cap.release()
cv.destroyAllWindows()

как я могу оптимизировать?

3
JoinMOD 20 Дек 2019 в 21:37

1 ответ

Лучший ответ

Ваш код может быть векторизован с numpy как:

while True:
    e1 = cv.getTickCount()
    sx = 0
    px = 1

    _, frame = cap.read()
    frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

    # note the _INV
    _, frame = cv.threshold(frame, 50, 255, cv.THRESH_BINARY_INV)

    # count the number of non-zero
    xs,_ = np.nonzero(frame)

    # if you insist on using cv.THRESH_BINARY
    # replace above two lines with
    # _, frame = cv.threshold(frame, 50, 255, cv.THRESH_BINARY)
    # xs,_ = np.where(frame==0)

    # equivalent of those two lines, without thresholding
    # xs, _ = np.where(frame < 50)

    # sx, px = xs.sum(), len(xs)
    # if you only  want sx/px:
    print(xs.mean())

    e2 = cv.getTickCount()
    print('average = ' + str((e2-e1) / cv.getTickFrequency()))
    cv.imshow('video', frame)
    if cv.waitKey(10) & 0xFF == ord('q'):
        break
2
Quang Hoang 20 Дек 2019 в 19:04