You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python通过摄像头拍摄护照尺寸证件照

问题描述

我现有一段用Python调用摄像头拍摄图像的代码,但拍出来的图像宽高尺寸太大。能不能把画面调整成护照照片的尺寸,只拍摄头部到肩部的区域?有没有办法实现这个需求?我想要的画面效果和最终成品类似护照照,现有代码如下:

import cv2

key = cv2.waitKey(1)
webcam = cv2.VideoCapture(0)
while True:
    try:
        check, frame = webcam.read()
        print(check)  # prints true as long as the webcam is running
        print(frame)  # prints matrix values of each framecd
        cv2.imshow("Capturing", frame)
        key = cv2.waitKey(1)
        if key == ord('s'):
            cv2.imwrite(filename='saved_img.jpg', img=frame)
            webcam.release()
            img_new = cv2.imread('saved_img.jpg', cv2.IMREAD_UNCHANGED)
            img_new = cv2.imshow("Captured Image", img_new) # SHOWS THE IMAGE AFTER CAPTURING
            cv2.waitKey(1650)
            cv2.destroyAllWindows()
            print("captured images saved")

            break
        elif key == ord('q'):
            print("Turning off camera.")
            webcam.release()
            print("Camera off.")
            print("Program ended.")
            cv2.destroyAllWindows()
            break

    except(KeyboardInterrupt):
        print("Turning off camera.")
        webcam.release()
        print("Camera off.")
        print("Program ended.")
        cv2.destroyAllWindows()
        break
解决方案

完全可以实现,核心思路是在预览和拍摄时锁定/裁剪头肩区域,下面给两种实用方案:

方案1:固定区域裁剪(快速上手)

护照照片标准比例一般是3:4(比如300×400像素),可以在摄像头画面上画一个绿色参考框,提示用户对准,拍摄时直接裁剪框内区域:

修改后的代码:

import cv2

# 定义护照照目标像素尺寸(可按需调整)
PASSPORT_W = 300
PASSPORT_H = 400

webcam = cv2.VideoCapture(0)
# 获取摄像头原始分辨率
cam_w = int(webcam.get(cv2.CAP_PROP_FRAME_WIDTH))
cam_h = int(webcam.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 计算居中的裁剪区域坐标
x_start = (cam_w - PASSPORT_W) // 2
y_start = (cam_h - PASSPORT_H) // 2
x_end = x_start + PASSPORT_W
y_end = y_start + PASSPORT_H

while True:
    check, frame = webcam.read()
    if not check:
        break
    
    # 在预览画面画绿色参考框
    cv2.rectangle(frame, (x_start, y_start), (x_end, y_end), (0, 255, 0), 2)
    cv2.imshow("对准绿色框拍摄", frame)
    
    key = cv2.waitKey(1)
    if key == ord('s'):
        # 裁剪框内区域
        cropped_img = frame[y_start:y_end, x_start:x_end]
        cv2.imwrite('passport_photo.jpg', cropped_img)
        
        webcam.release()
        # 展示成品
        cv2.imshow("拍摄完成", cropped_img)
        cv2.waitKey(2000)
        cv2.destroyAllWindows()
        print("护照照片已保存")
        break
    elif key == ord('q'):
        print("关闭摄像头")
        webcam.release()
        cv2.destroyAllWindows()
        break

webcam.release()
cv2.destroyAllWindows()

方案2:人脸检测自动裁剪(精准适配)

如果想自动定位头肩区域,用OpenCV自带的人脸检测模型就能实现,检测到人脸后扩展区域到头肩范围:

修改后的代码:

import cv2

# 加载OpenCV自带的人脸检测模型
face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 护照照目标比例3:4
TARGET_RATIO = 3/4

webcam = cv2.VideoCapture(0)

while True:
    check, frame = webcam.read()
    if not check:
        break
    
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray, 1.1, 4)
    
    # 检测到人脸时计算头肩区域并画框
    for (x, y, w, h) in faces:
        # 扩展人脸区域:向上加30%高度(头顶),向下加20%高度(肩部)
        top = max(0, int(y - h*0.3))
        bottom = min(frame.shape[0], int(y + h + h*0.2))
        # 根据比例计算宽度并居中
        desired_w = int((bottom - top) * TARGET_RATIO)
        left = max(0, int(x + w//2 - desired_w//2))
        right = min(frame.shape[1], left + desired_w)
        
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
    
    cv2.imshow("对准人脸拍摄", frame)
    
    key = cv2.waitKey(1)
    if key == ord('s'):
        if len(faces) > 0:
            # 裁剪头肩区域并调整到标准尺寸
            cropped_img = frame[top:bottom, left:right]
            cropped_img = cv2.resize(cropped_img, (300, 400))
            cv2.imwrite('auto_passport_photo.jpg', cropped_img)
            print("自动裁剪的护照照片已保存")
        else:
            print("未检测到人脸,请调整位置")
        
        webcam.release()
        cv2.destroyAllWindows()
        break
    elif key == ord('q'):
        print("关闭摄像头")
        webcam.release()
        cv2.destroyAllWindows()
        break

webcam.release()
cv2.destroyAllWindows()

补充说明

  • 固定裁剪方案适合快速实现,需要用户自己对准框内区域
  • 人脸检测方案更智能,能自动适配不同用户的头肩位置,准确率取决于人脸检测的环境(光线、角度等)
  • 可以根据实际护照照片的尺寸要求,修改代码里的像素数值

内容的提问来源于stack exchange,提问作者O JOE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:55:23