# 機能設計書 52-画像変換操作（Image Operations）

## 概要

本ドキュメントは、TensorFlowにおける画像変換操作機能の設計を記述する。画像のリサイズ・クロップ・回転・反転・色空間変換・エンコード/デコード・Non-Max Suppressionなどの画像処理オペレーション群を提供する。

### 本機能の処理概要

**業務上の目的・背景**：画像認識・物体検出・スタイル変換などの機械学習タスクにおいて、入力画像の前処理（リサイズ、クロップ、正規化、色空間変換）は不可欠である。また、推論結果の後処理（Non-Max Suppression、バウンディングボックス描画）も必要となる。本機能はこれらの画像処理パイプラインを構成するためのC++オペレーション群を提供する。

**機能の利用シーン**：カメラフレームからの画像入力前処理（YUV→RGB変換、リサイズ）、データオーギュメンテーション（ランダムクロップ、色調変更）、物体検出の後処理（NMS）、画像ファイルの読み書き（JPEG/PNG/BMP/GIF/WebPエンコード・デコード）などで利用される。

**主要な処理内容**：
1. 画像リサイズ操作：Bilinear, Bicubic, NearestNeighbor, Area補間によるリサイズ
2. 画像デコード操作：JPEG, PNG, BMP, GIF, WebP, JXL形式のデコード
3. 画像エンコード操作：JPEG, PNGへのエンコード
4. 色空間変換：RGB/HSV相互変換、コントラスト・色相・彩度調整
5. クロップ・変形操作：CropAndResize, ExtractGlimpse, ProjectiveTransform
6. バウンディングボックス操作：DrawBoundingBoxes, SampleDistortedBoundingBox
7. Non-Max Suppression：V1〜V5およびCombinedNMS, SoftNMS

**関連システム・外部連携**：Android Cameraフレームワーク（CameraActivity、Camera2 API）との連携。TFLite推論エンジンへの入力画像供給。

**権限による制御**：特段の権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 画像分類画面 | 主機能 | カメラフレームの画像リサイズ・クロップ・色空間変換 |
| 2 | 物体検出画面 | 主機能 | カメラフレームの画像リサイズ・クロップ・色空間変換 |
| 3 | スタイル変換画面 | 主機能 | カメラフレームの画像リサイズ・クロップ・色空間変換 |
| 5 | カメラベース画面（抽象） | 主機能 | YUV420→ARGB8888への色空間変換 |
| 6 | カメラ接続フラグメント | 主機能 | Camera2 APIでYUV_420_888形式のプレビューフレーム取得 |
| 7 | レガシーカメラ接続フラグメント | 主機能 | 旧Camera APIでプレビューフレーム取得 |
| 9 | TFLiteカメラプレビューフラグメント | 補助機能 | Camera2 APIでカメラプレビューをBitmapへ変換 |
| 10 | OVICベンチマーク画面 | 補助機能 | テスト画像のデコード・Bitmap変換 |

## 機能種別

計算処理 / 画像変換

## 入力仕様

### 入力パラメータ（主要オペレーション）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| images | T（各種数値型） | Yes | 入力画像テンソル [batch, height, width, channels] | rank=4 |
| size | int32 | Yes | 出力サイズ [height, width]（リサイズ系） | rank=1, dim[0]=2 |
| contents | string | Yes | エンコードされた画像バイト列（デコード系） | rank=0 スカラー |
| boxes | float | Yes | バウンディングボックス座標（NMS系） | rank=2, dim[1]=4 |
| scores | float | Yes | 検出スコア（NMS系） | rank=1 |
| channels | int（属性） | No | デコード時のチャネル数指定（0=自動） | 非負整数 |

### 入力データソース

カメラフレーム（YUV/RGB画像データ）、ファイルシステム上の画像ファイル、tf.data Datasetからの画像テンソル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| resized_images | float | リサイズ後の画像テンソル [batch, new_h, new_w, channels] |
| image | uint8/uint16/float32 | デコードされた画像テンソル [h, w, channels] |
| contents | string | エンコードされた画像バイト列 |
| selected_indices | int32 | NMS選択済みインデックス |
| output | T | 色調調整後の画像テンソル |

### 出力先

後続の計算グラフ（推論モデル入力、画面表示、ファイル保存）。

## 処理フロー

### 処理シーケンス

