图像处理在各种应用中都扮演着至关重要的角色,从面部识别到透视校正。本文将介绍三种使用 Python 和 OpenCV 进行图像处理的基本技术:用于亮度调整的伽马校正、用于透视校正的单应性变换以及使用 Haar 级联分类器进行人脸检测。
如果您对计算机视觉感兴趣,并希望探索有效的图像处理和分析技术,那么本文正适合您。
测试了如下图片:
实现步骤
您可以在这里查看 Python 实现和过程步骤:
import numpy as npimport cv2import globimport os
1. 亮度调整的gamma校正
gamma校正是一种允许对图像亮度进行非线性调整的方法。adjust_gamma()函数使用预先计算的查找表来应用伽马校正。伽马值大于 1会使图像更亮,而伽马值小于 1会使图像更暗。此技术可用于增强低光照条件下的图像或校正过亮的图像。
def adjust_gamma(image, gamma=1.5):"""Adjust the gamma of an input image to control its brightness.Parameters:- image: The input image to process (as a NumPy array).- gamma: The gamma correction value (default is 1.5).A value greater than 1 makes the image brighter,while a value less than 1 makes it darker.Returns:- The gamma-corrected image."""# Calculate the inverse of the gamma valueinvGamma = 1.0 / gamma# Create a lookup table mapping pixel values [0, 255] to their adjusted values# Each value in the table is adjusted using the formula:# new_value = (old_value / 255.0) ** invGamma * 255table = np.array([(i / 255.0) ** invGamma * 255 for i in np.arange(0, 256)]).astype("uint8")# Apply the lookup table to the image to adjust its pixel values# cv2.LUT is used to map the pixel intensities according to the lookup tablereturn cv2.LUT(image, table)
2. 单应变换用于透视校正
transform_homography()函数执行基于单应性的透视校正。它首先使用 Canny 边缘检测器检测边缘,通过轮廓检测识别最大的物体(例如卡片或文档),然后将其扭曲为标准矩形形状。此方法对于文档扫描和校正扭曲图像特别有用。
def transform_homography(image, imgName):"""Applies a homography transformation to an image, adjusting its perspective to a standard rectangular shape. This is useful for correcting distorted perspectives in images, such as cards, documents, or planar surfaces.:param image: The input image in which the homography transformation will be applied.:param imgName: The base name of the image, used for saving intermediate and final results.:return: transformed image"""# Convert the input image to grayscalegray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# Detect edges using the Canny edge detectoredges = cv2.Canny(gray, 50, 150)# Find contours in the edge-detected imagecontours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# Select the largest contour based on areacontour = max(contours, key=cv2.contourArea)# Approximate the contour to reduce the number of pointsepsilon = 0.02 * cv2.arcLength(contour, True)approx = cv2.approxPolyDP(contour, epsilon, True)# Check if at least 4 corners (vertices) were foundif len(approx) >= 4:# Extract corner pointspoints = np.array([point[0] for point in approx], dtype="float32")# Calculate sums and differences of the points' coordinates# to determine their positionss = points.sum(axis=1)diff = np.diff(points, axis=1)# Identify the four corners of the contourtop_left = points[np.argmin(s)]bottom_right = points[np.argmax(s)]top_right = points[np.argmin(diff)]bottom_left = points[np.argmax(diff)]# Arrange the corners in the correct ordersrc_pts = np.array([top_left, top_right, bottom_right, bottom_left],dtype="float32")# Draw the detected contour on the original imagecv2.polylines(image, [src_pts.astype(int)], isClosed=True,color=(0, 255, 0), thickness=3)# Save the image with the contour overlaidcv2.imwrite(f"{imgName}_original_with_contour.jpg", image)# Define the destination points for the homography transformationdst = np.array([[100, 100], # Top-left corner[650, 100], # Top-right corner[650, 650], # Bottom-right corner[100, 650] # Bottom-left corner], dtype="float32")# Compute the homography matrixhomography_matrix, _ = cv2.findHomography(src_pts, dst)# Warp the perspective of the original image using the homography matrixwarped_image = cv2.warpPerspective(image, homography_matrix, (800, 800))# Save the transformed (warped) imagecv2.imwrite(f"{imgName}_transformed_card.jpg", warped_image)return warped_imageelse:# Print a message if not enough corners were foundprint("Failed to find enough corners.")return image
调整图像大小,然后检测轮廓并绘制在图像上:
然后将图像变换为与其边缘平行:
3. 使用 Haar 级联分类器进行人脸检测
detect_face()函数使用 OpenCV 内置的Haar 级联分类器自动从图像中检测并提取人脸。该算法首先将图像转换为灰度图像,然后检测人脸,并将提取的人脸保存为单独的图像。该技术广泛应用于面部识别应用以及人脸图像的预处理,以便进一步分析。
def detect_face(img, imgName):"""Detects and extracts the face from an image using a Haar Cascade classifier for frontal faces.:param img: Input image where faces are to be detected.:param imgName: Base name of the image, used for saving the detected face.:return:"""# Convert the input image to grayscalegray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Load the Haar cascade classifier for face detectionface_classifier = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")# Detect faces in the grayscale image# - `scaleFactor`: Specifies how much the image size is reduced at each image scale.# - `minNeighbors`: Specifies how many neighbors each candidate rectangle should have to retain it.# - `minSize`: Minimum possible object size. Objects smaller than this are ignored.face = face_classifier.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5, minSize=(40, 40))# Get the coordinates and size of the first detected face(x, y, w, h) = face[0]# Crop the face from the original imagecropped_face = img[y:y + h, x:x + w]# Save the cropped face imagecv2.imwrite(f"{imgName}_onlyface_result.jpg", cropped_face)
从图像中检测到的脸部如下所示:
把所有东西放在一起
# Pls specify here the folder of your pictures:image_folder = 'your folder'# Check if the folder existsif not os.path.exists(image_folder):print(f"Error: The specified folder '{image_folder}' does not exist. Please check the path and try again.")else:# Get a list of all .jpg images in the folderimage_files = glob.glob(f"{image_folder}/*.jpg")if not image_files:print(f"Error: No .jpg images found in the folder '{image_folder}'. Please ensure the folder contains .jpg files.")else:# Process all images (in jpg format) in the specified folderfor imgpath in glob.glob(f"{image_folder}/*.jpg"):print(f"Processing of {imgpath} has started.") # Log the start of processingimgname = os.path.splitext(os.path.basename(imgpath))[0] # Extract the image name without extension# Read the image from the given pathimage = cv2.imread(imgpath)# Resize the image to a standard size of 800x800 pixelsimage = cv2.resize(image, (800, 800), interpolation=cv2.INTER_AREA)# Apply gamma correction to enhance brightnessimage = adjust_gamma(image, gamma=1.5)try:# Attempt to apply homography transformationtransformed = transform_homography(image, imgname)except Exception as e:# Log the error if homography transformation failsprint(f"Homography error for image {imgname}: {e}")continue # Skip further processing for this imagetry:# Attempt to detect and crop the face in the transformed imagedetect_face(transformed, imgname)except Exception as e:# Log the error if face detection failsprint(f"Face detection error for image {imgname}: {e}")# Log the completion of processing for the current imageprint(f"Processing of {imgname} has been completed.")
这三种技术是计算机视觉和图像处理的基础。无论您是想增强图像、扫描文档还是检测人脸,OpenCV 和 Python 都能提供强大的工具来高效地完成这些任务。
218