'Is there any method to make open-cv run faster using python

I am running GTX 1650 and i5-9300HF and the following code is giving me around 15 to 14 FPS and I need around 30 to 40 I have tried multiple ways but to no avail. I tried to reduce input size but that just drops the accuracy to not usable. I have been at it for days but nothing seems to work. the following is the code

import cv2
import numpy as np
import time


def getFileNames():
    classFile = 'additional Files//coco.names'
    with open(classFile, 'rt') as f:
        classNames = f.read().rstrip('\n').split('\n')
    return classNames

def nnSetup():
    configPath = 'additional Files//ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt'
    weightsPath = 'additional Files//frozen_inference_graph.pb'

    net = cv2.dnn_DetectionModel(weightsPath, configPath)

    return net

thres = 0.58  # Threshold to detect object
nms_threshold = 0.15
cap = cv2.VideoCapture(0)
cap.set(3,1280)
cap.set(4,720)

classNames = getFileNames()

net = nnSetup()
net.setInputSize(320, 320)
net.setInputScale(0.5 / 127.5)
net.setInputMean((127.5, 127.5, 127.5))
net.setInputSwapRB(True)
pTime = time.time()

while True:
    success, img = cap.read()
    classIds, confs, bbox = net.detect(img, confThreshold=thres)
    bbox = list(bbox)
    confs = list(np.array(confs).reshape(1, -1)[0])
    confs = list(map(float, confs))
    indices = cv2.dnn.NMSBoxes(bbox, confs, thres, nms_threshold)

    cTime = time.time()

    fps = 1 / (cTime - pTime)
    pTime = cTime
    print(fps,"FPS")

    for i in indices:

        box = bbox[int(i)]
        x, y, w, h = box[0], box[1], box[2], box[3]
        cenerCords = x+w//2,y+h//2
        if classNames[classIds[int(i)] - 1] == "person":
            cv2.rectangle(img, (x, y), (x + w, h + y), (0, 128, 0), 5)
            cv2.circle(img, cenerCords, 15, (0,0,255), -1)
        else:
            cv2.rectangle(img, (x, y), (x + w, h + y), (255, 0, 0), 5)
            cv2.circle(img, cenerCords, 15, (0,0,255), -1)
            cv2.putText(img,classNames[classIds[int(i)] - 1].upper(),(box[0]+10,box[1]+30),cv2.FONT_HERSHEY_COMPLEX,2,(0,255,0),2)
    if len(indices) != 0 and classNames[classIds[int(i)] - 1] != "person":
        pass
    else:
        pass


    cv2.imshow("Output", img)
    cv2.waitKey(1)


Solution 1:[1]

First, you want higher FPS? change you network to the yolov4 network family. It offers a 'tiny' version (yolov4-tiny.cfg and yolov4-tiny.weights). FPS increase significantly on the expense of precision and accuracy.
Second, you mentioned having a GPU but you didn't say anything about building open-cv with GPU support. please run this:

import wizzi_utils as wu  # pip install wizzi_utils
wu.cvt.test.cuda_on_gpu_test()

If you did build cv with GPU support, it will verify that you did it correctly. If you didn't, there are instruction in the function comments how to do it on windows(on linux it's much easier - just look it up).
Example output on my laptop with no GPU support:

cuda_on_gpu_test:
    * OpenCv Version 4.5.2 - GPU detected ? False
    0 GPU devices detected 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 gilad eini