본문 바로가기
Lecture/OpenCV Master with Python (Beginner)

OpenCV + Python Arithmetic and logical operations

by codingwalks.en 2024. 10. 24.
728x90
반응형

 

 

Hello. This is codingwalks.

In image processing, arithmetic and logical operations are very useful for combining two or more images or modifying specific parts of an image. In this article, we will cover how to apply arithmetic and logical operations between images using OpenCV and Python. This allows you to perform tasks such as image synthesis, brightness and contrast adjustment, and image masking.

 

1. Arithmetic Operations

OpenCV provides various functions to easily perform arithmetic operations such as addition, subtraction, multiplication, and division between two images. You can perform tasks such as combining two images or adjusting the brightness of an image through arithmetic operations. Multiplication or division between two images can be used for tasks such as adjusting the contrast of an image, but it is rarely used, and addition and subtraction are mainly used. Since saturate only expresses the brightness value of an 8-bit image between 0 and 255, if it is out of range, it replaces the value with 0 or 255.

• cv2.add(): Add a constant to the pixel values ​​of an image, or add the pixel values ​​of two images.

\[result(x,y)=saturate(img1(x,y)+constant)\]

\[result(x,y)=saturate(img1(x,y)+img2(x,y))\]

• cv2.subtract(): Subtract a constant to the pixel values ​​of an image, or subtract the pixel values ​​of two images.

\[result(x,y)=saturate(img1(x,y)-constant)\]

\[result(x,y)=saturate(img1(x,y)-img2(x,y))\]

• cv2.multiply(): Multiplies the pixel values ​​of an image by a constant, or multiplies the pixel values ​​of two images.

\[result(x,y)=saturate(img1(x,y)*constant)\]

\[result(x,y)=saturate(img1(x,y)*img2(x,y))\]

• cv2.divide(): Divides the pixel values ​​of an image by a constant or divides the pixel values ​​of two images.

\[result(x,y)=saturate(img1(x,y)/constant)\]

\[result(x,y)=saturate(img1(x,y)/img2(x,y))\]

1.1. Addition and multiplication operations between images and constants

Among the arithmetic operations between images and constants, addition and multiplication operations can be used to easily adjust the brightness and contrast of an image using constants.

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)

# Increase brightness (add constant)
bright_img = np.clip(cv2.add(img, 100), 0, 255).astype(np.uint8)

# Increase contrast (multiply by a constant)
contrast_img = np.clip(cv2.multiply(img, 1.5), 0, 255).astype(np.uint8)

plt.figure(figsize=(15, 4), linewidth=2)

