[PYTHON] Image capture / OpenCV speed comparison with and without GPU

Overview

Recently, I made a new PC. Before, when I was playing with OpenCV, the fps of image processing was only about 10 fps, and I thought it was subtle, so I will try to find out what it looks like by changing the PC. Next, I will compare the GPU with the GTX1660super and Intel built-in graphics.

I think someone is already doing it, but I couldn't find it, so I'm writing it. Please let me know if there are other articles doing the same thing. I want to read.

environment

PC specifications to be compared

Old PC

New PC-Built-in GPU

New PC-GPU

Cine-bench R20 result

PC Bench results
Old PC 613
New PC-Built-in GPU 4741
New PC-GPU 4839

It doesn't depend on GPU at all.

FFXV_bench 1920 * 1080, standard quality

PC Bench results
Old PC 547:Difficult to operate
New PC-Built-in GPU 708:Difficult to operate
New PC-GPU 8379:comfortable

The memory is barely enough, and it's useless without a GPU.

Image capture bench

Image capture (using mss library)

You can capture screens in a library called mss.

pip install mss

Is required. Get the elapsed time $ [s] $ in a library called time. Compare the time it took to capture the screen 1000 times. I don't know where the bottleneck is. If you loop $ while $ without acquiring the image, it could not be measured at the second level, so the image capture part

sct.grab(monitor)

I think there is no doubt that it takes time.

PC Seconds
Old PC 16.7(60fps)
New PC-Built-in GPU 16.7(60fps)
New PC-GPU 16.7(60fps)

This is expected because the refresh rate of the display connected to the PC is set to 59.94Hz.

capture_test.py


import cv2			#OpenCV library
import numpy as np		#Numpy library
from mss import mss
import time

sct = mss()

"""
For operation check: Comment out after operation check
"""
#windowName = "capture"
#cv2.namedWindow(windowName)

n= 0
while True:
    if n == 0:
        start_time = time.time()
        
    if n>= 1000:  #Repeated 1000 times
        end_time = time.time()
        break
    """
Image acquisition
    """        
    monitor = {"top": 300, "left": 170, "width": 600, "height": 200}
    img = np.array(sct.grab(monitor))
    
    """
Operation check part
    """
    """
    img = img[:,:,0:3]
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    img = np.asarray(img)
    cv2.imshow(windowName,img)
    key = cv2.waitKey(1)
    if key ==ord('q'):                 #end processing
        break
    """
    
    n = n+ 1

cv2.destroyAllWindows()
img[0][0][0] = 1         #If you do not use it even once, I think it will be useless and add it

print(end_time-start_time)

Image capture (using pyautogui library)

Let's try it with the famous library "pyautogui".

PC Seconds
Old PC 68.1(Close to 15fps)
New PC-Built-in GPU 34.1(Close to 30fps)
New PC-GPU 33.4(Close to 30fps)

It may be adjusted to 15,30,60fps, which is a good number according to the performance of the PC. Compared to mss, the load on both GPU and CPU is a little higher. There was almost no effect on the capture range. Since the load factor of any PC has a margin from the upper limit, it is wondering why there is a difference in performance.

However, the 15fps of the old PC is too low to use.

capture_test_pyautogui.py


import cv2			#OpenCV library
import numpy as np		#Numpy library
import pyautogui
import time

"""
For operation check: Comment out after operation check
"""
"""
windowName = "capture"
cv2.namedWindow(windowName)
"""
monitor = {"top": 300, "left": 170, "width": 600, "height": 600}
n= 0
while True:
    if n == 0:
        start_time = time.time()
        
    if n>= 1000:  #Repeated 100 times
        end_time = time.time()
        break
    """
Image acquisition
    """        
    home = pyautogui.screenshot(region=(0,0,600,200))
    img = np.asarray(home)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    
    """
Operation check part
    """
    """
    img = img[:,:,0:3]
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    img = np.asarray(img)
    cv2.imshow(windowName,img)
    key = cv2.waitKey(1)
    if key ==ord('q'):                 #end processing
        break
    """
    
    n = n+ 1

cv2.destroyAllWindows()
img[0][0][0] = 1         #If you do not use it even once, I think it will be useless and add it

print(end_time-start_time)

OpenCV bench List the functions you want to try.

Basically, I want to do image recognition, so it looks like this.

cv2.imshow Since the "same" image is displayed repeatedly, "different images" may give slightly different results. I was greatly influenced by the size of the image. I feel that the CPU load is high


Image size 100 * 100

PC Seconds
Old PC
New PC-Built-in GPU 0.015~0.017
New PC-GPU 0.017

Image size 300 * 300

PC Seconds
Old PC
New PC-Built-in GPU 0.08
New PC-GPU 0.083~0.084

Image size 800 * 800

PC Seconds
Old PC
New PC-Built-in GPU 1.20~1.23
New PC-GPU 1.11~1.13

Image size 2000 * 2000

PC Seconds
Old PC
New PC-Built-in GPU 8.5~8.9
New PC-GPU 8.0~8.2

result

Bench code

opencv_imshow.py


import cv2			#OpenCV library
import numpy as np		#Numpy library
import time

windowName = "capture"
cv2.namedWindow(windowName)

img = np.zeros((2000,2000,3))

n= 0
while True:
    if n == 0:
        start_time = time.time()
        
    if n>= 1000:  #Repeated 100 times
        end_time = time.time()
        break
    
    cv2.imshow(windowName,img)
    """
    #Operation test
    key = cv2.waitKey(1)
    if key ==ord('q'):                 #end processing
        break
    """
    n = n+ 1

