OpenCV 画像認識 detectMultiScale を実行してプロセスが終了しない

Windows環境、Python で、OpenCV で、画像から顔検出
OpenCV: Face Detection using Haar Cascades

顔認識として、以下から取得したカスケードファイル
opencv/data/haarcascades at master · opencv/opencv · GitHub

haarcascade_frontalface_default.xml 正面を向いた顔の認識用カスケードファイル
haarcascade_eye.xml 瞳を認識するカスケードファイル

(他にも、haarcascade_smile.xml など、笑顔の認識用などあるので参考に)

これで、cv2.CascadeClassifier より、
抽出処理 detectMultiScale を実行すると、処理が終わってもプロセスは停止しない。
OpenCVは、opencv-python 4.5.1.48 を使っている。

良い方法が見つからなかったので、並行処理プロセス multiprocessing で実行させる。
サンプル
cascade というフォルダに検出用のカスケードファイルを置き、
検出対象の画像pahと、検出後、検出部分を四角形で囲んだ画像を書込むpathを指定して実行する
クラスを用意して、multiprocessing で実行、
join(timeout=1) で待ち合わせて、.terminate() で終了させる。

# -*- coding: UTF-8 -*-
import cv2
import multiprocessing

class facecatch():
    def __init__(self):
        face_cascade_path = 'cascade/haarcascade_frontalface_default.xml'
        eye_cascade_path = 'cascade/haarcascade_eye.xml'
        self.face_cascade = cv2.CascadeClassifier(face_cascade_path)
        self.eye_cascade = cv2.CascadeClassifier(eye_cascade_path)
    def catch(self, inpath, out):
        src = cv2.imread(inpath)
        src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
        faces = self.face_cascade.detectMultiScale(src_gray)
        count = 0
        for (x, y, w, h) in faces:
            face = src[y: y + h, x: x + w]
            face_gray = src_gray[y: y + h, x: x + w]
            eyes = self.eye_cascade.detectMultiScale(face_gray)
            if len(eyes) == 2:
                count = count + 1
                cv2.rectangle(src, (x, y), (x + w, y + h), (255, 0, 0), 2)
        if count > 0:
            cv2.imwrite(out, src)
        return count

class Worker(multiprocessing.Process):
    def __init__(self):
        super().__init__()
    def setImagePath(self, imgpath, outpath):
        self.imgpath = imgpath
        self.outpath = outpath
    def run(self):
        self.f = facecatch()
        self.cnt = self.f.catch(self.imgpath, self.outpath)
        print('検出 count = %d' % self.cnt)
        return self.cnt
    def getcount(self):
        return self.cnt

if __name__ == '__main__':
    p = Worker()
    p.setImagePath('data/lena.jpg', 'out/result.jpg')
    p.start()
    p.join(timeout=1)
    p.terminate()
    print('finish !')

このサンプルは、顔の輪郭の中で、瞳を認識(瞳を2個検出)しないと、顔として検出したことにしない方法である。