Chapter 3: Image Operations

Image addition and bit operations are relatively basic operations. But many complex image processing functions are completed with the help of these basic operations. For example: bit plane decomposition, image XOR encryption, digital watermarking, etc.

one. Image addition operation:

In image processing, it is often necessary to perform addition operations on images. The image can be added by the plus operator "+", or the image can be added by the cv2.add() function.

  • plus operator "+"
  • cv2.add()

Usually, in grayscale images, pixels are represented by 8 bits (one byte), and the range of pixel values ​​is [0, 255]. When two pixel values ​​are added, the sum is likely to exceed 255. The above two different addition methods have different processing methods for values ​​exceeding 255.

1. Plus operator "+":

Use the plus operator "+" to sum image a (pixel value a) and image b (pixel value b), following the following rules:

a + b = { a + b , a + b ≤ 255 m o d ( a + b , 256 ) , a + b > 255 a+b = \begin{cases} a +b, \quad a+b≤255 \\ mod(a+b, 256), \quad a+b >255 \end{cases} a+b={ a+b,a+b255mod(a+b,256),a+b255

In the formula, mod(): modulo operation mod(a + b, 256) means to calculate the sum of "a+b" and divide it by 256 to get the remainder.

According to the above rules, when two pixels are added:

  • If the sum of the corresponding pixel values ​​of the two images is less than or equal to 255, add them directly to get the operation result. Example: Add 28 and 36 to get 64
  • If the sum of the corresponding pixel values ​​of the two images is greater than 255, the operation result is modulo 256. For example: 255+58 = 313, then the calculated result is (255+58) % 256 = 57.

Example: Simulate a grayscale image using an array of random numbers and observe the result of summing pixel values ​​using "+".

Note: By defining the type of the array as dtype = np.uint8, the range of array values ​​is guaranteed to be between [0, 255]

import numpy as np

img1 = np.random.randint(0, 256, size=[3, 3], dtype=np.uint8)
img2 = np.random.randint(0, 256, size=[3, 3], dtype=np.uint8)

print('img1=\n', img1)
print('img2=\n', img2)
print('img1+img2=\n', img1+img2)

result:

img1=
 [[241  85  79]
 [ 62  29 113]
 [ 33 129 150]]
img2=
 [[168  93 112]
 [ 32 246 228]
 [229  89 107]]
img1+img2=
 [[153 178 191]
 [ 94  19  85]
 [  6 218   1]]

Note : In this example, the modulus of addition is performed by the array type dtype=np.uint8.

2. cv2.add() function:

The function cv2.add() can be used to calculate the sum of image pixel values, the syntax format is:

  • result = cv2.add(a, b)

When using cv2.add() to sum pixel values ​​a and b, follow the following rules: a + b = { a + ba + b ≤ 255 255 a + b > 255 a + b = \begin{cases} a + b \quad a + b≤255 \\ 255 \quad a+b>255 \end{cases}a+b={ a+ba+b255255a+b255

The parameters of cv2.add() have the following three forms:

  • resutl = cv2.add(image 1, image 2): Both parameters are images, and the size and type of images participating in the operation must be consistent
  • result = cv2.add(value, image): the first parameter is a value, and the second parameter is an image. At this time, the value exceeding the saturation value of the image is processed to the maximum value.
  • result = cv2.add(image, value): The first parameter is the image, and the second parameter is the value. At this time, the value exceeding the saturation value of the image will be processed to the maximum value.

Example: Use the plus operator and the function cv2.add() to calculate the sum of the pixel values ​​of two grayscale images.

import cv2
a = cv2.imread('../lena.bmp', 0)
b = a
result1 = a + b
resutl2 = cv2.add(a, b)
cv2.imshow('original', a)
cv2.imshow('result1', result1)
cv2.imshow('result2', resutl2)
cv2.waitKey()
cv2.destroyAllWindows()

insert image description here

It can be seen from the processing results that:

  • Use the plus operator: only the modulus operation will be performed on the sum greater than 255. After the modulus, the part of the value greater than 255 becomes smaller, causing the point that should be brighter to become darker.
  • Use the function cv2.add(): process the value greater than 255 as a saturation value of 255. The pixel value of the image increases, and the image as a whole becomes brighter.

two. image weighted sum:

The so-called image weighted sum is to take the weight of each image into account when calculating the sum of the pixel values ​​of two images, which can be expressed as: dst = saturate ( src 1 × α + src 2 × β + γ ) dst = saturate(src1×\alpha + src2×\beta + \gamma)dst=s a t u r a t e ( s r c 1×a+s r c 2×b+c ) .

In the formula, stautrate() means to take the saturation value. When the image is weighted and calculated, it is required that src1 and src2 must have the same size and type, but there are no special restrictions on the specific type and channel. They can be of any data type and have any number of channels. (grayscale image or color image) as long as they are the same.

The function cv2.addWeighted() is used in OpenCV to realize the weighted sum operation (mixing and fusion) of images.

Grammar format:

  • dst = cv2.addWeighted(src1, alpha, src2, beta, gamma)

    Among them, the parameters alpha and beta are the coefficients corresponding to src1 and src2, and their sum can be equal to 1 or not equal to 1. The function realized by this function is dat = src1 x alpha + src2 x beta + gamma. It should be noted that the parameter gamma in the formula can be 0, but this parameter is mandatory and cannot be omitted. The above formula can be understood as "result = image 1 x coefficient 1 + image 2 x coefficient 2 + brightness adjustment amount"

Example 1: Use an array to demonstrate the use of the function cv2.addWeighted().

import cv2
a = cv2.imread('../lena.bmp')
b = cv2.imread('../boat.512.tiff')
result = cv2.addWeighted(a, 0.6, b, 0.4, 0)
cv2.imshow('lena', a)
cv2.imshow('boat', b)
cv2.imshow('result', result)
cv2.waitKey()
cv2.destroyAllWindows()

insert image description here

three. Bitwise logical operation:

Logic operation is a very important operation method. In the process of image processing, logic operations are often performed according to bits. The following describes bit-by-bit logic operations in OpenCV, referred to as bit operations.

Common bit operation functions in OpenCV:

insert image description here

1. Bitwise AND operation:

In an AND operation, the result is true when both logical values ​​involved in the AND operation are true. Its logical relationship can be compared to the series circuit in the figure below, it will only light up when both switches are closed.

insert image description here

insert image description here

In OpenCV, you can use the cv2.bitwise_and() function to implement bitwise AND operations, and its syntax format is:

  • dst = cv2.bitwise_and(src1, src2[, mask])

In the formula:

  • dst: Indicates the array output value with the same size as the input value
  • src1: Indicates the first input value of array or scalar type.
  • src2: Indicates the input value of the second array or scalar type.
  • mask: Indicates an optional operation mask, an 8-bit single-channel array.

Note: The bitwise AND operation has the following characteristics:

  • Performing a bitwise AND operation on any value N with a value 0 yields the value 0
  • Bitwise ANDing any value N (only 8-bit values ​​are considered here) with the value 255 (1111111 in 8-bit binary) yields the value N itself.

insert image description here

Example 1: Construct a submerged image, using a bitwise AND operation to preserve the portion of the image specified by the mask.

import cv2
import numpy as np
a = cv2.imread('../lena.bmp', 0)
b = np.zeros(a.shape, dtype=np.uint8)
b[100: 400, 200: 400] = 255
b[100: 500, 100: 200] = 255

c = cv2.bitwise_and(a, b)
cv2.imshow('a', a)
cv2.imshow('b', b)
cv2.imshow('c', c)
cv2.waitKey()
cv2.destroyAllWindows()

insert image description here

Note: In addition to masking grayscale images, it is often necessary to use masks to extract specified parts for color images in BGR mode. Since the bitwise AND operation requires the data involved in the operation to have the same channel, it is impossible to directly perform the bitwise AND operation on the color image and the single-channel mask image. In general, the mask operation can be realized by converting the mask image into a color image in BGR mode, and performing a bitwise AND operation on the color image and the mask image

import cv2
import numpy as np
a = cv2.imread('../lena512color.tiff', 1)
b = np.zeros(a.shape, dtype=np.uint8)
b[100: 400, 200: 400] = 255
b[100: 500, 100: 200] = 255

c = cv2.bitwise_and(a, b)
cv2.imshow('a', a)
cv2.imshow('b', b)
cv2.imshow('c', c)
cv2.waitKey()
cv2.destroyAllWindows()

insert image description here

2. Bitwise OR operation:

The rule of the OR operation is that the result is true when either of the two logical values ​​involved in the operation is true. Parallel circuit as shown below:

insert image description here

insert image description here

In OpenCV, you can use the cv2.bitwise_or() function to implement a bitwise OR operation, and its syntax format is:

  • dst = cv2.bitwise_or(src1, src2, [, mask])

In the formula:

  • dst: Indicates the array output value with the same size as the input value
  • src1: Indicates the first input value of array or scalar type.
  • src2: Indicates the input value of the second array or scalar type.
  • mask: Indicates an optional operation mask, an 8-bit single-channel array.

insert image description here

3. Bitwise NOT operation:

The NOT operation is the negation operation:

  • When the operand is true, the result is false;
  • When the operand is false, the result is true

insert image description here

The bitwise NOT operation refers to performing the NOT operation on the corresponding position after converting the value into a binary value.

In OpenCV, the function cv2.bitwise_not() can be used to realize the bitwise inversion operation, and its syntax format is:

  • dst = cv2.bitwise_not(src, [mask])

In the formula:

  • dst: Indicates the array output value with the same size as the input value
  • src1: Indicates the first input value of array or scalar type.
  • mask: Indicates an optional operation mask, an 8-bit single-channel array.

insert image description here

4. Bitwise XOR operation:

XOR operation is also called half-add operation, and its algorithm is similar to addition without binary bits. Its English name is "exclusive OR", so the function is usually expressed as xor

insert image description here

Bitwise XOR operation refers to performing XOR operation on the corresponding position after converting the value into a binary value.

insert image description here

In OpenCV, the function cv2.bitwise_xor() can be used to realize the bitwise inversion operation, and its syntax format is:

  • dst = cv2.bitwise_xor(src1, src2, [mask])

In the formula:

  • dst: Indicates the array output value with the same size as the input value
  • src1: Indicates the first input value of array or scalar type.
  • src2: Indicates the input value of the second array or scalar type.
  • mask: Indicates an optional operation mask, an 8-bit single-channel array.

four. mask:

Many functions in OpenCV will specify a mask, also known as a mask, for example:

result = cv2.add(parameter 1, parameter 2, mask)

When using the mask parameter, the operation will only be performed on the pixels whose mask value is not empty, and set the other pixels to 0.

Example 1:

i m a g e 1 = ∣ 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 ∣ i m a g e 2 = ∣ 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 ∣ m a s k = ∣ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 ∣ image1 = \begin{vmatrix} 3 & 3 & 3 & 3 & 3 \\ 3 & 3 & 3 & 3 & 3 \\3 & 3 & 3 & 3 & 3 \\3 & 3 & 3 & 3 & 3 \\3 & 3 & 3 & 3 & 3 \end{vmatrix} \quad image2 = \begin{vmatrix} 5 & 5 & 5 & 5 & 5 \\ 5 & 5 & 5 & 5 & 5 \\5 & 5 & 5 & 5 & 5 \\5 & 5 & 5 & 5 & 5 \\5 & 5 & 5 & 5 & 5 \end{vmatrix} \quad mask= \begin{vmatrix} 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \\0 & 0 & 0 & 0 & 0 \\0 & 0 & 0 & 1 & 1 \\0 & 0 & 0 & 1 & 1 \end{vmatrix} image1=3333333333333333333333333image2=5555555555555555555555555mask=0000000000000000001100011

Image3 is obtained img3 = cv2.add(img1, img2, mask=mask)after operation:

i m g 3 = ∣ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 8 0 0 0 8 8 ∣ img3= \begin{vmatrix} 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \\0 & 0 & 0 & 0 & 0 \\0 & 0 & 0 & 8 & 8 \\0 & 0 & 0 & 8 & 8 \end{vmatrix} i m g 3=0000000000000000008800088

When calculating, img3 calculates the result of "img1 + img2" under the control of the mask mask. During calculation, the part with mask 1 corresponds to "img1+img2", and the pixel values ​​of other parts are all 0.

Notice:

​ Masks are not only used in image addition operations, but also in other operations such as bit operations.

​ In the previous bit operation, the color original image and the mask image were calculated. Since the bitwise AND operation requires that the data involved in the operation should have the same channel, it is impossible to directly perform the color image and the single-channel mask image. Bitwise AND operation. We need to convert the mask image into a color image in BGR mode, and perform a bitwise AND operation on the color image and the (color) mask image to realize the mask operation.

In fact, the mask parameter used in the function can be an 8-bit single-channel image. Therefore, the mask image can be used as the value of the parameter mask in the bitwise AND function cv2.bitwise_and(src1, src2 [, mask]) to complete the mask operation. At this time, let the color image to be processed be used as the parameters src1 and src2 of the function cv2.bitwise_and(src1, src2 [, mask]) at the same time, use the mask image as the mask parameter, and complete the bitwise AND operation, you can get the mask Color images of membrane controls.

Supplement: Any numerical value and breeding are calculated by bitwise, and the result is still itself.

import cv2
import numpy as np

img1 = cv2.imread('../lena512color.tiff')
w, h, c = img1.shape
mask = np.zeros((w, h), dtype=np.uint8)
mask[100: 400, 200: 400] = 255
mask[100: 500, 100: 200] = 255
img2 = cv2.bitwise_and(img1, img1, mask=mask)
cv2.imshow('img1', img1)
cv2.imshow('mask', mask)
cv2.imshow('img2', img2)
cv2.waitKey()
cv2.destroyAllWindows()

insert image description here

five. Image and numerical operations:

In the above-mentioned addition operation and bitwise operation, even the parameters involved in the operation are the same, and in fact it can be two images, or one image and one value.

For example: If you want to increase the overall brightness of the image, you can add a specific value to each pixel value. During implementation, an image with a uniform pixel value can be added to the image, or a fixed value can be added to the image.

Example 1: The original values ​​of img1 and img2 are:

i m a g e 1 = ∣ 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 ∣ i m a g e 2 = ∣ 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 ∣ image1 = \begin{vmatrix} 3 & 3 & 3 & 3 & 3 \\ 3 & 3 & 3 & 3 & 3 \\3 & 3 & 3 & 3 & 3 \\3 & 3 & 3 & 3 & 3 \\3 & 3 & 3 & 3 & 3 \end{vmatrix} \quad image2 = \begin{vmatrix} 5 & 5 & 5 & 5 & 5 \\ 5 & 5 & 5 & 5 & 5 \\5 & 5 & 5 & 5 & 5 \\5 & 5 & 5 & 5 & 5 \\5 & 5 & 5 & 5 & 5 \end{vmatrix} image1=3333333333333333333333333image2=5555555555555555555555555

  • After img3 = cv2.add(img1, img2) operation, img3 is obtained as:

i m a g e 3 = ∣ 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 ∣ image3 = \begin{vmatrix} 8 & 8 & 8 & 8 & 8 \\ 8 & 8 & 8 & 8 & 8 \\8 & 8 & 8 & 8 & 8 \\8 & 8 & 8 & 8 & 8 \\8 & 8 & 8 & 8 & 8 \end{vmatrix} i m a g e 3=8888888888888888888888888

  • After img4 = cv2.add(img1, 6) operation, img4 is obtained as:

i m a g e 4 = ∣ 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 ∣ image4 = \begin{vmatrix} 9 & 9 & 9 & 9 & 9 \\ 9 & 9 & 9 & 9 & 9 \\9 & 9 & 9 & 9 & 9 \\9 & 9 & 9 & 9 & 9 \\9 & 9 & 9 & 9 & 9 \end{vmatrix} image4=9999999999999999999999999

  • After img5 = cv2.add(6, img1) operation, the obtained img5 is:

i m a g e 5 = ∣ 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ∣ image5 = \begin{vmatrix} 11 & 11 & 11 & 11 & 11 \\ 11 & 11 & 11 & 11 & 11 \\11 & 11 & 11 & 11 & 11 \\11 & 11 & 11 & 11 & 11 \\11 & 11 & 11 & 11 & 11 \end{vmatrix} im a g e 5 _=11111111111111111111111111111111111111111111111111

six. Bit-plane decomposition:

Combine the binary pixels in the same bit in the grayscale image to obtain a new binary image, which is called a bit plane of the grayscale image. This process is called bit-plane decomposition. For example, the "least significant bit" bit plane can be formed by combining the lowest values ​​of all pixels in a grayscale image.

​ In an 8-bit grayscale image, each pixel is represented by 8-bit binary, and its value range is between [0, 255]. The value can be expressed as:

insert image description here

In the formula, ai a_iaimay only be 0 or 1. It can be seen that each ai a_iaiThe weights are not the same, a 7 a_7a7has the highest weight, a 0 a_0a0has the lowest weight. This stands for a 7 a_7a7The value of has the greatest impact on the image, while a 0 a_0a0A value of 0 has the least effect on the image.

By extracting the combination of each bit of the binary pixel value of the grayscale image pixel, multiple bit plane images can be obtained. ai a_i of all pixel values ​​in the imageaiThe bit plane formed by the value is called the i-th bit-plane (i-th layer). In an 8-bit grayscale image, 8 binary images can be composed, that is, the original image can be decomposed into 8 bit planes.

​ According to the above analysis, each ai a_i in the pixel valueaiThe weights are not the same:

  • a 7 a_7 a7has the highest weight, the resulting bit plane has the highest correlation with the original image, and the changed bit plane usually looks the most similar to the original image
  • a 0 a_0 a0With the lowest weight, the resulting bit plane has the least correlation to the original image, and the plane usually looks cluttered.

Bit-plane decomposition can be achieved with the help of bitwise AND operation. For example, there is a grayscale image O whose pixel values ​​are:

insert image description here

Its corresponding binary value is:

insert image description here

ai a_i of all pixelsaiValues ​​are combined to get the 8 bit planes of the image. ah once is a 0 − a 7 a_0 - a_7a0a7

insert image description here

​ For RGB images, if the bit planes corresponding to each channel in the R channel, G channel, and B channel are merged, a new RGB color image can be formed. For example, for an RGB image, the third bit plane of the R channel, the third bit plane of the G channel, and the third bit plane of the B channel are combined to form a new RGB color image. We call this the 3rd bit plane of the original image. Through the above method, the bit plane decomposition of the color image can be completed.

Taking the grayscale image as an example, the specific steps of bit plane decomposition are introduced:

  1. Image preprocessing : read the original image O, get the width M and height N of the original image

  2. Construct the extraction matrix : use the bitwise AND operation to easily extract the number on the specified bit of a value. For example, the figure below uses different extraction factors F to extract specific bits in the value N.
    insert image description here

    According to the above analysis results, it can be established that a value is 2 n 2^n2The Mat of n is used as an extraction matrix for bitwise AND operation with the original image to extract the nth bit plane.

    The values ​​in the extracted matrix Mat can be:
    insert image description here

  3. Extract bitplanes:

    Perform a bitwise AND operation on the grayscale image and the extraction matrix to obtain individual bit planes.

    Compare pixel values ​​with a value of 2 n 2^n2The bitwise AND operation is performed on the value of n , which can ensure that the nth bit of the pixel value remains unchanged, and set the rest of the bits to 0. Therefore, through the bitwise AND operation of the pixel value and the specific value, the value of the specified binary bit of the pixel value can be extracted. Similarly, through bitwise operations, a specified bit plane of an image can be extracted.

    For example, if there is a pixel with a pixel value of 219, it is necessary to extract the value of its 4th binary bit, that is, to extract the 4th bit information of the pixel value (the serial number starts from 0). At this point, the extracted value that needs to be used is " 2 4 2^424 = 16"。
    insert image description here

    For example:

    Extract the bit plane for the image O in the following figure:

    insert image description here

    Its corresponding binary form is:

    insert image description here

    To extract the third bit plane, it is necessary to establish element values ​​of 2 3 2^323 (8) Extraction matrix:

    insert image description here

    Perform a bitwise AND operation on the original image and the extraction matrix to get:
    insert image description here

    Supplement: The extracted bit plane can also be obtained by shifting the binary pixel value to the right by a specified bit, and then modulo 2. For example, to extract the nth bit plane, you can move the pixel to the right by n bits, and then take a modulo 2 to get the nth bit plane.

  4. Thresholding:

    ​ The calculated bit plane is a binary image (that is, 0 value and specific value). If the bit plane obtained above is displayed directly, an approximately black image will be obtained. Because the current display is an 8-bit grayscale image, when the pixel value is small, the displayed image will be approximately black.

    ​ That is to say, after extracting a bit plane every time, if you want to display the binary bit plane in black and white, you need to threshold the obtained binary bit plane, and set the number that is not 0 to 255 .

  5. Display image:

Example: Extract the bit planes of an image.

import cv2
import numpy as np

lena = cv2.imread('../lena.bmp', 0)
cv2.imshow('lena', lena)
r, c = lena.shape
x = np.zeros((r, c, 8), dtype=np.uint8)
for i in range(8):
    x[:, :, i] = 2**i
r = np.zeros((r, c, 8), dtype=np.uint8)
for i in range(8):
    r[:, :, i] = cv2.bitwise_and(lena, x[:, :, i])
    mask = r[:, :, i] > 0
    r[mask] = 255
    cv2.imshow(str(i), r[:, :, i])
cv2.waitKey()
cv2.destroyAllWindows()

insert image description here

seven. Image encryption and decryption:

The encryption and decryption of the image can be realized through the bitwise XOR operation of the image.

Encryption can be realized by bitwise XORing the original image and the key image; decryption can be realized by bitwise XORing the encrypted image and the key image again.

insert image description here

According to the rules of XOR operation, it is assumed that:

  • xor(a, b) = c

Then, you can get:

  • xor(c, b) = a

  • xor(c, a) = b

Example of bitwise XOR process:

insert image description here

From the above results, a, b, c have the following relationship:

  • a: plaintext, raw data
  • b: key
  • c: ciphertext, realized by xor(a, b)

Then the operation of the appeal data can be understood as:

  • Encryption process: Perform bitwise XOR of plaintext a and key b to complete encryption and obtain ciphertext c
  • Decryption process: Perform bitwise XOR of ciphertext c and key b to complete decryption and obtain plaintext a

Bit operation refers to the operation performed on binary bits, and the encryption and decryption of pixels can be realized by using bit operation.

In the process of image processing, the value of the image pixel to be processed is usually a gray value, and its orientation is [0, 255]. For example, if the value of a certain pixel is 216 (plaintext), you can use 178 (this value is defined by the encryptor) as a key to encrypt it, and let the binary values ​​of these two numbers be XORed bit by bit That is, the encryption is completed, and a ciphertext 106 is obtained. When decryption is required, the ciphertext 106 and the key 178 are subjected to a bitwise XOR operation to obtain the value 216 of the original pixel.

  • bit_xor(216, 178) = 106
  • bit_xor(106, 178) = 216

Encryption process:

insert image description here

Decryption process:

insert image description here

Repeat the above operations for each pixel in the image to complete the encryption and decryption operations on the image.

Example: Randomly generate an image as a key to encrypt the original image

import cv2
import numpy as np

lena = cv2.imread('../lena.bmp', 0)
r, c = lena.shape
key = np.random.randint(0, 256, size=[r, c], dtype=np.uint8)
encryption = cv2.bitwise_xor(lena, key)
decryption = cv2.bitwise_xor(encryption, key)
cv2.imshow('lena', lena)
cv2.imshow('key', key)
cv2.imshow('encryption', encryption)
cv2.imshow('decryption', decryption)

cv2.waitKey()
cv2.destroyAllWindows()

insert image description here

eight. digital watermark:

​ The least significant bit value is the 0th bit in the binary value, that is, the lowest bit. Least significant bit information hiding refers to embedding the binary image information that needs to be hidden into the least significant bit of the carrier image, that is, replacing the least significant bit of the carrier image with the current binary image that needs to be hidden, so as to realize binary image hiding the goal of. Since the binary image is in the least significant bit of the carrier, it has no obvious influence on the carrier image and has high concealment.

This information hiding is also known as digital watermarking. In this way it is possible to:

  • information hiding
  • Copyright certification
  • Authentication

and other functions, digital watermark information can be in the form of text, video, audio, etc.

1. Principle:

From the point of view of the bit plane, digital watermarking is divided into the following two parts:

  • Embedding process: Embed digital watermark information (a binary image) into the 0th bit plane of the carrier image.

    For example, a grayscale image is:

    insert image description here

    Its corresponding binary is:

    insert image description here

    There is a grayscale binary image W:

    insert image description here

    Embed a grayscale binary watermark image W in it to get:

    insert image description here

    Since the least significant bit of information has a limited influence on the size of the value, the image will not be significantly transformed and cannot be seen by the naked eye

    In order to facilitate understanding, only the case where the carrier image is a grayscale image is introduced here. In practice, the same watermark can be embedded in multiple channels (to improve robustness), or different watermarks can be embedded in different channels (to improve embedding). quantity), etc.

    • Note: In the actual processing process, the original image and the watermark image can be colored images. At this time, they need to be decomposed by channels and layers first. Then embed the digital watermark into the carrier image.
  • Extraction process: extract the 0th bit plane of the carrier image to obtain the digital watermark.

    The extraction process is the inverse of the embedding process.

2. Implementation method:

The implementation of the lowest finite bit watermark includes the embedding process and the extraction process. The specific implementation method is introduced below:

Embedding process:

  1. Carrier image preprocessing: read the original carrier image, and obtain the row number M and column number N of the carrier image

  2. Create an extraction matrix: Create an extraction matrix with a size of MxN and an element value of 254. Used to extract the upper 7 bits of the image

  3. By bitwise AND operation, the upper 7 bits of the carrier image are extracted, and the lowest bit is set to 0.

  4. Watermark image processing: In some cases, it is necessary to perform simple processing on the watermark image. For example, when the watermark image is a binary image of an 8-bit grayscale image, it needs to be converted into a binary binary image to facilitate embedding it into the The lowest bit of the carrier image.
    insert image description here

  5. Embedding watermark: After the original carrier image is subjected to the operation of "reserve the upper 7 bits and the lowest position is zero", we can get a new image, and perform a bitwise OR operation on the new image and the watermark image to embed the watermark information in the carrier image.

  6. Display image: After the above operations are completed, the original image, watermarked image, and watermarked image can be displayed.
    insert image description here

Extraction process:

  1. Watermarked carrier image processing: read the watermarked carrier image and obtain the size MxN of the watermarked carrier image
  2. Create an extraction matrix: It is recommended to use an extraction matrix with a size of MxN and values ​​of 1.
  3. Extract watermark information: perform bitwise AND operation on the watermark-containing carrier image and the extraction matrix to extract watermark information.
  4. Calculate the carrier image after removing the watermark
  5. display image
    insert image description here

Note: The least significant bit of the pixel value can be obtained by taking the modulo 2 of the pixel value. Therefore, the watermark information of the least significant bit can be obtained by performing modulo 2 on the pixel value.

For example: Embedding and extraction process of simulated digital watermark

import cv2
import numpy as np

lena = cv2.imread('../lena.bmp', 0)
watemark = cv2.imread('../boat.512.tiff', 0)
w = watemark[:, :] > 0
watemark[w] = 1

r, c = lena.shape
t254 = np.ones((r, c), dtype=np.uint8) * 254
lena_h7 = cv2.bitwise_and(lena, t254)
e = cv2.bitwise_or(lena_h7, watemark)
t1 = np.ones((r, c), dtype=np.uint8)
wm = cv2.bitwise_and(e, t1)

w = wm[:, :] > 0
wm[w] = 255
cv2.imshow('lena', lena)
cv2.imshow('watemake', watemark*255)
cv2.imshow('e', e)
cv2.imshow('wm', wm)
cv2.waitKey()
cv2.destroyAllWindows()

Note: The least significant bit of the pixel value can be obtained by taking the modulo 2 of the pixel value. Therefore, the watermark information of the least significant bit can be obtained by performing modulo 2 on the pixel value.

For example: Embedding and extraction process of simulated digital watermark

import cv2
import numpy as np

lena = cv2.imread('../lena.bmp', 0)
watemark = cv2.imread('../boat.512.tiff', 0)
w = watemark[:, :] > 0
watemark[w] = 1

r, c = lena.shape
t254 = np.ones((r, c), dtype=np.uint8) * 254
lena_h7 = cv2.bitwise_and(lena, t254)
e = cv2.bitwise_or(lena_h7, watemark)
t1 = np.ones((r, c), dtype=np.uint8)
wm = cv2.bitwise_and(e, t1)

w = wm[:, :] > 0
wm[w] = 255
cv2.imshow('lena', lena)
cv2.imshow('watemake', watemark*255)
cv2.imshow('e', e)
cv2.imshow('wm', wm)
cv2.waitKey()
cv2.destroyAllWindows()

The content of this article is summarized from the book "OpenCV Easy Getting Started", and you can refer to this book for details.

Guess you like

Origin blog.csdn.net/weixin_57440207/article/details/121103553