Gemini 画像のウォーターマークを高速に削除するまでの試行錯誤(OpenCV / LaMa / 自作アルゴリズム)
Geminiで生成した画像をダウンロードすると、右下に自動的に追加されるウォーターマーク。
品質は高いのに、この小さなロゴのせいでそのまま使えない場面も多いと思います。
そこで私は、Chrome拡張「Gemini Watermark Cleaner」
と、オンライン版 Gemini Watermark Remover

を個人開発しました。
目的はとてもシンプルで、
- 操作を変えず
- ダウンロード時に自動で除去
- できるだけローカル処理のみ
という条件で、「意識しなくても勝手に消えている」体験を作ることでした。
この記事では、
OpenCV → LaMa → 自作軽量アルゴリズム
という 実装の進化過程と設計判断 をまとめます。
デモ動画
まずは実際の動作を確認してもらうのが一番わかりやすいと思います。
YouTube デモ動画
ダウンロード時に自動でウォーターマークが消える様子が確認できます。
開発方針
最初に決めた方針は次の 3 点です。
- ユーザーの操作フローは変えない
- 可能な限りローカル処理(プライバシー重視)
- Chrome 拡張として実用レベルの速度
「拡張を意識しなくても、いつの間にか消えている」体験を目標にしました。
フェーズ1:OpenCV ベースの単純実装(v1.1.0)
最初は OpenCV を使った素朴な実装から始めました。
参考実装
アプローチ
- ウォーターマーク位置を固定領域として検出
- 単色背景を前提に inpainting / 塗りつぶし
結果
-
単色背景では問題なし
-
しかし以下では破綻が目立つ:
-
グラデーション背景
-
写真
-
色数の多い画像
境界が目立ちやすく、
「実運用には厳しい」という結論になりました。
フェーズ2:LaMa Inpainting の導入(v2.0.0)
次に試したのが LaMa のローカル推論です。
参考
構成
- PyTorch + LaMa
- 完全ローカル推論
- セマンティック補完
精度
- ほぼすべての画像で自然に復元
- 人物・写真・複雑背景でも非常に高精度
正直、品質面ではほぼ理想的でした。
問題点
ただし実用面で大きな問題がありました。
| 項目 | 値 |
|---|---|
| モデルサイズ | 数百 MB |
| 処理時間 | 約 30 秒 / 枚 |
| Chrome 拡張 | 現実的でない |
「精度は完璧だが、プロダクトとして成立しない」状態です。
フェーズ3:軽量自作アルゴリズム(v3.0.0)
最終的に、学習モデルを使わない
軽量アルゴリズムを自作する方針に切り替えました。
参考
目標
- モデル非依存
- JS / WASM 実装可能
- 数ミリ秒で処理
- Chrome 拡張に完全組み込み
アプローチ概要
- ウォーターマークの形状・アルファ構造を解析
- エッジ検出 + 局所パッチ再構成
- 周辺ピクセルから統計的補完
- 境界ブレンド処理
結果として:
- ファイルサイズ < 2MB
- 処理時間:数ミリ秒
- 実用精度を維持
というバランスに落ち着きました。
Chrome 拡張での組み込み
現在の拡張では次の流れで動作しています。
- ユーザーが通常通り「ダウンロード」
-
chrome.downloadsをフック - ローカルで画像処理
- ウォーターマーク除去後に保存
ポイント
- UI なし
- 操作フロー変更なし
- 画像は外部送信されない
「拡張を意識しなくてよい」ことを最優先にしました。
オンライン版(ブラウザ内ローカル処理)
拡張を使えない環境向けに、
ブラウザ内ローカル処理のオンライン版も用意しています。
- 画像はサーバー保存なし
- AI API 不使用
- Nano Banana 画像対応
プライバシー設計
共通方針として:
- すべてローカル処理
- 自動アップロードなし
- ログ保存なし
- AI API 未使用
生成画像の機密性をそのまま維持できる設計にしています。
まとめ
開発の流れは次のようになりました。
| フェーズ | 技術 | 精度 | 速度 | 実用性 |
|---|---|---|---|---|
| v1 | OpenCV | 低〜中 | 高速 | △ |
| v2 | LaMa | 非常に高 | 遅い | ✗ |
| v3 | 自作アルゴリズム | 高 | 超高速 | ◎ |
現在の実装は:
- 高精度
- 超高速
- 軽量
- 完全ローカル
という、実運用向けのバランスに落ち着きました。
同じように画像処理やブラウザ拡張を扱っている方の参考になれば幸いです。
技術的な指摘や改善案なども歓迎します。
Discussion