“This is the 11th day of my participation in the First Challenge 2022. For details: First Challenge 2022”
preface
Image processing technology is the core of computer vision project, usually is the key tool in computer vision project, can be used to complete a variety of computer vision tasks. Therefore, if you want to build computer vision projects, you need to have a good understanding of image processing. Image operation is also a kind of image processing technology. In this article, we will introduce common arithmetic operations that can be performed on images.
Saturated operation
Saturated operation is an arithmetic operation that limits the operation to a fixed range by limiting the maximum and minimum values that the operation can take. For example, some operations on an image (such as interpolation, etc.) may produce values that are out of the available range, which can be solved by using saturation operations. For example, to store the image img, which is the result of a specific operation on an 8-bit image with values ranging from 0 to 255, the saturation operation is calculated as follows: result(x,y)=min(max(round(img),0),255)result(x,y)=min(max(round(img),0),255)result(x,y)=min(max(round(img),0),255) Use the following simple example to better understand:
x = np.uint8([250])
y = np.uint8([50])
# add: 250+50 = 300 => 255:
result_opencv = cv2.add(x, y)
print("cv2.add(x:'{}' , y:'{}') = '{}'".format(x, y, result_opencv))
# Numpy: 250+50 = 300%256 = 44
result_numpy = x + y
print("x:'{}' + y:'{}' = '{}'".format(x, y, result_numpy))
Copy the code
In OpenCV, these values are clipped to the range [0, 255], which is called a saturation operation. In NumPy, values are wrapped around, which is also known as modular operations.
Image addition and subtraction mix with images
Image addition and subtraction can be performed using the cv2.add() and cv2.subtract() functions, respectively. These functions perform element-by-element summation/subtraction of two arrays and can also be used for summing/subtracting arrays and scalars. For example, to add 60 to all pixels of an image, first build the image to add to the original image:
M = np.ones(image.shape, dtype="uint8") * 60
Copy the code
Then, add or subtract using the following code:
added_image = cv2.add(image, M)
subtracted_image = cv2.subtract(image, M)
Copy the code
You can also create a scalar and add it to the original image. For example, to add 110 to all pixels of an image, first build a scalar:
scalar = np.ones((1.3), dtype="float") * 110
Copy the code
Then, add or subtract using the following code:
added_image_2 = cv2.add(image, scalar)
subtracted_image_2 = cv2.subtract(image, scalar)
Copy the code
The code execution result is shown below:
From the figure above, you can clearly see the effect of adding and subtracting predefined values. Image blending is also a kind of image addition, but it can give different weights to the images and achieve a similar effect of transparency. The cv2.addweighted () function can be used for image blending. Next, the Sobel operator is used to observe the effect of the cv2.addweighted () function. The Sobel operator is used for edge detection, which creates an image that detects edges in the graph. The Sobel operator uses two 3 × 3 cores convolved with the original image to compute an approximation of the derivative, capturing both horizontal and vertical gradients:
Output depth is set to CV_16S to avoid overflow
# CV_16S is a channel consisting of 2-byte signed integers (16-bit signed integers)
gradient_x = cv2.Sobel(gray_image, cv2.CV_16S, 1.0.3)
gradient_y = cv2.Sobel(gray_image, cv2.CV_16S, 0.1.3)
Copy the code
Once the horizontal and vertical gradients are calculated, they can be blended into an image using the function cv2.addweighted (), as shown below:
abs_gradient_x = cv2.convertScaleAbs(gradient_x)
abs_gradient_y = cv2.convertScaleAbs(gradient_y)
# Blend the two images with the same weight
sobel_image = cv2.addWeighted(abs_gradient_x, 0.5, abs_gradient_y, 0.5.0)
Copy the code
Finally draw the image:
def show_with_matplotlib(color_img, title, pos) :
img_RGB = color_img[:, :, ::-1]
ax = plt.subplot(1.4, pos)
plt.imshow(img_RGB)
plt.title(title, fontsize=8)
plt.axis('off')
plt.figure(figsize=(10.4))
plt.suptitle("Sobel operator and cv2.addWeighted() to show the output", fontsize=14, fontweight='bold')
show_with_matplotlib(image, "Image".1)
show_with_matplotlib(cv2.cvtColor(abs_gradient_x, cv2.COLOR_GRAY2BGR), "Gradient x".2)
show_with_matplotlib(cv2.cvtColor(abs_gradient_y, cv2.COLOR_GRAY2BGR), "Gradient y".3)
show_with_matplotlib(cv2.cvtColor(sobel_image, cv2.COLOR_GRAY2BGR), "Sobel output".4)
# Show the Figure:
plt.show()
Copy the code
The code looks like this:
Bitwise operations
OpenCV contains operations that can be performed at the bit level using bitwise operators. Bitwise operations are simple and fast, so they are also useful tools for processing images. Bitwise operations include AND, OR, NOT, AND XOR. To demonstrate bitwise operations, let’s first create some images:
img_1 = np.zeros((300.300), dtype='uint8')
cv2.rectangle(img_1, (10.10), (110.110), (255.255.255), -1)
cv2.circle(img_1, (200.200), 50, (255.255.255), -1)
img_2 = np.zeros((300.300), dtype='uint8')
cv2.rectangle(img_2, (50.50), (150.150), (255.255.255), -1)
cv2.circle(img_2, (225.200), 50, (255.255.255), -1)
image = cv2.imread('sigonghuiye.jpeg')
image = cv2.resize(image,(300.300))
img_3 = np.zeros((300.300), dtype="uint8")
cv2.circle(img_3, (150.150), 150, (255.255.255), -1)
Copy the code
The bitwise operation is then performed on the created image:
# OR
bitwise_or = cv2.bitwise_or(img_1, img_2)
# AND
bitwise_and = cv2.bitwise_and(img_1, img_2)
# XOR
bitwise_xor = cv2.bitwise_xor(img_1, img_2)
# NOT
bitwise_not_1 = cv2.bitwise_not(img_1)
bitwise_not_2 = cv2.bitwise_not(img_2)
# AND with mask
bitwise_and_example = cv2.bitwise_and(image, image, mask=img_3)
Copy the code
Display operation result:
Next, we use the real image, further using bitwise operations, and note that the loaded real image should have the same shape:
image = cv2.imread('8.png')
binary_image = cv2.imread('250.png')
image = image[250:500.170:420]
bitwise_and = cv2.bitwise_and(image, binary_image)
bitwise_or = cv2.bitwise_or(image, binary_image)
bitwise_xor = cv2.bitwise_xor(image, binary_image)
Copy the code
The code runs as follows, and you can see the resulting image after performing the bitwise operation: