C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

OpenCVで1

全く更新していなかった・・・実際何もしていなかったです。
(家を建ててから10年経つと、色々な契約等が切れて忙しすぎる。
もっとズレてやって来てくれないかな?)

最近、ちょっとOpenCVに触れたところ少し興味が出てきました。
イヤ深くでは無いです・・・。

Fusion360の図面をエクスポートする場合はPDFになりますよね?
但し、個人ユーザーはNGだとの記憶ですが。

で、図面の違いをOpenCVで・・・と思ったのですがPDFダメっぽいです。
その為、こんな作戦です。

PDF -> 画像の何か -> OpenCV

一応、Fusion360APIでは無く、素のPython(3.11)で行ってみました。
仮想環境下で開発するので、venvで環境を作成した後に以下を
インストール。(ひょっとしたらnumpyは不要かも・・・)

PDFを画像にする為のモジュールを探すと"pdf2image"が
見つかるのですが、他のソフト(?)をインストーラーでインストール
する必要があるっぽいので却下。探した所"PyMuPDF"が
見つかりました。

図面はこちら・・・以前、何かのテストで作ったもので根拠の
無いものです。(根拠のあるものを持っていない・・・)

以下を他サイトを参考にながら作成しました。

import traceback
from pathlib import Path
import fitz
import cv2

def pdf2png(file_path: str) -> str:
    """
    PDFファイルの1ページを画像ファイルに変換する
    """
    path_file = Path(file_path)
    folder_name = path_file.parent
    base_file_name = path_file.stem

    # PDFファイルを開く
    pdf = fitz.open(file_path)

    # 1ページのみ変換
    page = pdf[0]
    pix = page.get_pixmap()
    image_f_name = f'{base_file_name}.png'
    image_f_path = Path(folder_name) / image_f_name
    pix.save(image_f_path)

    return str(image_f_path)


def exec_diff_pic(
        picPath1: str,
        picPath2: str,
):
    """
    二つの画像を比較して、異なる部分に印を付けた画像を作成
    """
    try:
        img1 = cv2.imread(picPath1)
        img2 = cv2.imread(picPath2)

        # グレースケールに変換
        img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
        img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

        # 絶対差を計算
        diff = cv2.absdiff(img1_gray, img2_gray)

        # しきい値を適用して重大な違いを識別する
        thresh = 30
        diff[diff < thresh] = 0
        diff[diff >= thresh] = 255

        # 差の輪郭を見つける
        contours, _ = cv2.findContours(
            diff, 
            cv2.RETR_EXTERNAL, 
            cv2.CHAIN_APPROX_SIMPLE
        )

        # 長方形を描画
        for contour in contours:
            (x, y, w, h) = cv2.boundingRect(contour)
            cv2.rectangle(img1, (x, y), (x + w, y + h), (0, 0, 255), 2)

        cv2.imwrite("diff.png", img1)

        # 表示
        cv2.imshow('Output', img1)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

    except:
        print('Failed:\n{}'.format(traceback.format_exc()))


def main():
    """
    メイン処理
    """
    exec_diff_pic(
        pdf2png("box draw v18.pdf"),
        pdf2png("box draw v19.pdf"),
    )


if __name__ == '__main__':
    """
    エントリーポイント
    """
    main()

結果はこちら

本来なら途中の画像はtempfileで作るべきだろうけど・・・。