如何使用多线程来加快速度?

时间:2020-07-31 18:19:02

标签: python multithreading performance

下面的代码将遍历HDD上具有 620,000帧的文件,我正在使用OpenCV的DNN面部检测器提取面部。它可以正常工作,但是每帧大约需要1秒= 172小时。 因此,我想使用多线程来加快速度,但是不确定如何做到这一点。

注意:我的笔记本电脑上有4个CPU内核,硬盘的读写速度约为100 MB / s

文件路径示例:/Volumes/HDD/frames/Fold1_part1/01/0/04541.jpg

frames_path = "/Volumes/HDD/frames"
path_HDD = "/Volumes/HDD/Data"

def filePath(path):
    for root, directories, files in os.walk(path, topdown=False):
        for file in files:
            if (directories == []): 
                pass
            elif (len(directories) > 3):
                pass
            elif (len(root) == 29):
                pass
            else: 
            # Only want the roots with /Volumes/HDD/Data/Fold1_part1/01
                for dir in directories:
                    path_video = os.path.join(root, dir)
                    for r, d, f in os.walk(path_video, topdown=False):
                        for fe in f:
                            fullPath = r[:32]
                            label = r[-1:]
                            folds = path_video.replace("/Volumes/HDD/Data/", "")
                            finalPath = os.path.join(frames_path, folds)
                            finalImage = os.path.join(finalPath, fe)
                            fullImagePath = os.path.join(path_video, fe)
                            try :
                               if (os.path.exists(finalPath) == False):
                                   os.makedirs(finalPath)
                               extractFaces(fullImagePath, finalImage)    
                            except OSError as error:
                               print(error)
                             
    sys.exit(0)

def extractFaces(imageTest, savePath):
    model = "/Users/yudhiesh/Downloads/deep-learning-face-detection/res10_300x300_ssd_iter_140000.caffemodel"
    prototxt = "/Users/yudhiesh/Downloads/deep-learning-face-detection/deploy.prototxt.txt"
    
    net = cv2.dnn.readNet(model, prototxt)
    # load the input image and construct an input blob for the image
    # by resizing to a fixed 300x300 pixels and then normalizing it
    image = cv2.imread(imageTest)
    (h, w) = image.shape[:2]
    blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,(300, 300), (104.0, 177.0, 123.0))
    print(f'Current file path {imageTest}')
   
# pass the blobs through the network and obtain the predictions
    print("Computing object detections....")
    net.setInput(blob)
    detections = net.forward()
   # Detect face with highest confidence
    for i in range(0, detections.shape[2]):
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")
   
        confidence = detections[0, 0, i, 2]
   
   # If confidence > 0.5, save it as a separate file
        if (confidence > 0.5):
            frame = image[startY:endY, startX:endX]
            rect = dlib.rectangle(startX, startY, endX, endY)
            image = image[startY:endY, startX:endX]
            print(f'Saving image to {savePath}')
            cv2.imwrite(savePath, image)

if __name__ == "__main__":
    filePath(path_HDD)


1 个答案:

答案 0 :(得分:0)

设法将时间缩短为每张图像0.09-0.1秒。感谢您提出使用ProcessPoolExecutor的建议。

frames_path = "/Volumes/HDD/frames"
path_HDD = "/Volumes/HDD/Data"

def filePath(path):
    for root, directories, files in os.walk(path, topdown=False):
        for file in files:
            if (directories == []): 
                pass
            elif (len(directories) > 3):
                pass
            elif (len(root) == 29):
                pass
            else: 
            # Only want the roots with /Volumes/HDD/Data/Fold1_part1/01
                for dir in directories:
                    path_video = os.path.join(root, dir)
                    for r, d, f in os.walk(path_video, topdown=False):
                        for fe in f:
                            fullPath = r[:32]
                            label = r[-1:]
                            folds = path_video.replace("/Volumes/HDD/Data/", "")
                            finalPath = os.path.join(frames_path, folds)
                            finalImage = os.path.join(finalPath, fe)
                            fullImagePath = os.path.join(path_video, fe)
                            try :
                               if (os.path.exists(finalPath) == False):
                                   os.makedirs(finalPath)
                               with concurrent.futures.ProcessPoolExecutor() as executor:
                                   executor.map(extractFaces(fullImagePath, finalImage))
                            except OSError as error:
                               print(error)
                             
    sys.exit(0)

def extractFaces(imageTest, savePath):
    model = "/Users/yudhiesh/Downloads/deep-learning-face-detection/res10_300x300_ssd_iter_140000.caffemodel"
    prototxt = "/Users/yudhiesh/Downloads/deep-learning-face-detection/deploy.prototxt.txt"
    
    net = cv2.dnn.readNet(model, prototxt)
    # load the input image and construct an input blob for the image
    # by resizing to a fixed 300x300 pixels and then normalizing it
    image = cv2.imread(imageTest)
    (h, w) = image.shape[:2]
    blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,(300, 300), (104.0, 177.0, 123.0))
    print(f'Current file path {imageTest}')
   
# pass the blobs through the network and obtain the predictions
    print("Computing object detections....")
    net.setInput(blob)
    detections = net.forward()
   # Detect face with highest confidence
    for i in range(0, detections.shape[2]):
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")
   
        confidence = detections[0, 0, i, 2]
   
   # If confidence > 0.5, save it as a separate file
        if (confidence > 0.5):
            frame = image[startY:endY, startX:endX]
            rect = dlib.rectangle(startX, startY, endX, endY)
            image = image[startY:endY, startX:endX]
            print(f'Saving image to {savePath}')
            cv2.imwrite(savePath, image)

if __name__ == "__main__":
    filePath(path_HDD)

相关问题