如何修改dlib人脸关键点检测脚本:读取图片替代摄像头流
Hey there! Let's fix this up step by step—first we'll adjust the script to work with local image files, then tackle the URL image issue that's giving you trouble.
一、修改为读取本地图片文件
The original script runs in a loop to grab frames from your webcam, so we just need to swap out the camera input with a local image read, ditch the loop (since we're dealing with a single image), and tweak the display/exit logic.
Here's the updated code:
from imutils import face_utils import dlib import cv2 # 确保预训练模型文件在指定路径下 p = "shape_predictor_68_face_landmarks.dat" detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor(p) # 替换成你的本地图片路径(相对/绝对路径都可以) image_path = "your_face_photo.jpg" # 读取本地图片 image = cv2.imread(image_path) # 先检查图片是否成功读取,避免后续报错 if image is None: print("Error: 找不到图片或者路径有误,请检查!") exit() # 转为灰度图(人脸检测需要灰度图) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 检测图片中的人脸 rects = detector(gray, 0) # 遍历每一张检测到的人脸,绘制关键点 for (i, rect) in enumerate(rects): shape = predictor(gray, rect) shape = face_utils.shape_to_np(shape) # 逐个绘制68个关键点 for (x, y) in shape: cv2.circle(image, (x, y), 2, (0, 255, 0), -1) # 显示处理后的图片 cv2.imshow("Output", image) # 按下任意键就会关闭窗口 cv2.waitKey(0) cv2.destroyAllWindows()
Key changes made:
- Removed the
cv2.VideoCapture(0)webcam setup andwhile Trueloop - Replaced camera frame reads with
cv2.imread()for local files - Added a check to make sure the image loads successfully
- Adjusted the exit logic to wait for any key press instead of the ESC key loop
二、解决URL图片读取失败的问题
You can't use cv2.imread() directly on a URL—it doesn't support network paths. Instead, we need to fetch the image data over the network first, then convert it into a format OpenCV can work with. We'll use the requests library for this (install it first with pip install requests if you haven't already).
Here's the URL-compatible version:
from imutils import face_utils import dlib import cv2 import requests import numpy as np # 预训练模型路径 p = "shape_predictor_68_face_landmarks.dat" detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor(p) # 替换成你要读取的图片URL image_url = "https://example.com/your_target_face_image.jpg" try: # 发送请求获取图片字节数据 response = requests.get(image_url) response.raise_for_status() # 检查请求是否成功(比如404、500错误) # 将字节数据转换成OpenCV能识别的格式 image_array = np.asarray(bytearray(response.content), dtype=np.uint8) image = cv2.imdecode(image_array, cv2.IMREAD_COLOR) if image is None: print("Error: 无法解析URL中的图片,可能是URL无效或者图片格式不支持!") exit() # 后续的人脸检测和关键点绘制逻辑和本地图片一致 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) rects = detector(gray, 0) for (i, rect) in enumerate(rects): shape = predictor(gray, rect) shape = face_utils.shape_to_np(shape) for (x, y) in shape: cv2.circle(image, (x, y), 2, (0, 255, 0), -1) cv2.imshow("Output", image) cv2.waitKey(0) cv2.destroyAllWindows() except requests.exceptions.RequestException as e: print(f"Error: 网络请求失败 - {e}")
Important notes for URL handling:
- We use
requests.get()to fetch the raw image bytes, then convert it to a numpy array before decoding it with OpenCV - Added error handling to catch network issues (like broken URLs, no internet, or server errors)
- If you hit a 403 Forbidden error, try adding a browser-like header to the request (e.g.,
headers={"User-Agent": "Mozilla/5.0"}insiderequests.get()) to bypass basic anti-scraping measures
Quick Extra Tips
- Make sure you have the
shape_predictor_68_face_landmarks.datfile—you can get it from the official dlib model repository if you don't have it - If you need to process multiple images, wrap the detection/drawing logic into a function and loop through your list of file paths/URLs
内容的提问来源于stack exchange,提问作者fightstarr20