plt.subplot(1, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')

plt.subplot(1, 3, 2)
plt.imshow(bright_img, cmap='gray')
plt.title('Bright Image')
plt.axis('off')

plt.subplot(1, 3, 3)
plt.imshow(contrast_img, cmap='gray')
plt.title('Contrast Image')
plt.axis('off')

# Show plot
plt.tight_layout()
plt.savefig('results/arithmetic.png', dpi=200, facecolor='#eeeeee', edgecolor='black')
plt.show()

original, brightness(+100), contrast(x1.5)

1.2. Addition operation between images

import cv2
import numpy as np

# Load image
img1 = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('resources/baboon.bmp', cv2.IMREAD_GRAYSCALE)

# Resize images (scale to the same size)
img1 = cv2.resize(img1, (512, 512))
img2 = cv2.resize(img2, (512, 512))

# Image addition operation
added_image = np.clip(cv2.add(img1, img2), 0, 255).astype(np.uint8)

cv2.imshow('Added Image', added_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

image's arithmetic operation

1.3. Subtraction operation between images

The subtraction operation between images can be used as image masking. An example that is often used in image processing is the method of masking a specific area using a gradient mask. A gradient mask is a mask in which pixel values ​​gradually change from 0 to 255, which allows you to smoothly process certain areas of an image. To create a gradient mask, you can use the Sigmoid function to create a gradient, and then spread it in a circular shape to create a gradient mask image. If you perform a subtraction operation using the created gradient mask, you can see the result as shown below.

import cv2
import numpy as np

# Load image (convert to black and white image)
img = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)

# Check the image size and create a gradient mask of the same size
height, width = img.shape[:2]

# Set the center coordinates and radius of the circle
center = (width // 2, height // 2)
radius = 200

# Create coordinates for creating gradients
X, Y = np.meshgrid(np.arange(width), np.arange(height))

# # Calculating distance from the center of the image
dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

# Calculating gradient using sigmoid function
scale = 0.05
gradient_mask = 1 / (1 + np.exp(-scale * (dist_from_center - radius)))
gradient_mask = gradient_mask * 255
gradient_mask = gradient_mask.astype(np.uint8)

# Subtraction operation
subtracted_image1 = cv2.subtract(img, gradient_mask)
subtracted_image2 = cv2.subtract(gradient_mask, img)

cv2.imshow('Original Image', img)
cv2.imshow('Gradient Mask', gradient_mask)
cv2.imshow('Subtracted Image1', subtracted_image1)
cv2.imshow('Subtracted Image2', subtracted_image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.subtract

1.4. cv2.addWeighted Arithmetic Operation

The addWeighted() function in OpenCV is a very useful function that can merge two images by applying weights. Using this, you can achieve natural synthesis through linear interpolation between the two images.

\[dst(x,y)=saturate(\alpha \cdot src1(x,y)+\beta \cdot src2(x,y)+\gamma)\]

The function provided in OpenCV is cv2.addWeighted(src1, alpha, src2, beta, gamma).

• src1, src2: Two images to be merged
• alpha: Weight of the first image
• beta: Weight of the second image
• gamma: Additional value to be added to the resulting image (usually 0)

 

import cv2

# Load image
img1 = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('resources/airplane.bmp', cv2.IMREAD_GRAYSCALE)

# Resize images (scale to the same size)
img1 = cv2.resize(img1, (512, 512))
img2 = cv2.resize(img2, (512, 512))

# Merge image weights
blended_image = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)

cv2.imshow('Blended Image', blended_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

blended image

 

2. Logical Operations

The bitwise operations provided by OpenCV are very useful when masking or compositing a specific area in image processing. Logical operations perform operations on each pixel value in bit units, and are generally used when performing operations between images or processing only a specific area using a mask.

• cv2.bitwise_and(): The AND operation \((A \land B)\) returns 1 only when both pixel values ​​of the two images are 1. Otherwise, the result is 0.

\[\text{Result}(x, y) = A(x, y) \land B(x, y)\]

A (pixel value) B (pixel value) A AND B
1 1 1
1 0 0
0 1 0
0 0 0

• cv2.bitwise_or(): The OR operation \((A \lor B)\) returns 1 if either image is 1.

\[\text{Result}(x, y) = A(x, y) \lor B(x, y)\]

A (pixel value) B (pixel value) A OR B
1 1 1
1 0 1
0 1 1
0 0 0

• cv2.bitwise_xor(): The XOR operation \((A \oplus B)\) is 1 when the two values ​​are different. That is, the result is 1 only if A and B are different.

\[\text{Result}(x, y) = A(x, y) \oplus B(x, y)\]

A (pixel value) B (pixel value) A XOR B
1 1 0
1 0 1
0 1 1
0 0 0

• cv2.bitwise_not(): The NOT operation \((\neg A)\) is applied to a single image or pixel, inverting each bit, i.e. 1 becomes 0 and 0 becomes 1.

\[\text{Result}(x, y) = \neg A(x, y)\]

A (pixel value) NOT A
1 0
0 1

 

import cv2
import numpy as np

# Load image (convert to black and white image)
img = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)

# Check the image size and create a gradient mask of the same size
height, width = img.shape[:2]
mask = np.zeros((height, width), dtype=np.uint8)
cv2.circle(mask, (height//2, width//2), 200, 255, -1)
cv2.imshow('Mask', mask)

# Logical operations
bitwise_and = cv2.bitwise_and(img, mask)
bitwise_or = cv2.bitwise_or(img, mask)
bitwise_xor = cv2.bitwise_xor(img, mask)
bitwise_not = cv2.bitwise_not(img, mask)

cv2.imshow('Original Image', img)
cv2.imshow('Bitwise AND', bitwise_and)
cv2.imshow('Bitwise OR', bitwise_or)
cv2.imshow('Bitwise XOR', bitwise_xor)
cv2.imshow('Bitwise NOT', bitwise_not)
cv2.waitKey(0)
cv2.destroyAllWindows()

bitwise results

 

3. Conclusion

In this article, we covered how to perform arithmetic and logical operations between images using OpenCV and Python, and how to merge arrays using addWeighted(). We saw how to adjust the brightness and contrast of an image using arithmetic operations, perform masking operations using logical operations, and use the addWeighted() function to naturally merge two images by applying weights. These techniques are very useful in image processing, and can be easily applied to various editing and compositing tasks.

 

If you found this post useful, please like and subscribe below. ^^

Buy me a coffee

 

[Codingwalks]에게 송금하기 - AQR

[Codingwalks]에게 송금하기 - AQR

aq.gy

★ All contents are referenced from the link below. ★

 

OpenCV: OpenCV-Python Tutorials

Core Operations In this section you will learn basic operations on image like pixel editing, geometric transformations, code optimization, some mathematical tools etc.

docs.opencv.org

728x90
반응형