```
1. 画像前処理パイプライン
   ├─ DecodeJpeg/DecodePng/DecodeImage: ファイルバイト列→テンソル変換
   ├─ ResizeBilinear/ResizeBicubic: 指定サイズへのリサイズ
   ├─ CropAndResize: ROI領域の切り出しとリサイズ
   ├─ AdjustContrastv2/AdjustHue/AdjustSaturation: 色調補正
   └─ RGBToHSV/HSVToRGB: 色空間変換

2. 推論後処理パイプライン
   ├─ NonMaxSuppression (V1-V5): 重複検出の抑制
   ├─ CombinedNonMaxSuppression: バッチ対応NMS
   └─ DrawBoundingBoxes: 検出結果の可視化

3. 画像出力パイプライン
   ├─ EncodeJpeg: JPEG形式へのエンコード
   └─ EncodePng: PNG形式へのエンコード
```

### フローチャート

```mermaid
flowchart TD
    A[画像入力] --> B{入力形式}
    B -->|バイト列| C[DecodeJpeg/DecodePng/DecodeImage]
    B -->|テンソル| D[前処理]
    C --> D
    D --> E[ResizeBilinear/ResizeBicubic]
    E --> F[色調補正: AdjustContrast/Hue/Saturation]
    F --> G[推論モデル入力]
    G --> H[推論結果]
    H --> I[NonMaxSuppression]
    I --> J[DrawBoundingBoxes]
    J --> K[EncodeJpeg/EncodePng]
    K --> L[画像出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | リサイズ形状推論 | 出力形状は [batch, new_height, new_width, channels] でsizeテンソルから高さ・幅を取得 | ResizeArea/Bilinear/Bicubic/NearestNeighbor |
| BR-52-02 | チャネル数制御 | channels=0で画像本来のチャネル数を使用、それ以外は指定数に変換 | Decode系オペレーション |
| BR-52-03 | NMSボックス形状 | ボックステンソルは [num_boxes, 4] 形状（4は座標値） | NonMaxSuppression系 |
| BR-52-04 | 非推奨オペレーション | RandomCropはバージョン8で非推奨、AdjustContrastはバージョン2で非推奨 | 旧バージョン互換 |
| BR-52-05 | align_corners | trueの場合コーナーピクセルを入出力で一致させる | リサイズ系オペレーション |

### 計算ロジック

- **Bilinear補間**: 4近傍ピクセルの線形補間
- **Bicubic補間**: 16近傍ピクセルの3次補間
- **NearestNeighbor補間**: 最近傍ピクセルの値をコピー
- **Area補間**: 面積平均によるダウンサンプリング
- **NMS**: IoU（Intersection over Union）閾値による重複除去

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | ランクエラー | 入力画像テンソルのランクが期待値と異なる場合 | 正しいランクのテンソルを入力 |
| InvalidArgument | チャネルエラー | channels属性が負の値の場合 | 0以上の整数を指定 |
| InvalidArgument | サイズエラー | sizeテンソルがDT_INT32型でない場合 | int32型のsizeテンソルを使用 |
| InvalidArgument | ボックス形状エラー | boxes[1]が4でない場合 | [num_boxes, 4]形状のテンソルを使用 |

### リトライ仕様

画像処理はステートレスであり、同一入力に対して同一出力を返す。リトライに特別な考慮は不要。

## トランザクション仕様

トランザクション制御は行わない。

## パフォーマンス要件

- リアルタイムカメラフレーム処理では30FPS以上の処理速度が求められる場合がある
- GPU上でのカーネル実行により高速化が可能

## セキュリティ考慮事項

- 悪意のある画像ファイル（バッファオーバーフロー攻撃を意図したもの）に対する防御が必要
- DecodeJpegのtry_recover_truncated属性で破損JPEG処理に対応

## 備考

image_ops.ccは約1224行の大規模なオペレーション定義ファイルであり、約40以上のオペレーションを定義している。形状推論のヘルパー関数（SetOutputToSizedImage、ResizeShapeFn、DecodeImageShapeFn等）が共通利用されている。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

画像テンソルの形状表現（batch, height, width, channels）と形状推論のヘルパー関数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 30-66行目: SetOutputToSizedImage関数 - リサイズ後のテンソル形状 [batch, height, width, channels] の推論ロジック |
| 1-2 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 68-73行目: ResizeShapeFn - rank=4入力からSetOutputToSizedImageを呼び出すパターン |
| 1-3 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 75-98行目: GetChannelsDim, DecodeImageShapeFn - デコード時のチャネル数と形状推論 |

**読解のコツ**: TensorFlowの形状推論システムでは`InferenceContext`が中心的な役割を果たす。`c->WithRank()`でランク検証、`c->Dim()`で次元取得、`c->MakeDim()`で次元生成、`c->set_output()`で出力形状設定を行う。

#### Step 2: エントリーポイントを理解する

主要なオペレーション登録を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 274-282行目: ResizeArea - 面積補間リサイズ |
| 2-2 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 310-319行目: ResizeBilinear - 双線形補間リサイズ |
| 2-3 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 463-471行目: DecodeImage - 汎用画像デコード |
| 2-4 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 981-1005行目: NonMaxSuppression - NMS V1 |

**主要処理フロー**:
1. **274-282行目**: ResizeArea Op登録。T型入力画像とint32型サイズを受け取り、float型リサイズ画像を出力
2. **463-471行目**: DecodeImage Op登録。string型バイト列を入力し、channels/dtype/expand_animationsの属性で出力形状を制御
3. **528-540行目**: EncodeJpeg Op登録。品質・プログレッシブ・クロマダウンサンプリング等の多数の属性を持つ
4. **981-1005行目**: NonMaxSuppression V1登録。boxes[num_boxes,4]+scores[num_boxes]+max_output_sizeを入力

#### Step 3: NMS系オペレーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 155-176行目: NMSShapeFn - boxes/scores/threshold検証と可変長出力 |
| 3-2 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 178-202行目: SoftNMSShapeFn - Soft-NMS用の形状推論 |
| 3-3 | image_ops.cc | `tensorflow/core/ops/image_ops.cc` | 204-269行目: CombinedNMSShapeFn - バッチ対応NMSの複雑な形状推論 |

### プログラム呼び出し階層図

```
image_ops.cc (Op定義)
    |
    +-- ヘルパー関数
    |    +-- SetOutputToSizedImage (30-66行目)
    |    +-- ResizeShapeFn (68-73行目)
    |    +-- GetChannelsDim / DecodeImageShapeFn (75-98行目)
    |    +-- DecodeImageV2ShapeFn (100-122行目)
    |    +-- EncodeImageShapeFn (124-129行目)
    |    +-- ColorspaceShapeFn (141-153行目)
    |    +-- NMSShapeFn (155-176行目)
    |    +-- SoftNMSShapeFn (178-202行目)
    |    +-- CombinedNMSShapeFn (204-269行目)
    |
    +-- リサイズ系Op
    |    +-- ResizeArea (274行目)
    |    +-- ResizeBicubic (285行目)
    |    +-- ResizeBilinear (310行目)
    |    +-- ResizeNearestNeighbor (387行目)
    |    +-- ScaleAndTranslate (322行目)
    |
    +-- デコード系Op
    |    +-- DecodeImage (463行目)
    |    +-- DecodeJpeg (474行目)
    |    +-- DecodePng (613行目)
    |    +-- DecodeBmp (629行目)
    |    +-- DecodeGif (636行目)
    |    +-- DecodeWebP (650行目)
    |    +-- DecodeJxl (670行目)
    |
    +-- エンコード系Op
    |    +-- EncodeJpeg (528行目)
    |    +-- EncodePng (621行目)
    |
    +-- 色空間/色調Op
    |    +-- RGBToHSV / HSVToRGB (678/685行目)
    |    +-- AdjustContrastv2 / AdjustHue / AdjustSaturation (580/593/603行目)
    |
    +-- NMS系Op
    |    +-- NonMaxSuppression V1-V5 (981-1101行目)
    |    +-- CombinedNonMaxSuppression (1135行目)
    |
    +-- その他Op
         +-- CropAndResize (919行目)
         +-- DrawBoundingBoxes V1/V2 (692/724行目)
         +-- ExtractGlimpse V1/V2 (849/883行目)
         +-- ImageProjectiveTransformV2/V3 (1192/1207行目)
```

### データフロー図

```
[入力]                      [処理]                         [出力]

画像バイト列 -------> Decode(Jpeg/Png/Bmp/..) -------> 画像テンソル [H,W,C]
                                                            |
画像テンソル -------> Resize(Bilinear/Bicubic/..) ------> リサイズ画像 [B,H',W',C]
                                                            |
画像テンソル -------> AdjustContrast/Hue/Saturation --> 色調補正画像
                                                            |
boxes + scores -----> NonMaxSuppression ----------------> 選択インデックス
                                                            |
画像 + boxes -------> DrawBoundingBoxes ----------------> 描画済み画像
                                                            |
画像テンソル -------> Encode(Jpeg/Png) -----------------> 画像バイト列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| image_ops.cc | `tensorflow/core/ops/image_ops.cc` | ソース | 画像操作オペレーション定義（約40 Op） |
| common_shape_fns.h | `tensorflow/core/framework/common_shape_fns.h` | ヘッダ | 共通形状推論関数 |
| op.h | `tensorflow/core/framework/op.h` | ヘッダ | REGISTER_OPマクロ定義 |
| shape_inference.h | `tensorflow/core/framework/shape_inference.h` | ヘッダ | InferenceContext定義 |
