OpenCV-Python image addition operation cv2.add function detailed explanation

☞ ░ to the old ape Python Bowen directory

1. Overview of addition

Image addition has two main uses. One is to reduce or even eliminate the noise mixed in the image acquisition. Since the acquisition noise of each point of the image is not correlated with each other, and the noise has the statistical characteristics of zero mean, the image can be processed Collect multiple images to form multiple images, and then add these multiple images and take the average value to achieve noise elimination; the other is to make special effects, superimpose multiple images together, and then perform further processing.

The addition operation of opencv is the addition of two images or an image and a scalar (a scalar is a single value). For the addition of two images, it is required that the size of the two or more added images should be the same. When processing, the gray value of the pixel at the same position of the two images (gray image) or each channel value of the color pixel (color image) ) Add separately; when adding an image to a scalar, the channel values ​​of all pixels of the image are added to the scalar respectively.

2. Grammar introduction

Calling syntax:

add(src1, src2, dst=None, mask=None, dtype=None)

Parameter Description:
  1. src1, src2: two images of equal size and number of channels or one image and a scalar (a scalar is a single value) to be added
  2. dst: optional parameter, the variable for saving the output result, the default value is None, if it is not None, the output image is saved to the corresponding actual parameter of dst, and its size and number of channels are the same as the input image, and the depth of the image (that is, the image pixel Digits) confirmed by dtype parameter or input image
  3. mask: Image mask, optional parameter, 8-bit single-channel grayscale image, used to specify the elements of the output image array to be changed, that is, the output image pixels are output only when the corresponding position element of the mask is not 0, otherwise All channel components of the pixel at this position are set to 0
  4. dtype: optional parameter, the depth of the output image array, that is, the number of bits of a single pixel value of the image (if RGB is represented by three bytes, it is 24 bits).
  5. Return value: the result image of the addition

Three, three scenarios of addition operation processing

  1. Two image arrays of the same size and number of channels are added together
    dst(I)=saturate(src1(I)+src2(I))if mask(I)≠0
    , that is, each pixel of the target image. When the value of the corresponding position of the mask is not 0, the value of each channel of the pixel is equal to the pixel channel of the same position of src1 and src2 Values ​​are added (saturated). For understanding of saturate and src1(I), please refer to " opencv image processing learning essay: the meaning of saturate in the calculation formula of the help document "

  2. An image array and a scalar are added
    dst(I)=saturate(src1(I)+src2)if mask(I)≠0
    to each pixel of the target image. When the value of the corresponding position of the mask is not 0, the value of each channel of the pixel is equal to the value of each channel and the scalar of each pixel of the src1 image Add each value (digitized constant will be converted into a four-tuple representing BGRA, the first element is the number value, other elements are 0; if it is a four-tuple, add them separately. The same below)

  3. The addition of a scalar and an image array
    dst(I)=saturate(src1+src2(I))if mask(I)≠0
    is each pixel of the target image. When the value of the corresponding position of the mask is not 0, the value of each channel of the pixel is equal to the value of each channel and the scalar of each pixel of the src2 image Add up