cv2.destroyAllWindows()
img[0][0][0] = 1         #If you do not use it even once, I think it will be useless and add it

print(end_time-start_time)

cv2.circle

PC Seconds
Old PC 0.0239~0.0269
New PC-Built-in GPU 0.012
New PC-GPU 0.013

It doesn't seem to be a load at all.

opencv_circle.py


import cv2			#OpenCV library
import numpy as np		#Numpy library
import time

windowName = "capture"
cv2.namedWindow(windowName)

img = np.zeros((500,500,3))

n= 0
while True:
    if n == 0:
        start_time = time.time()
        
    if n>= 1000:  #Repeated 100 times
        end_time = time.time()
        break
    
    cv2.circle(img, (int(n*0.5),50), 10, (0, 0, 255), 4)
    
    """
Operation check part
    """
    """
    cv2.imshow(windowName,img)
    key = cv2.waitKey(1)
    if key ==ord('q'):                 #end processing
        break
    """
    
    
    n = n+ 1

cv2.destroyAllWindows()
img[0][0][0] = 1         #If you do not use it even once, I think it will be useless and add it

print(end_time-start_time)

cv2.matchTemplate This process has the heaviest image. Also, it was strongly influenced by the image size.

PC Seconds taken to run 100 times
Old PC
New PC-Built-in GPU
New PC-GPU 4.413

import cv2			#OpenCV library
import numpy as np		#Numpy library
import time

windowName = "capture"
cv2.namedWindow(windowName)

x = 100
y = 100
depth = 3
img = np.zeros((1000,1000,depth),dtype = np.uint8)
object1 = np.random.randint(0,255,(x,y,depth),dtype = np.uint8)

n= 0
while True:
    if n == 0:
        start_time = time.time()
        
    if n>= 100:  #Repeated 100 times
        end_time = time.time()
        break
    
    img_ccoeff = cv2.matchTemplate(img, object1, cv2.TM_CCOEFF_NORMED)

    n = n+ 1

cv2.destroyAllWindows()

print(end_time-start_time)

Camera capture (camera used is 30fps)

cv2.minMaxLoc

PC Seconds taken to run 1000 times
Old PC
New PC-Built-in GPU
New PC-GPU 0.255

You can see that it hasn't taken any time.

minmaxLoc_bench.py


import cv2			#OpenCV library
import numpy as np		#Numpy library
import time

windowName = "capture"
cv2.namedWindow(windowName)

x = 100
y = 100
depth = 3
img = np.zeros((1000,1000,depth),dtype = np.uint8)
object1 = np.random.randint(0,255,(x,y,depth),dtype = np.uint8)
img_ccoeff = cv2.matchTemplate(img, object1, cv2.TM_CCOEFF_NORMED)

n= 0
while True:
    if n == 0:
        start_time = time.time()
        
    if n>= 1000:  #Repeated 100 times
        end_time = time.time()
        break
    
    cMin, cMax1, pMin, pMax1 = cv2.minMaxLoc(img_ccoeff)
    n = n+ 1

cv2.destroyAllWindows()

print(end_time-start_time)

I'm sorry. Since dbd was so much fun that it wasn't so much, I'll publish it for now and update it when I can afford it.

Recommended Posts

Image capture / OpenCV speed comparison with and without GPU
XavierNX accelerates OpenCV image processing with GPU (CUDA)
With and without WSGI
Image editing with python OpenCV
Camera capture with Python + OpenCV
Get image features with OpenCV
Image recognition with Keras + OpenCV
BASIC and C and assembler speed comparison and optimization play with IchigoJam
Build GPU environment with GCP and kaggle official image (docker)
Shining life with Python and OpenCV
Automatic image interpolation with OpenCV and Python (Fast Marching Method, Navier-Stokes)
Speed comparison of Wiktionary full text processing with F # and Python
Neural network with OpenCV 3 and Python 3
[Python] Using OpenCV with Python (Image transformation)
Image segmentation with scikit-image and scikit-learn
Speed comparison between CPython and PyPy
Find image similarity with Python + OpenCV
Try blurring the image with opencv2
Draw shapes with OpenCV and PIL
Read the graph image with OpenCV and get the coordinates of the final point of the graph
Image processing with Python & OpenCV [Tone Curve]
Image acquisition from camera with Python + OpenCV
Light image processing with Python x OpenCV
Image processing with Lambda + OpenCV (gray image creation)
Speed comparison of murmurhash3, md5 and sha1
I tried "smoothing" the image with Python + OpenCV
Performance comparison of face detector with Python + OpenCV
I tried "differentiating" the image with Python + OpenCV
Generate and post dummy image data with Django
How to crop an image with Python + OpenCV
Install OpenCV 4.0 and Python 3.7 on Windows 10 with Anaconda
I tried "binarizing" the image with Python + OpenCV
[Small story] Test image generation with Python / OpenCV
Wavelet transform of images with PyWavelets and OpenCV
Data cleansing 3 Use of OpenCV and preprocessing of image data
Feature matching with OpenCV 3 and Python 3 (A-KAZE, KNN)
Speed comparison between incrementing count variable and enumerate
Create a High Dynamic Range Image (HDR) with OpenCV and Python (Mertens, Robertson, Debevec)
A memo that detects and returns an image acquired from a webcam with Django's OpenCV