今さら聞けない画像処理

こちらのイベントで説明した内容の抜粋です。

https://pages.databricks.com/jp-webinar-202209-Image-Processing.html

ウェビナーで使用したノートブックはこちらにあります。

https://github.com/taka-yayoi/public_repo/tree/main/20220921_image_webinar

スライドはこちら。

<script defer class="speakerdeck-embed" data-id="a1b5f20e3c7343e38fd7f850433c4fa7" data-ratio="1.7777777777777777" src="//speakerdeck.com/assets/embed.js"></script>

# 画像処理とは

我々が日常的に目にする**画像**をコンピューターで処理する技術です。

- **画像処理**とは、主にコンピュータを使用して、画像を変形したり、色合いを変えたり、別の画像と合成したり、画像から何らかの情報を取り出す等の処理を指します。
- そして、近年では、コンピュータが画像の内容を理解し、情報の抽出やデータ化を行う**画像解析**の適用も進んでいます。
![Screen Shot 2022-10-10 at 6.33.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/61a87909-f437-5611-7c17-de3fd82fe69f.png)

# 画像解析とは

**画像**から被写体の形状、色、サイズなどを抽出する技術です。

- **画像データの増加**による画像データ活用の可能性の拡大、**機械学習、人工知能技術**
の進展により、コンピュータを用いて、画像データから人、顔、自動車、部品などを抽出し、その形状、色などを判定することで、異常行動の検知、認証、品質チェックを行うという取り組みが増えています。対象は画像だけではなく、動画にも拡大しています。
- 最近ではMidjourneyなどによる画像生成も流行り始めていますが、今回は割愛します。
![Screen Shot 2022-10-10 at 6.34.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/2ff9ae75-b2f0-ce9c-29d4-f713f6c06e17.png)

# 画像解析の適用事例

もはや画像解析は実験段階ではなく実運用されるレベルになっています。

**JOHN DEERE**

- コンバインによって収穫される穀物をカメラで継続的にモニタリング。
- 穀物にダメージが認められた場合には、自動的に機械の制御パラメーターを調整。

https://qiita.com/taka_yayoi/items/a16d57aa432024eb73fb

**wehkamp**

- eコマースサイトに掲載する服の形状を検出し、自動で背景を除去。
- 背景画像を統一することで、サイトの一貫性を確保。

https://qiita.com/taka_yayoi/items/c4fcb1a24f2d4406eb6a

**デジタル病理学(digital pathology)**

- 画像処理技術の進展と新たな効率的な計算ツールの出現により、デジタル病理学は研究、診断の両方において中心的な位置を占めるように。
- 癌や感染症を診断し、治療する際の効率・効果を改善。

https://qiita.com/taka_yayoi/items/3929677d4e0c9dffaef4

# 画像解析でできること

画像解析によって人間の目、あるいはそれ以上の能力を活用できます。

**物体検知**
画像・映像内の特定の物体を検知することで、個数カウント、サイズ測定、不良品検知などをおこないます。

**パターン検知**
X線画像から腫瘍のパターンを検知することで、病状の早期検知につなげます。

**顔認識**
スマートフォンでも広く用いられており、新たな認証手法として確立されています。

**文字認識**
画像上の文字を認識し、翻訳を行うことがごく自然に行われています。

**類似画像検索**
画像の形状などから類似性を算出し、似ている画像を検索します。

# 画像処理ウォークスルー

ここではコンピュータビジョンのライブラリOpenCVを使用します。以降のウォークスルーで使用したノートブックはこちらにあります。

https://github.com/taka-yayoi/public_repo/tree/main/20220921_image_webinar

**グレースケール変換**
カラー画像をグレースケールに変換します。

**エッジ検出**
画像の輪郭を検出します。

**サイズ変更**
画像サイズを変更します。

こちらのノートブックを使用しました。

https://github.com/taka-yayoi/public_repo/blob/main/20220921_image_webinar/1.%20Databricks%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8BOpenCV%E3%81%AE%E6%B4%BB%E7%94%A8.py

```py:Python
import matplotlib.pyplot as plt
import cv2
import numpy as np
```

