Gemini でプログラミング学習 #2 OpenCV でモザイク処理

現在、Pythonを勉強中です。 また、生成AIも習うより慣れよと出来る限り使って経験値を高めようとしています。 ということで Gemini を教師として Python のプログラミングを学習していく過程をブログに残していきます。

今回は前回作ったWebカメラの画像を出力するプログラムについて、出力画像にモザイクをかけるという処理を追加しようと考えています。 前回は手動で Windows ペイント使ってモザイクっぽくしたのですが毎回実施するのは面倒ということもあり。

Gemini に教えてもらう

bigriver.jp
bigriver.jp

OpenCV ではモザイク処理は行えますか?

Gemini
Gemini

OpenCV でモザイク処理が行えそうなこと(そうなと言ったのは生成AIの答えが常に正しいかはわからないため)、そしてサンプルコードの回答がありました。 ただ、見ていくとWebカメラで取り込んだ画像をモザイク処理かけるという一連の処理のサンプルコードではなく個別に取り込んだ画像(このプログラムでは input.jpg)について座標を指定してモザイク処理をかけるというサンプルコードです。  

(全く関係ない話ですが座標指定を見て小学生のころに触っていたBASICを思い出しました。 プログラムが何かよくわからないままテキスト通り打ち込んでいたりしていましたが座標を指定するだけで線をかいたり四角形や円を書けたこと、あとはスプライトを使ってのアクションゲームみたいなものを作ろうとしたことなど。)

Geminiに再度聞くことにします。 OpenCVで取り込んだ画像を表示する際にモザイク処理をおこないたいと。

bigriver.jp
bigriver.jp

OpenCVでWebカメラの画像を読み取り出力したい。画像を出力する際にモザイク処理を行うこと。 サンプルコードを教えて。

Gemini
Gemini

サンプルコードが提示されましたが今回のコードは情報のソースとして https://tech.fusic.co.jp/posts/2019-12-03-2019-12-03-put-mosaic-on-human-faces/ であることがわかります。 このサイトも確認させてもらいましたが Gemini から提示されたコードよりも高度な処理(画像の中の Face を認識しその領域にモザイクをかける)が紹介されていました。 

コード

Gemini からのコードを参考にコメントの文章を変えたのと、あとウィンドウの名前を”Mosaic frame – bigriver.jp”に変えています。 

import cv2

def mosaic(src, ratio=0.1):
    small = cv2.resize(src, None, fx=ratio, fy=ratio, interpolation=cv2.INTER_NEAREST)
    return cv2.resize(small, src.shape[:2][::-1], interpolation=cv2.INTER_NEAREST)

# Web camera's deviceId
cap = cv2.VideoCapture(0)

while True:
    # read a frame from the camera
    ret, frame = cap.read()

    # if the frame was not read, exit
    if ret:
        # mosaic the frame
        frame = mosaic(frame)

        # show the frame
        cv2.imshow('Mosaic frame - bigriver.jp', frame)

        # 'q' key is pressed
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

# release the camera
cap.release()
cv2.destroyAllWindows()

Gemini から教えてもらったコードの解説も載せておきます。

解説
  1. mosaic 関数: 以前の回答で紹介したモザイク処理関数です。画像を縮小・拡大することでモザイク効果を実現します。
  2. cv2.VideoCapture(0): ウェブカメラのデバイスを開きます。
  3. cap.read(): ウェブカメラからフレームを読み込みます。
  4. mosaic(frame): 読み込んだフレーム全体にモザイク処理を適用します。
  5. cv2.imshow('Mosaic Frame', frame): モザイク処理後のフレームを表示します。
  6. cv2.waitKey(1) & 0xFF == ord('q'): ‘q’ キーが押されるまで処理を繰り返します。
  7. cap.release(), cv2.destroyAllWindows(): ウェブカメラとウィンドウを閉じます。

実行すると”Mosaic frame – bigriver.jp”というウィンドウが立ち上がり、窓からの風景がモザイク処理されてリアルタイムに表示されます。 以下のGIFはWindows標準機能でウィンドウをキャプチャしMP4ファイル出力した動画をGIFに変換したものです。 Webカメラからの画像が連続的に動画としてウィンドウに表示されその画像がモザイク処理されていることがわかります。

OpenCV の mosaic() のモザイク比率を変えてみる

サンプルコードでは比率(ratio)は 0.1 でした。 ここを変えてみてどうなるか確認してみることにします。実際のコードでいうと以下の部分です。

def mosaic(src, ratio=0.1):

ratio = 0.2 で大分解像度があがりました。 

これ以上はモザイク処理する意味がなくなる感じで紹介が難しい感じです。0.5 だと車の車種もわかる、0.8 だとほぼモザイクが無いのと同等で左側にある標識の文字(速度制限の数字)が識別できる位です。

ratio = 0.05 は以下。 元を知らないと何の画像かわからないレベルです。

ratio = 0.01 は以下。 ここまで来ると画像として見せる意味がなくなるレベルでした。

まとめ

今回はブログに紹介するにあたってプライバシーの配慮のために行うモザイク処理を OpenCV で実装してみました。 Google Gemini を利用することで簡単に実装できました。 ブログの記事を書いている時間の方が何倍も多いくらいです。

以上