菜鸟AI - 让提示词生成更简单! 全站导航 全站导航
AI工具安装 新手教程 进阶教程 辅助资源 AI提示词 热点资讯 技术资讯 产业资讯 内容生成 模型技术 AI信息库

已有账号?

首页 > 资讯 > OpenCV实战精选:Gamma校正、单应变换与人脸检测
其他资讯 OpenCV实战精选

OpenCV实战精选:Gamma校正、单应变换与人脸检测

2026-06-04
阅读 0
热度 0
作者 菜鸟AI编辑部
摘要

摘要

图像处理在计算机视觉项目中扮演着基础而关键的角色——无论是人脸识别、透视畸变矫正

图像处理在计算机视觉项目中扮演着基础而关键的角色——无论是人脸识别、透视畸变矫正还是文档数字化,都依赖若干经典算法。本文聚焦 Python 与 OpenCV 生态,详细拆解三种实用技术:Gamma 校正(亮度调节)、单应性变换(透视校正)以及基于 Haar 级联的人脸检测。每段代码都经过验证,可直接复制运行。

基于OpenCV实现Gamma校正、单应变换和人脸检测

如果你正在探索计算机视觉的落地场景,或者需要快速掌握几种高效的处理手段,以下内容能直接帮你上手。

测试用的原始图像如下(每张图均依次经过完整的三步流水线):

实现步骤

流水线分三个阶段:先调整亮度,再纠正透视,最后检测人脸。下面是 Python 核心代码。

import numpy as np
import cv2
import glob
import os

1. 亮度调整的 gamma 校正

Gamma 校正本质上是图像亮度的非线性映射——不是简单加减常数,而是通过幂函数曲线调整像素强度。原理直观:gamma > 1 提亮暗部、整体泛白;gamma < 1 压低亮部、整体偏暗。低光照照片或过曝图像都能靠它修正。下面的 adjust_gamma 函数用查表法(LUT)实现,计算效率高。

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 value
    invGamma = 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 * 255
    table = 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 table
    return cv2.LUT(image, table)

2. 单应变换用于透视校正

拍摄身份证、名片或文档时,角度不正会导致透视畸变。单应变换能将倾斜的四边形“拉”回标准矩形。算法流程:先用 Canny 边缘检测抓轮廓,筛选面积最大的四边形(通常是卡片或纸张),计算其四个角点,再利用单应矩阵执行透视扭曲。下面的 transform_homography 函数输出校正后的图像,并在原图上绘制检测到的轮廓。

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 sa ving intermediate and final results.
    :return: transformed image
    """

    # Convert the input image to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Detect edges using the Canny edge detector
    edges = cv2.Canny(gray, 50, 150)

    # Find contours in the edge-detected image
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL,
                                   cv2.CHAIN_APPROX_SIMPLE)

    # Select the largest contour based on area
    contour = max(contours, key=cv2.contourArea)

    # Approximate the contour to reduce the number of points
    epsilon = 0.02 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, True)

    # Check if at least 4 corners (vertices) were found
    if len(approx) >= 4:
        # Extract corner points
        points = np.array([point[0] for point in approx], dtype="float32")

        # Calculate sums and differences of the points' coordinates
        # to determine their positions
        s = points.sum(axis=1)
        diff = np.diff(points, axis=1)

        # Identify the four corners of the contour
        top_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 order
        src_pts = np.array([top_left, top_right, bottom_right, bottom_left],
                           dtype="float32")

        # Draw the detected contour on the original image
        cv2.polylines(image, [src_pts.astype(int)], isClosed=True,
                      color=(0, 255, 0), thickness=3)

        # Sa ve the image with the contour overlaid
        cv2.imwrite(f"{imgName}_original_with_contour.jpg", image)

        # Define the destination points for the homography transformation
        dst = 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 matrix
        homography_matrix, _ = cv2.findHomography(src_pts, dst)

        # Warp the perspective of the original image using the homography matrix
        warped_image = cv2.warpPerspective(image, homography_matrix, (800, 800))

        # Sa ve the transformed (warped) image
        cv2.imwrite(f"{imgName}_transformed_card.jpg", warped_image)

        return warped_image
    else:
        # Print a message if not enough corners were found
        print("Failed to find enough corners.")
        return image

调整图像尺寸后,检测到的轮廓会绘制在原图上:

然后利用单应矩阵将图像变换为与边缘平行:

3. 使用 Haar 级联分类器进行人脸检测

Haar 级联分类器是 OpenCV 内置的经典人脸检测方案,推理快、无需额外模型。流程:图像转灰度,加载预训练的正脸级联分类器,调用 detectMultiScale 定位人脸框,最后裁出第一个检测到的人脸区域并保存。下面的 detect_face 函数封装了完整过程。

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 sa ving the detected face.
    :return:
    """
    # Convert the input image to grayscale
    gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Load the Haar cascade classifier for face detection
    face_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 ha ve 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 image
    cropped_face = img[y:y + h, x:x + w]

    # Sa ve the cropped face image
    cv2.imwrite(f"{imgName}_onlyface_result.jpg", cropped_face)

从图像中检测到的脸部截取结果如下:

把所有东西放在一起

下面这段主程序遍历指定目录下所有 JPG 图片,每张图先缩放到 800×800,然后依次执行 gamma 校正、单应变换和人脸检测。若某一步出错(如未找到四边形或无人脸),会跳过并打印提示,不影响流程继续。

# Pls specify here the folder of your pictures:
image_folder = 'your folder'

# Check if the folder exists
if 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 folder
    image_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 folder
      for imgpath in glob.glob(f"{image_folder}/*.jpg"):
          print(f"Processing of {imgpath} has started.")  # Log the start of processing
          imgname = os.path.splitext(os.path.basename(imgpath))[0]  # Extract the image name without extension

          # Read the image from the given path
          image = cv2.imread(imgpath)

          # Resize the image to a standard size of 800x800 pixels
          image = cv2.resize(image, (800, 800), interpolation=cv2.INTER_AREA)

          # Apply gamma correction to enhance brightness
          image = adjust_gamma(image, gamma=1.5)

          try:
              # Attempt to apply homography transformation
              transformed = transform_homography(image, imgname)
          except Exception as e:
              # Log the error if homography transformation fails
              print(f"Homography error for image {imgname}: {e}")
              continue  # Skip further processing for this image

          try:
              # Attempt to detect and crop the face in the transformed image
              detect_face(transformed, imgname)
          except Exception as e:
              # Log the error if face detection fails
              print(f"Face detection error for image {imgname}: {e}")

          # Log the completion of processing for the current image
          print(f"Processing of {imgname} has been completed.")

这三项技术构成了计算机视觉的必备工具集。无论你想优化图像对比度、自动矫正文档拍摄角度,还是快速定位人脸,OpenCV 与 Python 的组合都能高效胜任。运行上述代码,就能直观看到每一步的处理效果。

来源:互联网

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

同类文章推荐

相关文章推荐

更多