[Reproduced] OpenCV performance measurement and optimization methods (12)

In this tutorial, we talked about the performance measurement and optimization of OpenCV. As we all know, the most important point of the continuous innovation of the algorithm is continuous optimization and optimization, such as the edge detection algorithm we will talk about later, or image segmentation The algorithms, they all progress step by step over time to complete the optimization of the algorithm level. In the future study, we will come into contact with many frameworks. These so-called APIs are fixed. If we simply call these APIs, then we will not be able to make innovations at the algorithm level, and when we want to learn from When writing these algorithms at the principle level, we need to consider its speed and whether it can keep up with the speed of these original APIs.

In this tutorial, we need to touch several functions:

cv.getTickCount()

Return the number of clock cycles after calling this function. Therefore, if you call it before and after the function is executed, you will get the number of clock cycles used to execute the function.

cv.getTickFrequency()

The function returns the frequency of clock cycles, or the number of clock cycles per second.

Now let’s do an experiment. We use a normal Gaussian filter to call the function API in OpenCV. Let’s see how fast it is to call the OpenCV API:

	view plaincopy to clipboardprint?
import cv2  
  
img1 = cv2.imread("01.jpg")  
  
e1 = cv2.getTickCount()  
img1 = cv2.GaussianBlur(img1,(3,3),0)  
e2 = cv2.getTickCount()  
t = (e2 - e1) / cv2.getTickFrequency()  
print(t)  
cv2.imshow("res", img1)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Let's run to see the effect:
Insert picture description here

Insert picture description here

It can be seen that the running speed is very fast. Now we write a Gaussian filter by ourselves and no longer call the official API. Let's see the effect. Of course, this is just an experiment. The specific code is not required to be mastered at present. These are the following What we will learn, let's look at the code:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
import math  
import copy  
  
gauss = np.array([1, 2, 1, 2, 4, 2, 1, 2, 1])  
  
def spilt(a):  
    if a / 2 == 0:  
        x1 = x2 = a / 2  
    else:  
        x1 = math.floor(a / 2)  
        x2 = a - x1  
    return -x1, x2  
    
def gaussian_b0x(a, b):  
    judge = 10  
    sum = 0  
    box = []  
    x1, x2 = spilt(a)  
    y1, y2 = spilt(b)  
    for i in range(x1, x2):  
        for j in range(y1, y2):  
            t = i * i + j * j  
            re = math.e ** (-t / (2 * judge * judge))  
            sum = sum + re  
            box.append(re)  
  
    box = np.array(box)  
    box = box / sum  
    # for x in box :  
    #     print (x)  
    return box   
  
def original(i, j, k, a, b, img):  
    x1, x2 = spilt(a)  
    y1, y2 = spilt(b)  
    temp = np.zeros(a * b)  
    count = 0  
    for m in range(x1, x2):  
        for n in range(y1, y2):  
            if i + m < 0 or i + m > img.shape[0] - 1 or j + n < 0 or j + n > img.shape[1] - 1:  
                temp[count] = img[i, j, k]  
            else:  
                temp[count] = img[i + m, j + n, k]  
            count += 1  
    return temp    
  
def gaussian_function(a, b, img, gauss_fun):  
    img0 = copy.copy(img)  
    for i in range(0, img.shape[0]):  
        for j in range(2, img.shape[1]):  
            for k in range(img.shape[2]):  
                temp = original(i, j, k, a, b, img0)  
                img[i, j, k] = np.average(temp, weights=gauss_fun)  #按权分配  
    return img   
  
img0 = cv2.imread("01.jpg")  
gauss_new = gaussian_b0x(3 , 3)  
e1 = cv2.getTickCount()  
gauss_img = gaussian_function(3, 3, copy.copy(img0), copy.copy(gauss_new))  
e2 = cv2.getTickCount()  
t = (e2 - e1) / cv2.getTickFrequency()  
print(t)  
cv2.imshow("res",gauss_img)  
cv2.waitKey(0)  
cv2.destroyAllWindows() 

Let's look at the operation effect, which is consistent with the effect of the official API:
Insert picture description here

But its running time is unacceptable, and it is as long as 18 seconds:
Insert picture description here

From this we can use these two functions to check whether the algorithm we have written has been optimized enough, and the running time is the best proof.

Default optimization in OpenCV

Many OpenCV functions are optimized using SSE2, AVX, etc. Of course, it also contains unoptimized code. Therefore, if our system supports these features, we should make use of them (almost all modern processors support them). It is enabled by default at compile time, so OpenCV runs optimized code (if enabled), otherwise it runs unoptimized code. We can use cv2.useOptimized() to check if it is enabled/disabled, and use cv2.setUseOptimized() to enable/disable it:

view plaincopy to clipboardprint?
import cv2  
  
print(cv2.useOptimized())  
cv2.setUseOptimized(False)  
print(cv2.useOptimized())  

We can view the output:
Insert picture description here

Now we put it together and look at the speed difference between optimized and unoptimized. Let's first look at the optimized:

	view plaincopy to clipboardprint?
import cv2  
  
img1 = cv2.imread("cat.jpg")  
print(cv2.useOptimized())  # True  
e1 = cv2.getTickCount()  
for i in range(5, 49, 2):  
    img1 = cv2.medianBlur(img1, i)  
e2 = cv2.getTickCount()  
print((e2 - e1) / cv2.getTickFrequency())  

time:

image.png

Let's take a look at the unoptimized effect:

	view plaincopy to clipboardprint?
import cv2  
  
img1 = cv2.imread("cat.jpg")  
cv2.setUseOptimized(False)  
print(cv2.useOptimized())  # False  
e1 = cv2.getTickCount()  
for i in range(5, 49, 2):  
    img1 = cv2.medianBlur(img1, i)  
e2 = cv2.getTickCount()  
print((e2 - e1) / cv2.getTickFrequency()) 

Insert picture description here

Facts have proved that OpenCV's running speed has been improved after the optimization is turned on.

As of this tutorial, the tutorial of the introductory part of OpenCV is over. Starting from the next tutorial, the explanation of the basic part of OpenCV will be carried out.
Check the article summary page https://blog.csdn.net/weixin_44237705/article/details/107864965
More openvino technical information can be exchanged in the group~
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_44237705/article/details/108093556