【问题标题】:Importing other Python scripts as Modules将其他 Python 脚本作为模块导入
【发布时间】:2019-11-19 03:58:27
【问题描述】:

我目前正在尝试编写一个应用程序,将视频分割成单独的帧,然后在视频中找到人脸并将它们提取为 .jpg。我将项目拆分为多个文件,app.py 负责 GUI 等,extractor.py 负责完成工作。

我认为您可以通过以下方式导入文件:

import extractor

然后像这样运行它:

extractor()

显然,这似乎不起作用。我还尝试将整个提取器脚本设为一个函数,然后调用该函数,但这也不起作用。

app.py:

import extractor
extractor()

extractor.py:

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

try:
    if not os.path.exists('frames'):
        os.makedirs('frames')
except OSError:
    print('Error: Creating directory of frames')

try:
    if not os.path.exists('faces'):
        os.makedirs('faces')
except OSError:
    print('Error: Creating directory of faces')

def extract_frames(video_file_path):
    currentFrame_extract = 1
    video_capture = cv2.VideoCapture(video_file_path)

    while(True):
        ret, frame = video_capture.read()
        if ret == False:
            break
        name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
        print(f"Extracting Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
        cv2.imwrite(name, frame)
        currentFrame_extract += 1

    video_capture.release()
    cv2.destroyAllWindows()
    return currentFrame_extract

def find_faces_a(a):
    i = 0
    currentFrame = 1

    while (True):

        if a > currentFrame:

            image = face_recognition.load_image_file(f"data/frame_{currentFrame}.jpg")
            face_locations = face_recognition.face_locations(image)

            if len(face_locations) >= 1:
                top, right, bottom, left = face_locations[0]

                face_image = image[top:bottom, left:right]
                pil_image = Image.fromarray(face_image)
                pil_image.save(f"faces/face_{currentFrame}.jpg".format(i))
                print(f"Found a face at Frame_{currentFrame}, exporting it as Face_{currentFrame}.jpg")

            currentFrame += 4
        else:
            break

def find_faces_b(a):
    i = 0
    currentFrame = 2

    while (True):

        if a > currentFrame:

            image = face_recognition.load_image_file(f"data/frame_{currentFrame}.jpg")
            face_locations = face_recognition.face_locations(image)

            if len(face_locations) >= 1:
                top, right, bottom, left = face_locations[0]

                face_image = image[top:bottom, left:right]
                pil_image = Image.fromarray(face_image)
                pil_image.save(f"faces/face_{currentFrame}.jpg".format(i))
                print(f"Found a face at Frame_{currentFrame}, exporting it as Face_{currentFrame}.jpg")

            currentFrame += 4
        else:
            break

def find_faces_c(a):
    i = 0
    currentFrame = 3

    while (True):

        if a > currentFrame:

            image = face_recognition.load_image_file(f"data/frame_{currentFrame}.jpg")
            face_locations = face_recognition.face_locations(image)

            if len(face_locations) >= 1:
                top, right, bottom, left = face_locations[0]

                face_image = image[top:bottom, left:right]
                pil_image = Image.fromarray(face_image)
                pil_image.save(f"faces/face_{currentFrame}.jpg".format(i))
                print(f"Found a face at Frame_{currentFrame}, exporting it as Face_{currentFrame}.jpg")

            currentFrame += 4
        else:
            break

def find_faces_d(a):
    i = 0
    currentFrame = 4

    while (True):

        if a > currentFrame:

            image = face_recognition.load_image_file(f"data/frame_{currentFrame}.jpg")
            face_locations = face_recognition.face_locations(image)

            if len(face_locations) >= 1:
                top, right, bottom, left = face_locations[0]

                face_image = image[top:bottom, left:right]
                pil_image = Image.fromarray(face_image)
                pil_image.save(f"faces/face_{currentFrame}.jpg".format(i))
                print(f"Found a face at Frame_{currentFrame}, exporting it as Face_{currentFrame}.jpg")

            currentFrame += 4
        else:
            break

if __name__ == "__main__":

    video_file_path = "Video_3.mp4"
    currentFrame_extract = extract_frames(video_file_path)

    currentFrame_extract = [currentFrame_extract]
    p1 = multiprocessing.Process(target=find_faces_a, args=(currentFrame_extract))
    p2 = multiprocessing.Process(target=find_faces_b, args=(currentFrame_extract))
    p3 = multiprocessing.Process(target=find_faces_c, args=(currentFrame_extract))
    p4 = multiprocessing.Process(target=find_faces_d, args=(currentFrame_extract))

    p1.start()
    p2.start()
    p3.start()
    p4.start()

    p1.join()
    p2.join()
    p3.join()
    p4.join()

    print("Frame extraction and alignment finished successfully.")

我收到错误:TypeError: 'module' object is not callable。如果我按照你们中的一些人的建议或标记为“类似”的问题执行此操作,脚本将启动,但它仍然无法工作,只会创建文件夹。

【问题讨论】:

  • 添加完整的回溯。
  • 导入模块时,if __name__ == '__main__' 块之前的所有内容都将被评估。所以所有这些函数都将被定义并添加到extractor 命名空间。试试print(dir(namespace)) 看看我的意思。导入模块后可以调用extractor.find_faces_a(some_object_here)...
  • 完整回溯到底是什么意思?
  • 您好 duhaime,谢谢您的回答。我知道我拥有所有这些单独的功能,但是如何将它们组合成一个,以便当我调用 extractor() 时它只执行整个脚本?问题是 "if name == "main" 对于脚本来说是必不可少的,它应该像我手动运行文件一样运行。

标签: python python-3.x


【解决方案1】:

您可以通过将if __name__ == "__main__": 转换为新函数def extractor() 并导入模块来运行extractor.py

import extractor;
extractor.extractor();

您还可以使用以下导入变体仅导入特定名称(在我们的例子中为 extractor() 函数):

from extractor import extractor;
extractor();

查看此链接 (https://repl.it/repls/MeaslyMerrySymbol),我在其中完成了与您的文件类似的示例导入。

【讨论】:

  • 嗨,我试过这样做。它确实会创建文件夹并执行提取器脚本的启动,但是它不会提取图像也不会搜索人脸。
  • 所以它运行本身不会引发任何错误?如果它抛出错误,粘贴完整的错误消息(5-10 条红线)(也称为回溯)可以让我们更深入地了解可能发生的情况。
  • 是的,只是运行并说“进程完成,退出代码 0”。然而它并没有真正起作用,我认为所有的功能都没有得到执行。就创建文件夹而言,没有任何事情发生。
  • 有什么想法吗?我认为问题在于 name == main 没有启动,并且顶部的功能也没有启动。我真的不明白 name == main 甚至做了什么,但是当我离开它时,脚本不起作用。
【解决方案2】:

将您的提取器功能封装在另一个文件中,例如 extractor_impl。然后将所有内容放在这个文件中的一个函数中:

def extract(video_file_path)
    currentFrame_extract = extract_frames(video_file_path)

    currentFrame_extract = [currentFrame_extract]
    p1 = multiprocessing.Process(target=find_faces_a, args=(currentFrame_extract))
    p2 = multiprocessing.Process(target=find_faces_b, args=(currentFrame_extract))
    p3 = multiprocessing.Process(target=find_faces_c, args=(currentFrame_extract))
    p4 = multiprocessing.Process(target=find_faces_d, args=(currentFrame_extract))

    p1.start()
    p2.start()
    p3.start()
    p4.start()

    p1.join()
    p2.join()
    p3.join()
    p4.join()

    print("Frame extraction and alignment finished successfully.")

然后您可以从您的提取器文件中导入 extractor_impl 文件并调用此函数,但您也可以从其他文件中导入并调用它。

【讨论】:

  • 我试过了,但不幸的是,当我这样做时,脚本的某些部分就被遗漏了。它创建文件夹,但不提取任何图像。
【解决方案3】:

通过extractor.main() 调用它,因为您不必向它传递任何参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2021-09-14
    相关资源
    最近更新 更多