Hello. This is codingwalks.
In image processing, adjusting brightness and contrast is a basic but very important process. In particular, brightness and contrast are key elements in photo correction or video quality enhancement. In this article, we will introduce how to adjust the brightness and contrast of an image using OpenCV and Python. This article explains how to adjust brightness and contrast in real time using Trackbar and how to directly manipulate each pixel. Furthermore, we will cover how to adjust contrast and brightness more intuitively at the same time using the cv2.addWeighted function. We will also explain why the BMP format, which is a lossless image file format, is used.
1. Converting color images to grayscale
When processing images, color images (3 channels, RGB) are often converted to grayscale (1 channel). Since grayscale images remove color information and contain only brightness information, they are very useful when analyzing or processing the structural features of an image. In OpenCV, you can easily convert a color image to grayscale using the cv2.cvtColor function.
1.1. Converting directly in the cv2.imread function
The cv2.imread function can use various flags when reading an image. If you use the cv2.IMREAD_GRAYSCALE option among these flags, you can convert the image to grayscale and read it immediately after loading it. This method simplifies the code because you do not need to call cv2.cvtColor separately.
import cv2
# Load image in grayscale
img_gray = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)
cv2.imshow('Gray Image', img_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
This code stores the image in memory as it is already converted to grayscale the moment it is loaded. It is useful when you want to process grayscale images simply because there is no need for a separate conversion process.
1.2. Converting using the cv2.cvtColor function
The cv2.cvtColor function is a function that supports various color space conversions in OpenCV, and is one of the most basic ways to convert from BGR, the color space used by default in OpenCV, to grayscale.
import cv2
# Load a color image
img_color = cv2.imread('resources/lena.bmp')
# Convert color image to grayscale
img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)
cv2.imshow('Gray Image', img_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
This method is suitable for converting an already loaded color image to grayscale on demand, especially when you want to keep the color image while creating a separate grayscale version.
2. Adjusting the brightness of an image
Adjusting the brightness of an image means increasing or decreasing the color value of each pixel by a certain amount. If you increase the brightness, the entire image becomes brighter, and if you decrease it, it becomes darker. At this time, you can implement it by adding or subtracting a certain constant to the RGB value of each pixel. In addition, if the brightness value increases or decreases to become less than 0 or more than 255, it must be processed under the conditions below. The reason is that the byte (unsigned char) data type can only use values from 0 to 255, so saturate(x) processing is required, but it is not required in the case of signed, as an exception.
\[ saturate(x)=\left\{\begin{matrix}
0 & if(x<0) \\
255 & elif(x>255) \\
x & else \\
\end{matrix}\right. \]
The brightness adjustment of an image can be expressed in a formula as follows:
\[ dst(x,y)=saturate(src(x,y)+n) \]
import cv2
import numpy as np
# Load image in grayscale
gray = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)
gray_minus = np.clip(gray-100, 0, 255).astype(np.uint8)
gray_plus = np.clip(gray+100, 0, 255).astype(np.uint8)
result = cv2.hconcat([gray, gray_minus, gray_plus])
cv2.imshow('Brightness Image', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. Adjusting the contrast of an image
Contrast is a measure of the difference between the bright and dark parts of an image. Increasing the contrast makes the bright parts brighter and the dark parts darker, while decreasing the contrast flattens the image and brings it closer to the midtones. Contrast is adjusted by applying a multiplication to the pixel values, and the simplest way to adjust the contrast ratio is to multiply the value of each pixel by a certain ratio. This makes the dark parts of the image darker and the bright parts brighter. This method is expressed in the following formula:
\[ dst(x,y)=saturate(src(x,y)*s) \]
import cv2
import numpy as np
# Load image in grayscale
gray = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)
gray_dec = np.clip(gray*0.5, 0, 255).astype(np.uint8)
gray_inc = np.clip(gray*2.0, 0, 255).astype(np.uint8)
result = cv2.hconcat([gray, gray_dec, gray_inc])
cv2.imshow('Contrast Image', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
4. Brightness and Contrast Control Using cv2.addWeighted Function
The cv2.addWeighted function adjusts the image by applying weights to each of the two images and adding them together. This allows you to implement contrast control through weighted multiplication, and brightness control through constant addition.
\[ dst(x,y)=saturate(src1(x,y)*\alpha + src2(x,y)*\beta + \gamma) \]
import cv2
# Load image in grayscale
gray = cv2.imread('resources/lena.bmp', cv2.IMREAD_GRAYSCALE)
# Contrast and brightness control (increase contrast)
alpha = 1.5 # Contrast ratio
beta = 0.0 # Contrast ratio (0 means no change)
gamma = 50 # Brightness to add
# Adjust brightness and contrast ratio with addWeighted function
adjusted_img = cv2.addWeighted(gray, alpha, gray, beta, gamma)
cv2.imshow('Brightness/Contrast Adjusted', adjusted_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Here we use the same image twice, but we adjust the contrast by applying the \( \alpha \) weight to one image and setting the weight to 0 to the other image. \( \gamma \) is a constant that controls the brightness, and we can adjust its value to control both brightness and contrast at the same time if necessary.
5. Brightness and Contrast Control Using Trackbar in OpenCV
Trackbar is a slider-type UI element provided by OpenCV that allows users to directly control the brightness and contrast of an image in real time. Each value is controlled using the createTrackbar function of OpenCV, and the image can be updated immediately based on the changed values through Trackbar.
5.1. Basic Brightness and Contrast Control
import cv2
import numpy as np
# A function that adjusts the brightness and contrast of an image
def adjust_brightness_contrast(val):
brightness = cv2.getTrackbarPos('Brightness', 'Image') - 50
contrast = cv2.getTrackbarPos('Contrast', 'Image') / 50.0
# Brightness and contrast control
adjusted_img = np.int16(img)
adjusted_img = adjusted_img * contrast + brightness
adjusted_img = np.clip(adjusted_img, 0, 255) # 값 범위를 0-255로 제한
adjusted_img = np.uint8(adjusted_img)
cv2.imshow('Image', adjusted_img)
img = cv2.imread('resources/lena.bmp')
cv2.namedWindow('Image', cv2.WINDOW_AUTOSIZE)
# Create a trackbar (for brightness and contrast adjustment)
cv2.createTrackbar('Brightness', 'Image', 50, 100, adjust_brightness_contrast)
cv2.createTrackbar('Contrast', 'Image', 50, 100, adjust_brightness_contrast)
# Display initial image
adjust_brightness_contrast(0)
while True:
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
- Brightness control: The brightness variable is calculated based on the value selected in the slider. The default value of the trackbar is set to 50, and the range is 0 to 100. The actual brightness control is applied as the result of subtracting 50 from the slider value.
- Contrast control: The contrast variable is set based on the value of the trackbar divided by 50 to 1. The contrast is controlled through a multiplication operation, and the closer the value is to 1, the more similar it is to the original image.
- Pixel value conversion: In the process of adjusting brightness and contrast, the image values are expanded using the np.int16 format, and then the values are restricted to be between 0 and 255 through np.clip.
5.2. Contrast and brightness control using cv2.addWeighted
import cv2
import numpy as np
def adjust_brightness_contrast_addWeighted(val):
brightness = cv2.getTrackbarPos('Brightness', 'Image') - 50
contrast = cv2.getTrackbarPos('Contrast', 'Image') / 50.0
# Adjust brightness and contrast using cv2.addWeighted
adjusted_img = cv2.addWeighted(img, contrast, np.zeros_like(img), 0, brightness)
cv2.imshow('Image', adjusted_img)
img = cv2.imread('resources/lena.bmp')
cv2.namedWindow('Image', cv2.WINDOW_AUTOSIZE)
# Create a trackbar (for brightness and contrast adjustment)
cv2.createTrackbar('Brightness', 'Image', 50, 100, adjust_brightness_contrast_addWeighted)
cv2.createTrackbar('Contrast', 'Image', 50, 100, adjust_brightness_contrast_addWeighted)
# Display initial image
adjust_brightness_contrast_addWeighted(0)
while True:
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
- Contrast Control: The contrast value is applied as a weight to the first image in cv2.addWeighted. The alpha value is used to control the contrast.
- Brightness Control: The gamma value is used to control the brightness of the image, adding a constant to each pixel.
6. Why Use BMP: Importance of Lossless Image Format
There are two types of image file formats: lossy and lossless. JPG and PNG are widely used lossy compression image formats. These lossy compression images remove some image data to reduce the file size when saving, which may result in loss of image quality. Especially in the continuous image processing process, compression is applied every time, which may cause cumulative quality degradation.
On the other hand, BMP (Bitmap) is a lossless compression image format, which retains the original data without compression. Although the file size is much larger than JPG or PNG, it is advantageous to use the BMP format when it is very important to accurately maintain the original data in image processing. This is especially important for deep learning, computer vision, and precise pixel manipulation tasks. Using the BMP format can ensure the quality of the original data, preserving the accuracy and details of the image.
7. Conclusion
In image processing, brightness and contrast adjustment is a basic but very important task. In this article, we explained how to adjust the brightness and contrast of an image using OpenCV and Python. We have seen how to transform images intuitively using real-time adjustable Trackbars, and how to effectively adjust brightness and contrast simultaneously using the cv2.addWeighted function.
We have also explained how to process the structural features of an image more clearly by converting a color image to grayscale. Finally, we have discussed the importance of BMP, a lossless image format, which is essential especially for tasks where maintaining image quality is important.
By making proper use of Trackbar and cv2.addWeighted, and using lossless image formats such as BMP, image processing applications can easily adjust images as desired by users, while maintaining high quality.
If you found this post useful, please like and subscribe below. ^^
★ All contents are referenced from the link below. ★
'Lecture > OpenCV Master with Python (Beginner)' 카테고리의 다른 글
OpenCV + Python Arithmetic and logical operations (0) | 2024.10.24 |
---|---|
OpenCV + Python Histogram Analysis (0) | 2024.10.24 |
OpenCV + Python Angle Measuring Instrument (Practical) (0) | 2024.10.23 |
OpenCV + Python Outputting Unicode Fonts (0) | 2024.10.23 |
OpenCV + Python Handling mouse and keyboard events and utilizing the trackbar (0) | 2024.10.23 |