Databricksの環境にあるサンプル画像を使用します。

```py:Python
target = cv2.imread('/dbfs/databricks-datasets/cctvVideos/train_images/label=0/LeftBagframe0004.jpg', cv2.IMREAD_UNCHANGED)

# 画像の表示
plt.imshow(cv2.cvtColor(target, cv2.COLOR_BGR2RGB)) # OpenCV は色がGBR順なのでRGB順に並べ替える
plt.show()
```
![Screen Shot 2022-10-10 at 6.42.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/75509af2-310b-26d2-377c-f18422f15a99.png)

## グレースケール

カラー画像を白黒の階調で表現する様にします。

```py:Python
# imreadの第二引数でグレースケールを指定
gry = cv2.imread('/dbfs/databricks-datasets/cctvVideos/train_images/label=0/LeftBagframe0004.jpg', cv2.IMREAD_GRAYSCALE)
#imshow(gry)
cv2.imwrite('/tmp/gray.jpg', gry)

# 画像の表示
plt.imshow(cv2.cvtColor(gry, cv2.COLOR_BGR2RGB)) # OpenCV は色がGBR順なのでRGB順に並べ替える
plt.show()
```
![Screen Shot 2022-10-10 at 6.42.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/38740ddc-241b-103e-c2f4-fdac317b94f6.png)

## エッジ検出

輪郭を検出して強調表示します。

```py:Python
# エッジ検出
canny_img = cv2.Canny(target, 50, 110)

# 画像の表示
plt.imshow(cv2.cvtColor(canny_img, cv2.COLOR_BGR2RGB)) # OpenCV は色がGBR順なのでRGB順に並べ替える
plt.show()
```
![Screen Shot 2022-10-10 at 6.43.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/78390053-db8b-cbb0-8644-cda81da08331.png)

## サイズ変更

```py:Python
# 画像の高さ幅を指定
width,height = 60, 60
# 画像をリサイズ
resized_img = cv2.resize(target, (width, height))

# 画像の表示
plt.imshow(cv2.cvtColor(resized_img, cv2.COLOR_BGR2RGB)) # OpenCV は色がGBR順なのでRGB順に並べ替える
plt.show()
```
![Screen Shot 2022-10-10 at 6.44.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8d0510f1-639d-c4c2-b360-1d419e234535.png)

# 画像解析ウォークスルー

Databricksにおける画像の取り扱いから画像解析の例を説明します。ウェビナーでは以下のユースケースのノートブックをウォークスルーしました。

**画像データの取り扱いおよび画像のラベリング**
画像解析を行う際の基本的な流れを説明します。

**物体検知**
画像・映像内の特定の物体を検知することで、個数カウント、サイズ測定、不良品検知などをおこないます。

**パターン検知**
X線画像から腫瘍のパターンを検知することで、病状の早期検知につなげます。

**類似画像検索**
服や靴の画像を入力として、類似する画像を抽出します。

こちらでは物体検知のノートブックを説明します。

https://github.com/taka-yayoi/public_repo/blob/main/20220921_image_webinar/3.%20%E7%89%A9%E4%BD%93%E6%A4%9C%E7%9F%A5%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF.py

:::note
**注意**
使用しているImageAIのバージョンの関係からランタイムは**7.3ML**を使用してください。
:::

## セットアップ

