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

Python模块导入报错:视频人脸提取脚本调用失效排查

Let's work through your issues one by one and get your face extraction app up and running properly:


1. Fixing the TypeError: 'module' object is not callable

The first error happens because you're trying to call the entire extractor module like a function (extractor()) in app.py. Modules aren't callable—you need to call specific functions inside the module instead.


2. Why your core logic isn't executing when imported

Your frame extraction and face detection code is wrapped inside the if __name__ == "__main__" block in extractor.py. This block only runs when you run extractor.py directly (e.g., python extractor.py), not when you import it as a module into app.py. We'll fix this by moving the core workflow into a reusable function.


3. Hidden bugs blocking your functionality

There are a few other issues in extractor.py that are stopping the core features from working:

  • Path mismatch: Your extract_frames function saves frames to the frames/ folder, but your face detection functions are looking for frames in data/—so they can't find any files to process.
  • Multiprocessing argument error: When passing args to multiprocessing.Process, you need to pass a tuple. args=(currentFrame_extract) (a list) will cause a parameter mismatch error for your find_faces_* functions.
  • Redundant code: You have four nearly identical find_faces_* functions—we can simplify this into a single function that takes a starting frame as a parameter.
  • Useless format call: The .format(i) in your save line is unnecessary (you're already using an f-string with currentFrame, and i isn't even used).

Fixed Code

extractor.py

import cv2
import os
import face_recognition
from PIL import Image
import multiprocessing

# Create directories once at module load
for dir_name in ['frames', 'faces']:
    try:
        if not os.path.exists(dir_name):
            os.makedirs(dir_name)
            print(f"Created directory: {dir_name}")
    except OSError as e:
        print(f'Error creating directory {dir_name}: {e}')

def extract_frames(video_file_path):
    currentFrame_extract = 1
    video_capture = cv2.VideoCapture(video_file_path)
    if not video_capture.isOpened():
        print(f"Error: Could not open video file {video_file_path}")
        return 0

    while True:
        ret, frame = video_capture.read()
        if not ret:
            break
        name = f'frames/frame_{currentFrame_extract}.jpg'
        print(f"Extracting Frame {currentFrame_extract}, saving as {name}")
        cv2.imwrite(name, frame)
        currentFrame_extract += 1
    
    video_capture.release()
    cv2.destroyAllWindows()
    return currentFrame_extract - 1  # Return total frames extracted

def process_frames(start_frame, total_frames):
    currentFrame = start_frame
    while currentFrame <= total_frames:
        frame_path = f"frames/frame_{currentFrame}.jpg"
        if not os.path.exists(frame_path):
            print(f"Warning: Frame {currentFrame} not found, skipping")
            currentFrame += 4
            continue
            
        image = face_recognition.load_image_file(frame_path)
        face_locations = face_recognition.face_locations(image)
        
        if face_locations:
            top, right, bottom, left = face_locations[0]
            face_image = image[top:bottom, left:right]
            pil_image = Image.fromarray(face_image)
            face_save_path = f"faces/face_{currentFrame}.jpg"
            pil_image.save(face_save_path)
            print(f"Found face at Frame {currentFrame}, saved to {face_save_path}")
        
        currentFrame += 4

def run_face_extraction(video_file_path):
    total_frames = extract_frames(video_file_path)
    if total_frames == 0:
        print("No frames extracted, exiting")
        return

    # Create processes with correct tuple arguments
    processes = []
    for start in range(1, 5):
        p = multiprocessing.Process(target=process_frames, args=(start, total_frames))
        processes.append(p)
        p.start()

    # Wait for all processes to finish
    for p in processes:
        p.join()

    print("Frame extraction and face detection finished successfully.")

# Keep this for direct execution
if __name__ == "__main__":
    run_face_extraction("Video_3.mp4")

app.py

import extractor

# Call the exposed function from the module
extractor.run_face_extraction("Video_3.mp4")  # Replace with your video path if needed

Key Improvements

  • Reusable function: run_face_extraction is now the public entry point that can be called from app.py.
  • Fixed paths: All frame references now use the frames/ directory.
  • Simplified multiprocessing: Replaced four duplicate functions with a single process_frames function that takes a starting frame parameter.
  • Error handling: Added checks for video file opening and frame existence to catch issues early.
  • Cleaner directory setup: Combined directory creation into a loop to reduce redundancy.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:28:34