Regarding the latter two scenarios, in the OpenCV documentation, a scalar can also use a variable with the number of elements equal to the number of channels of the image array corresponding to another parameter (for example, for scenario 3, opencv describes it like this: "Sum of a scalar and an array when src1 is constructed from Scalar or has the same number of elements as src2.channels()”). The old ape didn’t understand this, and related tests (for example, for a three-channel image, the scalar was replaced by a triple or a list of three elements) did not work. After discussing with some experts in CSDN and verification tests, it was found that it was replaced with Quadruples can be, such as:

>>> import cv2
>>> imgBeauty = cv2.imread(r'F:\pic\beauty.jpg')
>>> img = imgBeauty[0:5, 0:5]
>>> 
>>> import cv2
>>> import numpy as np
>>> imgBeauty = cv2.imread(r'F:\pic\beauty.jpg')
>>> img = imgBeauty[0:5, 0:5]
>>> mask = np.zeros([5, 5], dtype=np.uint8)
>>> cv2.add(img,(1,1,1,1))
array([[[231, 226, 225],
        [231, 226, 225],
        [231, 226, 225],
        [230, 225, 224],
        [228, 223, 222]],

       [[232, 227, 226],
        [231, 226, 225],
        [231, 226, 225],
        [231, 226, 225],
        [230, 225, 224]],

       [[232, 227, 226],
        [232, 227, 226],
        [232, 227, 226],
        [232, 227, 226],
        [231, 226, 225]],

       [[231, 226, 225],
        [232, 227, 226],
        [232, 227, 226],
        [232, 227, 226],
        [231, 226, 225]],

       [[232, 227, 226],
        [233, 228, 227],
        [232, 227, 226],
        [232, 227, 226],
        [231, 226, 225]]], dtype=uint8)

I personally think this is because OpenCV enforces four-channel color image processing.

Remarks : The problem of scalar has been solved in the following article " OpenCV-Python Commonly Used Image Operations: Addition, Subtraction, Multiplication, and Division, Logarithm and Bit Operations ".

Four, some special scene cases

Some content in the OpenCV documentation is not very clear, let's do some tests to verify it.

4.1. Does the addition allow both input images to be scalar?

It is introduced in the document that src1 and src2 can be two image arrays, or one image array and one scalar, so whether both can be scalars. The verification code is as follows:

>>>import numpy as np
>>>import cv2
>>>img = cv2.add(1,2)
>>> img
array([[3.],
       [0.],
       [0.],
       [0.]])
>>> img.shape
(4, 1)

It can be seen that both are allowed to be scalars, but the output result is a two-dimensional array. Why are the four elements? Lao Yuan believes that OpenCV forces the scalar to be converted to the BGRA four-channel component for processing.

4.2. Use of mask

The mask has already been explained more clearly, and an example will give a better understanding. Sample code:

>>> imgBeauty = cv2.imread(r'F:\pic\beauty.jpg')
>>> img = imgBeauty[0:5, 0:5]
>>> img
array([[[230, 225, 224],
        [230, 225, 224],
        [230, 225, 224],
        [229, 224, 223],
        [227, 222, 221]],

       [[231, 226, 225],
        [230, 225, 224],
        [230, 225, 224],
        [230, 225, 224],
        [229, 224, 223]],

       [[231, 226, 225],
        [231, 226, 225],
        [231, 226, 225],
        [231, 226, 225],
        [230, 225, 224]],

       [[230, 225, 224],
        [231, 226, 225],
        [231, 226, 225],
        [231, 226, 225],
        [230, 225, 224]],

       [[231, 226, 225],
        [232, 227, 226],
        [231, 226, 225],
        [231, 226, 225],
        [230, 225, 224]]], dtype=uint8)
>>> mask = np.zeros([5, 5], dtype=np.uint8)
>>> mask[1]=[1,0,-1,1,0]
>>> mask[2] = [-2, -1, 0, 1, 2]
>>> mask
array([[  0,   0,   0,   0,   0],
       [  1,   0, 255,   1,   0],
       [254, 255,   0,   1,   2],
       [  0,   0,   0,   0,   0],
       [  0,   0,   0,   0,   0]], dtype=uint8)
>>> dest = np.zeros([5, 5, 3], dtype=np.uint8)
>>> img2 = cv2.add(img, img, mask=mask, dst=dest)
>>> img2
array([[[  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0]],

       [[255, 255, 255],
        [  0,   0,   0],
        [255, 255, 255],
        [255, 255, 255],
        [  0,   0,   0]],

       [[255, 255, 255],
        [255, 255, 255],
        [  0,   0,   0],
        [255, 255, 255],
        [255, 255, 255]],

       [[  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0]],

       [[  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0]]], dtype=uint8)
>>> img2 is dest
True

From the above execution case, we can see:
① After the addition of img and img itself, when the mask parameter is executed, only the pixel value whose mask is not 0 is reserved, and other values ​​are set to 0
②, because each img The single channel value of the pixel is relatively large, resulting in img+img, the value of each channel is set to 255, which is the result of saturated addition
③, the return value of the addition is the object specified by the dst parameter

4.3, about the parameter dtype

In the help document, the parameters src1 and src2 can have different image depths (that is, the number of image pixels, such as 8-bit, 16-bit, 24-bit and 32-bit). For example, a 16-bit image and an 8-bit image can be added Save the output result in a 32-bit output array.

The old ape didn’t understand this. If the depth of the image is different, it means that the number of channels of the image is different, and the number of channels is different, which means that the size of the array is different, and the two arrays cannot be added. Some tests have not been able to verify this description. Under normal circumstances, it is not necessary to use it in this way, so let's leave it in doubt.

Remarks : The problem of dtype has been solved in the following article " OpenCV-Python Commonly Used Image Operations: Addition, Subtraction, Multiplication, and Division, Logarithm and Bit Operation ".

4.4. About addition arithmetic expressions

For the addition of two image arrays of the same size and number of channels in the above-mentioned addition scene, the formula is:
dst(I)=saturate(src1(I)+src2(I))if mask(I)≠0

The opencv document introduces that the above functions can be replaced by matrix expressions. The replaced matrix expressions are as follows:
dst = src1 + src2

However, Lao Yuan tested this and found that opencv-python performed the addition as a pure matrix operation, and did not perform the opencv-python add addition, because the addition result did not perform saturated addition. Therefore, this statement is incorrect at least in opencv-python. In opencv-python, image addition is to be performed or the add function is called.

Five, addition operation case

There are two pictures below. The first picture is a collection of several pictures commonly used in image processing. The picture name is imgs.jpg. The corresponding pictures are as follows: The
Insert picture description here
second picture is a background picture and the picture name is bkground.jpg:
Insert picture description here

We add the two pictures. code show as below:

import numpy as np
import cv2

def  main():
    img1 = cv2.imread(r'F:\pic\imgs.png')
    img2 = cv2.imread(r'F:\pic\bkground.jpg')
    print(img1.shape,img2.shape)
    mask = np.zeros(img1.shape[0:2], dtype=np.uint8)
    mask[0:100,0:100] = 1
    imgNomask = cv2.add(img1, img2)
    imgMask = cv2.add(img1, img2,mask=mask)
    cv2.imshow('imgNomask',imgNomask)
    cv2.imshow('imgMask', imgMask)
    cv2.waitKey(0)
    
main()

Run display picture:
Insert picture description here

Insert picture description here

Six, summary

This section describes in detail the role of OpenCV-Python addition, the grammatical call of the arithmetic function add, the use of parameters, and the processing of different input scenarios for addition. It also explains and verifies some details that are not specified in the OpenCV official documents. It also provides code samples for image addition processing.

For more information about OpenCV-Python, please refer to the related article in the column " OpenCV-Python Graphics and Image Processing ".

Paid column about the old ape

Lao Yuan’s paid column " Developing Graphical Interface Python Applications Using PyQt " specifically introduces the basic tutorials of PyQt graphical interface development based on Python, and the paid column " Moviepy Audio and Video Development Column " details the related methods and usage of moviepy audio and video editing and synthesis processing Method to process related editing and synthesis scenes. Both columns are suitable for novice readers who have a certain Python foundation but no relevant knowledge.

Paid column article catalog : " Moviepy audio and video development column article directory ", " Use PyQt to develop graphical interface Python application column directory ".

For those who lack Python foundation, you can learn Python from scratch through Lao Yuan’s free column " Column: Python Basic Tutorial Directory ".

If you are interested and willing to support the readers of Old Ape, welcome to buy paid columns.

Learn Python and OpenCV from the old ape!

☞ ░ to the old ape Python Bowen directory

Guess you like

Origin blog.csdn.net/LaoYuanPython/article/details/109016144