**[ImageAI](https://github.com/OlafenwaMoses/ImageAI/blob/master/imageai/Detection/VIDEO.md):**の一部である**事前学習済み**モデルを追加するためにインストールを行います。
- **ImageAI**: ImageAI本体
- **Yolo V3**: You only look once (YOLO)は最先端のリアルタイム物体検知システムです。ここでは[YOLOv3: An Incremental Improvement](https://pjreddie.com/media/files/papers/YOLOv3.pdf)に記載されているV3を使用します。これは画像向けのモデルです。
- **Resnet**: 特徴量抽出のためにResidual Network model(h5 formatフォーマット)を使用します。このモデルは動画向けです。

### ImageAIのインストール

```
%pip install tensorflow==2.4.1
%pip install keras==2.5.0rc0

%pip install imageai
```

### ファイルパスの設定

このノートブックではユーザー名に基づいてファイル格納パスを設定します。以下のパスを使用します。
<br><br>
- `/tmp/20210902_workshop/<ユーザー名>/`: 検知対象データ、検出結果などを保存
- `/FileStore/tmp/20210902_workshop/<ユーザー名>/`: 検出結果参照用

```py:Python
import re
from pyspark.sql.types import * 

# ログインIDからUsernameを取得
username_raw = dbutils.notebook.entry_point.getDbutils().notebook().getContext().tags().apply('user')
# Username の英数字以外を除去し、全て小文字化。Username をファイルパスやデータベース名の一部で使用可能にするため。
username = re.sub('[^A-Za-z0-9]+', '', username_raw).lower()

# DBFS上のファイル格納パス
work_path = f"/tmp/20210902_workshop/{username}/"

# パスをシェル環境変数に設定して、シェルコマンドから参照できるようにします
import os
os.environ['work_path'] = work_path

print("path: " + work_path)
```
![Screen Shot 2022-10-10 at 6.47.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/76218276-fd95-7b2a-6492-1e016588ede7.png)

### 検知対象ファイルのダウンロード

シェルで`wget`を使用して画像ファイルをダウンロードします。

```sh
%sh
wget -P /dbfs${work_path} https://sajpstorage.blob.core.windows.net/workshop20210615-object-detection/five_drinks.jpg
```

### 学習済みモデルのダウンロード

Yoloをダウンロードします。

```sh
%sh
## Install the ImageAI pre-trained models: YoloV3, ResNet
wget -P /dbfs$work_path https://github.com/OlafenwaMoses/ImageAI/releases/download/1.0/yolo.h5
```

```py:Python
# ダウンロードされていることを確認します
display(dbutils.fs.ls(work_path))
```
![Screen Shot 2022-10-10 at 6.49.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/02b60dd2-0fc3-e222-c5f7-7ff2c7aff269.png)

```py:Python
## ------------------------------
## ユーティリティ関数
## ------------------------------
# displayVid(): クラウドストレージ上の動画を表示
def displayVid(filepath):
  return displayHTML("""
  <video width="480" height="320" controls>
  <source src="/files/%s" type="video/mp4">
  </video>
  """ % filepath)

# displayDbfsVid(): DBFSの動画を表示
def displayDbfsVid(filepath):
  return displayHTML("""
  <video width="480" height="320" controls>
  <source src="/dbfs/%s" type="video/mp4">
  </video>
  """ % filepath)

# displayImg(): DBFS/クラウドストレージの動画を表示
def displayImg(filepath):
  dbutils.fs.cp(filepath, "FileStore/%s" % filepath)
  return displayHTML("""
  <img src="/files/%s" width="800">
  """ % filepath)
```

## 単一画像からコーヒーの検知

YoloV3と以下のスターバックスのアイスコーヒーの画像を用いて物体検知を行います。

<img src="https://sajpstorage.blob.core.windows.net/workshop20210615-object-detection/five_drinks.jpg" width="600"/>

```py:Python
# TensorFlowの設定
import tensorflow as tf

config = tf.compat.v1.ConfigProto()
config.gpu_options.visible_device_list = "0"
config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = 0.5

tf.compat.v1.Session(config=config)
tf.compat.v1.set_random_seed(42) # 再現性確保のために乱数のシードを設定
```

```py:Python
# ImageAIからObjectDetectionをインポート
from imageai.Detection import ObjectDetection
import os
import h5py

# 実行パス、分析画像、出力先のパスを指定
execution_path = f"/dbfs{work_path}"
execution_path_source = f"/dbfs{work_path}five_drinks.jpg"
execution_path_results = f"/dbfs{work_path}result.jpg"

print(execution_path)
print(execution_path_source)
print(execution_path_results)
```
![Screen Shot 2022-10-10 at 6.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/849c7db2-3626-51f2-5418-79fdc64de3f9.png)

### 物体検知

```py:Python
# YoloV3モデルとObjectDetectionを使用
detector = ObjectDetection()
detector.setModelTypeAsYOLOv3()
detector.setModelPath( os.path.join(execution_path , "yolo.h5"))
detector.loadModel()

detections = detector.detectObjectsFromImage(
  input_image = execution_path_source, # 検知対象画像パス
  output_image_path = execution_path_results, # 検知結果画像パス
  minimum_percentage_probability = 30 # 確率の閾値
)
```

検知結果を確認します。

```py:Python
detections
```

領域とラベルのセットが得られています。

- dining tableの確率は30%程度ですが、他のcupに関しては60-90%程度の確率となっています。
- percentage_probabilityの後に表示されているのは検知箇所の座標です。
![Screen Shot 2022-10-10 at 6.51.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/dad115bf-d85c-8b0b-5cb0-38d6335abe34.png)

検知結果がオーバーレイされた画像を表示します。
![result.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/2b63c920-d80c-009e-7719-61e4ef5e2bab.jpeg)


# まとめ

![Screen Shot 2022-10-10 at 6.56.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/673f349e-4341-12a6-9ea1-8c02cb99f4ec.png)

ウェビナーでは、これ以外にもデジタル病理学の実例、[TensorFlow Similarity](https://github.com/tensorflow/similarity)を用いた類似画像の取得、アプリとの連携までをご紹介しました。画像処理よりも画像解析に重きを置いた内容となりましたが、これらすべては実験段階の域を超え、すでにビジネスで広く活用されている技術となっています。皆様も街中で画像解析が活用されている事例は結構見かけているはずです。

このような画像解析技術をクイックに試すことができ、実運用段階に容易にこうする仕組みを提供しているDatabricksを活用してみませんか？

以下はDatabricksが提供している機能のごく一部です。

- 並列分散処理による画像の高速処理
- GPUクラスターを簡単に構成して活用
- 様々なライブラリのサポート
- モデル管理からデプロイまでをカバーするMLOpsの実現

DatabricksのセミナーなのでDatabricksの宣伝になってしまいました。

Databricksでどの様に画像を活用できるのかに興味がある方は、以下の記事もご覧ください。

- [Databricks Community Editionで画像データを分析してみる](https://qiita.com/taka_yayoi/items/1c02542125bc327282d5)
- [画像アプリケーションに対するDatabricksリファレンスソリューション](https://qiita.com/taka_yayoi/items/41be81691df3f7c8e6bf)
- [Databricksにおける画像の取り扱い](https://qiita.com/taka_yayoi/items/8d4b1b61699d68a34e58)
- [DatabricksにおけるOpenCVの活用](https://qiita.com/taka_yayoi/items/f31703f1c770a15304dd)
- [Databricksにおけるバイナリーファイルの取り扱い](https://qiita.com/taka_yayoi/items/0435dab820dea19df339)
- [PyTorchによるeコマースのファッション画像背景の自動除去](https://qiita.com/taka_yayoi/items/c4fcb1a24f2d4406eb6a)
- [eコマース向け類似画像レコメンデーションシステムの構築](https://qiita.com/taka_yayoi/items/173d5228c1d08c5130ef)
- [Databricksにおける機械学習による病理画像分析の自動化](https://qiita.com/taka_yayoi/items/3929677d4e0c9dffaef4)
- [Databricks機械学習ランタイムを用いた動画における不審な振る舞いの検知](https://qiita.com/taka_yayoi/items/0dff172a79040ec5cfb6)
- [データレイクハウスでコンピュータービジョンアプリケーションを実現する](https://qiita.com/taka_yayoi/items/887343d522fceb7e793c)
- [DatabricksとLabelboxの連携](https://qiita.com/taka_yayoi/items/1921192a94246810bc11)
- [DatabricksとLabelboxの連携\(実践編\)](https://qiita.com/taka_yayoi/items/64245fe438443f3742c4)

# その他の「今さら聞けない」シリーズ

https://qiita.com/taka_yayoi/items/51583a581ce5a6ba6558

https://qiita.com/taka_yayoi/items/92ec880c7d7c6ce271d5

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)