今回は、OpenCVの顔検出データセットで、画像から顔を検出して、顔のみをInDesignに配置する記事です。
実用性:Zero
言いたいこと:コードを簡潔(=今後のメンテナンス)にするため:
・組版のjavascript(今回はappscriptで)に、組版部分のみ書く
・組版以外のデータ処理、Pythonのような言語に任せる(今回の例だと、顔の矩形座標検出処理は、10行程度しかない)
OpenCVのインストール:pip install opencv-python
使い方:
- InDesign(例はCC2019)に画像を配置、選択
- プログラム実行
- 新規documentが作成され、その中に顔のみが表示
import os import cv2 # pip install opencv-python from appscript import * # 顔検出haarcascade frontalface = os.path.join(cv2.data.haarcascades, "haarcascade_frontalface_default.xml") cascade = cv2.CascadeClassifier(frontalface) def get_face_rects(input_img, scaleFactor): image = cv2.imread(input_img) height, width = image.shape[:2] faces = cascade.detectMultiScale(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), scaleFactor=scaleFactor, # 顔検出精度 minNeighbors=2, minSize=(30, 30)) if len(faces) == 0: print("No faces detected.") return [], 0, 0 """ # draw red rectangles and save image color = (0, 0, 255) # B,G,R !! for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x + w, y + h), color, thickness=2) cv2.putText(image, text=f"scaleFactor={scaleFactor}", org=(100, 50), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(255, 0, 0)) cv2.imwrite(f"__{scaleFactor}_rectangles_".join( os.path.splitext(input_img)), image) """ return faces, width, height def get_img_path_from_indesign(): # get currently selected obj in InDesign sel = indd.selection()[0] # javascript: app.selection[0] if sel.class_() == k.image: # convert "Direct Selection" to "selection" sel.parent.select() sel = indd.selection()[0] graphic = sel.graphics[1] img_path = graphic.item_link.file_path() # colon delimited(on the Mac OS) return img_path.replace("Macintosh HD", "").replace(":", "/") indd = app("Adobe InDesign CC 2019") img_path = get_img_path_from_indesign() rects, width, height = get_face_rects(img_path, scaleFactor=1.1) if len(rects) != 0: indd.copy() # copy currently selected obj doc = indd.make(new=k.document) for rect in rects: indd.paste() # paste copied obj new_img = doc.selection()[0] new_img.fit(given=k.frame_to_content) # show whole image new_img.move(to=[0, 0]) # height/width (any indesign unit) indd_height, indd_width = new_img.geometric_bounds()[2:] # convert pixel unit to percentage x1, x2 = rect[0] / width, (rect[0] + rect[2]) / width y1, y2 = rect[1] / height, (rect[1] + rect[3]) / height # convert percentage to indesign unit new_img.geometric_bounds.set([y1 * indd_height, x1 * indd_width, y2 * indd_height, x2 * indd_width])因みに、顔検出の精度引数scaleFactorを1.09/1.3にしたら、大分違ってくる:
get_face_rects(img_path, scaleFactor=1.09) get_face_rects(img_path, scaleFactor=1.3)