# Opencv之图像算术函数操作及案例与性能测量及优化技术

## 第一部分：Arithmetic Operations on Images

There is a difference between OpenCV addition and Numpy addition. OpenCV addition is a saturated operation while Numpy addition is a modulo operation.

# -*- coding: utf-8 -*-
import cv2
import numpy as np
x = np.uint8([250])
y = np.uint8([10])
print( cv2.add(x,y) ) # 返回的结果为[[255]]   250+10 = 260 => 255
print( x+y )          # 返回的结果为[4]       250+10 = 260 % 256 = 4

### 2、Image Blending

# -*- coding: utf-8 -*-
import cv2
import numpy as np
img1 = cv2.imread('ml-370-649.png')  # machine learning图片，图片大小为：370*649
# 注解，确保两张图片大小一样，不然会报：OpenCV Error: Sizes of input arguments do not match错误
# https://stackoverflow.com/questions/22097513/python-opencv-error-sizes-of-input-arguments-do-not-match
# 数学表达式为：dst=α⋅img1+β⋅img2+γ
cv2.imshow('dst',dst)       #显示图片
cv2.waitKey(0)
cv2.destroyAllWindows()

### 3、Bitwise Operations

This includes bitwise AND, OR, NOT and XOR operations

For example, Below we will see an example on how to change a particular region of an image.

# -*- coding: utf-8 -*-
# I want to put logo on top-left corner, So I create a ROI
rows,cols,channels = img2.shape
print (rows)       # 343
print (cols)       # 280
print (channels)   # 3
roi = img1[0:rows, 0:cols ]
# Now create a mask of logo and create its inverse mask also
img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)  # 该函数的含义还是不懂
print (ret)     # 10
# Now black-out the area of logo in ROI
# Take only region of logo from logo image.
# Put logo in ROI and modify the main image
img1[0:rows, 0:cols ] = dst  # 这函数赋值也不是很懂
cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

## 第二部分：性能测量及优化技术

### 1、Measuring Performance with OpenCV

The number of clock-cycles after a reference event (like the moment machine was switched ON) to the moment this function is called. So if you call it before and after the function execution, you get number of clock-cycles used to execute a function.

The frequency of clock-cycles, or the number of clock-cycles per second. So to find the time of execution in seconds

# -*- coding: utf-8 -*-
# URL:http://docs.opencv.org/3.3.0/dc/d71/tutorial_py_optimization.html
import cv2
import numpy as np
e1 = cv2.getTickCount()
e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()
print (e1)  # 191539511303
print (e2)  # 191539511307
print (time)

# Following example apply median filtering with a kernel of odd size ranging from 5 to 49
e1 = cv2.getTickCount()
for i in xrange(5,49,2):
img1 = cv2.medianBlur(img1,i)
e2 = cv2.getTickCount()
t = (e2 - e1)/cv2.getTickFrequency()
print (e1)      # 192224888475
print (e2)      # 192227071737
print (cv2.getTickFrequency()) # 2531255.0
print (t)       # 0.862521555513

### 2、Measuring Performance in IPython

IPython:一种Python交互式计算和开发环境

C:\Users\Guan>ipython

Python 2.7.11 |Anaconda 4.0.0 (64-bit)| (default, Feb 16 2016, 09:58:36) [MSC v.

1500 64 bit (AMD64)]

IPython 4.1.2 -- An enhanced Interactive Python.

?         -> Introduction and overview of IPython's features.

%quickref -> Quick reference.

help      -> Python's own help system.

object?   -> Details about 'object', use 'object??' for extra details.

In [1]: x=5

In [2]: %timeit y=x**2

10000000 loops, best of 3: 51.4 ns per loop

In [3]: %timeit y=x*x

10000000 loops, best of 3: 50.6 ns per loop

In [5]: import numpy as np

In [6]: z = np.uint8([5])

In [7]: %timeit y=z*z

The slowest run took 34.69 times longer than the fastest. This could mean that a

n intermediate result is being cached.

1000000 loops, best of 3: 456 ns per loop

In [8]: %timeit y=np.square(z)

The slowest run took 20.56 times longer than the fastest. This could mean that a

n intermediate result is being cached.

1000000 loops, best of 3: 461 ns per loop

Tips: Python scalar operations are faster than Numpy scalar operations. So for operations including one or two elements, Python scalar is better than Numpy arrays. Numpy takes advantage when size of array is a little bit bigger.

### 3、Default Optimization in openCV

In [9]: import cv2

In [10]: cv2.useOptimized()

Out[10]: True

In [15]: %timeit res = cv2.medianBlur(img,49)

100000 loops, best of 3: 19.7 us per loop

In [16]: cv2.setUseOptimized(False)

In [17]: cv2.useOptimized()

Out[17]: False

In [18]: %timeit res = cv2.medianBlur(img,49)

100000 loops, best of 3: 19.8 us per loop

### 4、Performance Optimization Techniques

• Avoid using loops in Python as far as possible, especially double/triple loops etc. They are inherently slow.
• Vectorize the algorithm/code to the maximum possible extent because Numpy and OpenCV are optimized for vector operations.
• Exploit the cache coherence.
• Never make copies of array unless it is needed. Try to use views instead. Array copying is a costly operation.