ガンマ補正を用いたリアルタイム映像の明るさ調整【Python】

# 目次
[はじめに](#はじめに)
[実行環境](#実行環境)
[webカメラの幅と高さの取得方法](#webカメラの幅と高さの取得方法)
[メインウィンドウのサイズの設定方法](#メインウィンドウのサイズの設定方法)
[リアルタイム映像の表示領域の設定方法](#リアルタイム映像の表示領域の設定方法)
[スライドバーで小数を扱う方法](#スライドバーで小数を扱う方法)
[スライドバーの設定方法](#スライドバーの設定方法)
[ガンマ補正の実装方法](#ガンマ補正の実装方法)
[ルックアップテーブルの作成方法](#ルックアップテーブルの作成方法)
[ガンマ補正の処理方法](#ガンマ補正の処理方法)
[リアルタイム画像のtkinterでの表示方法](#リアルタイム画像のtkinterでの表示方法)
[定期的に処理を実行する方法](#定期的に処理を実行する方法)
[ソースコード](#ソースコード)
[結果](#結果)
[まとめ](#まとめ)

# はじめに
今回は、[**前回のTwitter(X)のアンケート**](https://twitter.com/0ca00118726208m/status/1695006241549058293)でトップだった<font color="red">**動画像処理**</font>についての記事です。
そのジャンルの中から、<font color="red"><ins>**webカメラから得られた映像に**</ins></font>**`γ変換`**<font color="red"><ins>**をかけて明るくしたリアルタイムの動画を**</font></ins>**`Tkinter`**<font color="red"><ins>**を用いて表示させ**</ins></font>**`γ`**<font color="red"><ins>**の値を**</ins></font>**`Tkinter`**<font color="red"><ins>**の**</ins></font>**`tkinter.Scale`**<font color="red"><ins>**で調整させる**</ins></font>プログラムを作成したのでそれについて紹介したいと思います。

--------

<details><summary>マイページについて</summary>

:::note info
主に<ins>**Pythonについての記事**</ins>を投稿してます!!
:::

[<font color="blue"><ins>**マイページはこちら**</ins></font>](https://qiita.com/blueman "マイページ")

</details>

<details><summary>X(Twitter)について</summary>

:::note info
<ins>**Qiitaの新着記事の通知**</ins>や<ins>**おススメの理工学書の紹介**</ins>をツイートしてます!!
:::
[<font color="blue"><ins>**X(Twitter)はこちら**</ins></font>](https://twitter.com/0ca00118726208m "X(Twitter)")

</details>

<details><summary>Zennについて</summary>

:::note info
主に<ins>**自分の書いたQiitaの記事の転載**</ins>と<ins>**Pythonを使っていて遭遇したエラーの対処法のような記事**</ins>を投稿していく予定です!!
:::
[<font color="blue"><ins>**Zennはこちら**</ins></font>](https://zenn.dev/blueman "Zenn")

</details>

# 実行環境
実行環境は次の通りです。

<details><summary>実行環境</summary>

- **環境**
    -  **`Windows10`**
    -  **`Python 3.10.5`**

- **ライブラリ**
    -  **`OpenCV 4.8.0`**
    -  **`numpy 1.22.4`**
    -  **`pillow 9.2.0`**

:::note info
<font color="red"> **`tkinter`** </font> は、<font color="red"><ins>**標準ライブラリ**</ins></font>なので<font color="red">**特に気にしなくても大丈夫です!!**</font>
:::

</details>

**処理内容**と**ライブラリ**の対応を分かりやすく表にすると次の通りです。
<details><summary>説明</summary>

| <font color="red">処理内容</font> | <font color="red">モジュール<br>ライブラリ</font> |
|:-:|:-:|
|**webカメラの幅と高さの取得<br>webカメラの映像の取得・反転<br>[ルックアップテーブル(LUT)](https://www.tem-inc.co.jp/contents/small-camera/110/#:~:text=%E3%83%AB%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%EF%BC%88LUT%EF%BC%89%E3%81%A8%E3%81%AF%E3%80%81%E5%85%A5%E5%8A%9B%E3%81%95%E3%82%8C%E3%81%9F%E5%80%A4%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E5%87%BA%E5%8A%9B%E5%80%A4%E3%82%92%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%82%8B%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%A7%E3%81%99%E3%80%82%20LUT%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%80%81%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E7%94%BB%E5%83%8F%E3%81%AB%E7%89%B9%E6%80%A7%E6%9B%B2%E7%B7%9A%E3%82%92%E7%B0%A1%E5%8D%98%E3%81%AB%E9%81%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%80%81%E3%81%9D%E3%81%AE%E8%A8%88%E7%AE%97%E3%82%82%E7%B4%A0%E6%97%A9%E3%81%8F%E8%A1%8C%E3%81%86%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82,%E3%81%93%E3%81%AE%E7%89%B9%E6%80%A7%E3%81%AF%E3%80%81%E8%A9%95%E4%BE%A1%E3%82%84%E8%89%B2%E7%A9%BA%E9%96%93%E8%A3%9C%E6%AD%A3%E3%81%AB%E3%81%A8%E3%81%A3%E3%81%A6%E6%9C%89%E6%84%8F%E3%81%AB%E5%83%8D%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82%20%E4%BE%8B%E3%81%88%E3%81%B08%E3%83%93%E3%83%83%E3%83%88%E7%94%BB%E5%83%8F%E3%81%AE%E5%A0%B4%E5%90%88%E3%80%81%E3%83%94%E3%82%AF%E3%82%BB%E3%83%AB%E5%80%A4%E3%81%8C0%EF%BD%9E127%E3%81%AE%E3%82%82%E3%81%AE%E3%81%AF0%E3%81%AB%E3%80%81128%EF%BD%9E255%E3%81%AE%E3%82%82%E3%81%AE%E3%81%AF255%E3%81%AB%E3%83%94%E3%82%AF%E3%82%BB%E3%83%AB%E5%80%A4%E3%82%92%E7%BD%AE%E3%81%8D%E6%8F%9B%E3%81%88%E3%81%BE%E3%81%99%E3%81%A8%E3%80%812%E5%80%A4%E5%8C%96%E7%94%BB%E5%83%8F%E3%82%92%E5%BE%97%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E5%BE%97%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)の実装**|<font color="red">  **`OpenCV`** </font>|
|**`γ`変換の初期値の設定**|<font color="red">  **`numpy`** </font>|
|**`γ`変換のGUIでの操作**|<font color="red">  **`tkinter`** </font>|
|**`OpenCV`で得られた画像を`Tkinter`で<br>使えるように変換**|<font color="red">  **`pillow`** </font>|

</details>

# webカメラの幅と高さの取得方法
こちらのソース

https://www.klv.co.jp/corner/python-opencv-camera-setting.html

によると、<font color="red">**`cv2.CAP_PROP_FRAME_WIDTH`**</font>でwebカメラの<font color="red">**幅**</font>を<font color="red">**`cv2.CAP_PROP_FRAME_HEIGHT`**</font>でwebカメラの<font color="red">**高さ**</font>を取得できるそうです。
この方法を使ってwebカメラの<ins>**幅**</ins>と<ins>**高さ**</ins>を取得しました。

# メインウィンドウのサイズの設定方法
こちらのソース

https://daeudaeu.com/main_window/#geometry

によると、<font color="red">**`geometry`**</font>メソッドを使うことで**メインウィンドウのサイズ**を設定できるそうです。
このメソッドを使って、<ins>メインウィンドウのサイズ</ins>を設定しました。

:::note
**メインウィンドウの幅**は、<font color="red">**`cv2.CAP_PROP_FRAME_WIDTH`**</font>で取得した<font color="red">**webカメラの幅**</font>を**整数型**に型変換し、その値を**文字列型**に型変換して設定しました。

**メインウィンドウの高さ**は、<font color="red">**`cv2.CAP_PROP_FRAME_HEIGHT`**</font>で取得した<font color="red">**webカメラの高さ**</font>を**整数型**に型変換し、その値を**文字列型**に型変換して設定しました。
:::

# リアルタイム映像の表示領域の設定方法
こちらのソース

https://daeudaeu.com/tkinter_canvas_widget/#i

によると、<font color="red">**`Canvas`**</font>ウィジェットを使うことで**図形を描画**できるそうです。
このウィジェットを使って<ins>リアルタイム映像を表示</ins>させました。

## 表示領域の幅の設定方法
こちらのソース

https://daeudaeu.com/tkinter_canvas_widget/#widthheight

によると、<font color="red">**`Canvas`**</font>ウィジェットの<font color="red">**`width`**</font>キーワード引数で**表示領域の幅**を設定できるそうです。
このキーワード引数を使って、<ins>表示領域の幅を設定</ins>しました。

## 表示領域の高さの設定方法
こちらのソース

https://daeudaeu.com/tkinter_canvas_widget/#widthheight

によると、<font color="red">**`Canvas`**</font>ウィジェットの<font color="red">**`height`**</font>キーワード引数で**表示領域の高さ**を設定できるそうです。
このキーワード引数を使って、<ins>表示領域の高さを設定</ins>しました。

# スライドバーで小数を扱う方法
こちらのソース

https://daeudaeu.com/control-variable/#i-2

によると、<font color="red">**`DoubleVar`**</font>というウィジェット変数を用いることで **`tkinter`** のスライドバーで<font color="red">**浮動小数点数(小数)**</font>を使うことができるそうです。
この<font color="red">**`DoubleVar`**</font>というウィジェット変数を用いて<ins>スライドバーで小数を扱えるように</ins>しました。

# スライドバーの設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#i-2

によると、<font color="red">**`Scale`**</font>ウィジェットを使うことで**スライドバー**を表示できるそうです。

## 向きの設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#orient

によると、<font color="red">**`orient`**</font>オプションの<font color="red">**`tkinter.HORIZONTAL`**</font>を使うことで**スライドバーの向きを水平方向(横向き)にすることができる**そうです。
このオプションを使って、<ins>向きを設定</ins>しました。

## 最小値と最大値の設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#from-to

によると、<font color="red">**`from_`**</font>オプションで**最小値**を<font color="red">**`to`**</font>オプションで**最大値**を設定できるそうです。
このオプションを使って、<ins>最小値</ins>と<ins>最大値</ins>を設定しました。

<details><summary>最小値と最大値の説明</summary>

::::note
- **最小値について**
[ガンマ補正の方法](#ガンマ補正の方法)の項で紹介するように<ins>**画像を明るく表示させたいときには1よりも大きい値に設定する必要がある**</ins>そうなので**1より大きく**しました。

- **最大値について**
実行環境で実験をしたところ、3で問題なかったので**3まで**としました。
:::

:::note warn
**最大値**については、お使いの際は<font color="red">**適宜変更**</font>してください。
:::

</details>

## 分解能の設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#resolution

によると、<font color="red">**`resolution`**</font>オプションで**分解能**を設定できるそうです。
このオプションを使って、<ins>分解能</ins>を設定しました。

<details><summary>分解能についての説明</summary>

:::note warn
<font color="red">**`resolution`**</font>オプションは<font color="red">**小数**</font>で指定してください。そうしないと、**スライドバーで小数を設定できません**。
:::

</details>

## ウィジェット変数の指定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#variable

によると、<font color="red">**`variable`**</font>オプションで**ウィジェット変数を指定**できるそうです。
このオプションを使って、<ins>ウィジェット変数を指定</ins>しました。

:::note

[**スライドバーで小数を扱う方法**](#スライドバーで小数を扱う方法)で示した<font color="red">**`DoubleVar`**</font>というウィジェット変数を<font color="red">**`variable`**</font>オプションで指定しました。

:::

## 目盛の設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#tickinterval

によると、<font color="red">**`tickinterval`**</font>オプションで**目盛の表示・間隔**を設定できるそうです。
このオプションを使って、<ins>目盛の表示と目盛の間隔</ins>を設定しました。

## 長さの設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#lengthwidth

によると、<font color="red">**`length`**</font>オプションで**長さ**を設定できるそうです。
このオプションを使って、<ins>長さ</ins>を設定しました。

:::note
スライドバーを**画面の横全体に表示させたかった**ので、[**webカメラの幅と高さの取得方法**](#webカメラの幅と高さの取得方法)で紹介した<font color="red">**`cv2.CAP_PROP_FRAME_WIDTH`**</font>を長さに設定しました。
:::

## 表示文字色の設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#fgor_foreground

によると、<font color="red">**`fg`**</font>オプションで**表示文字色**を設定できるそうです。
このオプションを使って、<ins>表示文字色</ins>を設定しました。

## 背景、選択してない状態でのスライドバーの色の設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#bgor_background

によると、<font color="red">**`bg`**</font>オプションで**背景、選択してない状態でのスライドバーの色**を設定できるそうです。
このオプションを使って、<ins>背景、選択してない状態でのスライドバーの色</ins>を設定しました。

## ウィジェットの枠線色の設定方法
こちらのソース

https://daeudaeu.com/tkinter-scale/#highlightcolorhighlightbackgroundhighlightthickness

によると、<font color="red">**`highlightbackground`**</font>オプションで**フォーカスが外れた時のスケールウィジェットの色**を設定できるそうです。
このオプションを使って、<ins>フォーカスが外れた時のスケールウィジェットの色</ins>を設定しました。

:::note
このオプションを指定しないと、**外枠線の色がデフォルト(灰色に似た色)のまま**になります。
:::

# ガンマ補正の実装方法
こちらのソース

http://rs.aoyaman.com/seminar/about10.html

によると、`γ`補正の公式は

> ```math
> Y＝255\times\Bigl(\frac{X}{255}\Bigl)^\frac{1}{\gamma}
> 
> ```
> ここで、
> ```math
> Y:γ補正後のピクセル値
> ```
> ```math
> X:γ補正前のピクセル値
> ```
> ```math
> γ:ガンマ補正値
> ```

で表現できるそうです。

また、こちらのソース


https://di-acc2.com/programming/python/19009/#index_id2

では、<font color="red">**画像を明るく表示**</font>したい場合には

> **`γ`の値を<font color="red"><ins>1より大きい値</ins></font>に設定する**

必要があるそうなので、<font color="red">**`γ`の値の範囲を1より大きく**</font>しました。

これらの情報をもとに`γ`補正を実装しました。

# ルックアップテーブルの作成方法
## `γ`補正の計算結果を格納する配列の作成方法

`γ`補正の計算結果を格納する変数を作成するために
**`numpy`** の **`zeros`** 関数を利用しました。

こちらのソース

https://www.sejuku.net/blog/68767

によると、<font color="red">**`numpy`**</font>の<font color="red">**`zeros`**</font>関数は、

> **配列の全要素が0で初期化されている**

関数だそうです。
この関数を使って、<ins>`γ`補正の計算結果を格納する配列</ins>を作成しました。

:::note alert
OpenCVのカラー画像では、値の範囲が0～255の<ins>**8bit**</ins>です。そのため、要素の型の指定ができるパラメータである<font color="red">**`dtype`**</font>で **`numpy`** で8bitデータを指している **`np.uint8`** を指定しました。
:::

## `γ`補正からのルックアップテーブルの作成方法

[**ガンマ補正の方法**](#ガンマ補正の方法)で紹介した`γ`補正の公式である

> ```math
> Y＝255\times\Bigl(\frac{X}{255}\Bigl)^\frac{1}{\gamma}
> 
> ```
> ここで、
> ```math
> Y:γ補正後のピクセル値
> ```
> ```math
> X:γ補正前のピクセル値
> ```
> ```math
> γ:ガンマ補正値
> ```

の公式を使って、 **`γ`補正の計算結果を格納する配列の作成方法**で紹介した配列に計算結果を**0～255**までループ処理で逐次代入して作成しました。

# ガンマ補正の処理方法
こちらのソース

https://pystyle.info/opencv-tone-transform/#outline__3

によると、<font color="red">**`OpenCV`**</font>の<font color="red">**`cv2.LUT`**</font>を使うことで**ルックアップテーブルをもとにした階調変換**ができるそうです。
この方法で<ins>ルックアップテーブルを使ってリアルタイム画像の階調変換</ins>を行いました。

# リアルタイム画像のtkinterでの表示方法
## `OpenCV`の画像の`tkinter`での使用方法
こちらのソース

https://daeudaeu.com/pil_cv2_tkinter/#PIL_Tkinter-2

によると、<font color="red">**`PIL(pillow)`**</font>の<font color="red">**`ImageTk`**</font>モジュールの<font color="red">**`PhotoImage`**</font>クラスを使うことで<font color="red">**`tkinter`**</font>の画像オブジェクトに変換できるそうです。

また、こちらのソース

https://daeudaeu.com/pil_cv2_tkinter/#OpenCV2_PIL-2

によると、次の手順で<font color="red">**`OpenCV`**</font>のデータを<font color="red">**`tkinter`**</font>で使えるデータに変換できるそうです。
1. <font color="red">**`OpenCV`**</font>の画像データをBGR色空間からRGB色空間に<font color="red">**`cv2.cvtColor`**</font>で変換
1. <font color="red">**`OpenCV`**</font>の画像データのような<font color="red">**`numpy`**</font>配列のデータを<font color="red">**`PIL(pillow)`**</font>の<font color="red">**`Image`**</font>モジュールの<font color="red">**`fromarray`**</font>クラスを使って<font color="red">**`PIL(pillow)`**</font>の画像データに変換

この手順で<font color="red">**`OpenCV`**</font>のデータを<font color="red">**`PIL(pillow)`**</font>のデータにすることができるそうです。

これらの方法を使って、<font color="red">**`OpenCV`**</font>で得られたリアルタイム画像を<font color="red">**`tkinter`**</font>で表示できるように設定しました。

## 変換した画像の表示方法
**`OpenCV`の画像の`tkinter`での使用方法** で **`OpenCV`** の画像を **`tkinter`** で使えるように変換できました。この変換された画像を

こちらのソース

https://daeudaeu.com/tkinter_canvas_draw/#create_image

によると、<font color="red">**`tkinter`**</font>の<font color="red">**`Canvas`**</font>クラスの<font color="red">**`create_image`**</font>メソッドを使うと画像を<font color="red">**`tkinter`**</font>に表示できるそうです。
このメソッドを使って、画像を<font color="red">**`tkinter`**</font>上に表示させました。

また、こちらのソース

https://daeudaeu.com/tkinter_canvas_draw/#anchor

によると、<font color="red">**`anchor`**</font>オプションを使うことで、**画像の基準位置**を設定できるそうです。
このオプションの<font color="red">**`tkinter.NW`**</font>
を指定しました。この値を指定することで**画像の左上**を基準位置として設定しました。

:::note
**座標(0,0)** に基準位置が来るように設定したため**画像の左上**を基準位置として設定しました。
こうすることで、**webカメラの幅と高さに依存しない**位置に画像を配置できました。
:::

# 定期的に処理を実行する方法
こちらのソース

https://daeudaeu.com/tkinter_after/#i-2

によると、<font color="red">**`after`**</font>オプションを関数内で使うことで**定期的に処理を実行させる**ことができるそうです。
このメソッドを使って、<ins>処理を定期的に実行</ins>させました。

# ソースコード
下にソースコードを示します。おそらく[実行環境](#実行環境)で示した環境では動くはず。

<details><summary>ソースコード</summary>

```python:img_gamma.py
import cv2                               #webカメラの幅と高さの取得、webカメラの映像を反転させるためにインポート
import numpy as np                       #γ変換の初期値を設定するためにインポート
import tkinter                           #γ変換をGUIで操作できるようにインポート
import PIL.Image,PIL.ImageTk             #OpenCVで得られた画像をTkinterで扱えるようにインポート

cap = cv2.VideoCapture(0)                #webカメラを設定

app = tkinter.Tk()                       #tkinterのセットアップ
app.title("画像明るさ調整")              #「画像明るさ調整」という名前のウインドウを作成
app.geometry(str(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))+"x"+str(int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))))                  #Tkinterのウインドウの初期サイズをwebカメラの幅×高さに設定

canvas = tkinter.Canvas(app,width=cap.get(cv2.CAP_PROP_FRAME_WIDTH),height=cap.get(cv2.CAP_PROP_FRAME_HEIGHT))              #webカメラの映像を表示させる範囲の設定(大きさ：webカメラの幅×
                                                                                                                            #高さに設定)

canvas.pack()                                                                                                               #webカメラの映像を表示させる範囲の表示

var_scale = tkinter.DoubleVar()                                                                                          #Double(浮動小数点数(実数)型でスライドバーの値を取得

#最小値1.0、最大値3.0、刻み幅0.01、値がvar_scale、向きが横向き、背景色が青色、文字色が黄色、枠線の色が青色、目盛の間隔が0.1、長さがwebカメラの幅のスライドバーをappの(x=0,y=0)に設置
#夜間にプログラムを走らせ実装したところ3.0以上は必要ないと考えたため最大値3.0とした
scale = tkinter.Scale(app,from_=1.0,to=3.0,resolution=0.01,variable=var_scale,orient=tkinter.HORIZONTAL,bg='blue',fg='yellow',highlightbackground='blue',tickinterval=0.1,length=cap.get(cv2.CAP_PROP_FRAME_WIDTH)).place(x=0,y=0)

def gamma_trans(event=None):                        #Tkinterの関数の定義(関数の定義をすることで再帰的に処理を実行(こうすることでfor文でのループ処理ができるようになる))
	_,img = cap.read()                              #webカメラから1フレーム取得
	img = cv2.flip(img,1)                           #取得したフレームを左右反転
	gamma = var_scale.get()                         #スライドバーで設定した値を取得
	img2gamma = np.zeros((256,1),dtype=np.uint8)    #256行1列の値がすべて0のリストを作成(OpenCVの色空間の値の範囲は0～255の符号なし8bitの数値であるためdtypeにnp.uint8を指定)

	for i in range(256):                            #0～255まで処理を実行
		
		'''
		γ補正の式
		
		γ_new=255×(X/255)^(1/γ)
		
		γ_new:γ補正後の画素値
		X:ガンマ補正前の画素値
		γ:γ補正値
		
		をもとにルックアップテーブル(LUT)を作成
		'''
		
		img2gamma[i][0] = 255 * (float(i)/255) ** (1.0 /gamma)          #img2gammaの先頭の値に255×(iをfloat(浮動小数点数(実数)型に型変換)したもの/255)^(1.0/スライドバーで指定したγの値)
		                                                                #小数部分が切り捨てられた状態(整数)でimg2gammaが取得される(dtypeをnp.uint8にしているため)

	gamma_img = cv2.LUT(img,img2gamma)                                  #webカメラから得られたフレームをimg2gammaをルックアップテーブル(LUT)として画像処理

	app.img = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(cv2.cvtColor(gamma_img, cv2.COLOR_BGR2RGB)))             #Tkinterのウインドウのwebカメラを表示させる範囲にgamma_imgを設定
	                                                                                                                    #PIL.Image.fromarrayで画像を指定(PillowとOpenCVの色空間が違うので
	                                                                                                                    #変換)
	canvas.create_image(0,0,image=app.img,anchor=tkinter.NW)                                                            #画像の座標を(0,0)(原点は画像の左上端)に表示する画像をapp.imgに
	                                                                                                                    #基準位置を画像の左上に設定
	app.after(1,gamma_trans)                                                                                            #1ms間隔でgamma_transを実行(この処理がないとリアルタイムなので
	                                                                                                                    #処理が重すぎて固まる)

gamma_trans()       #この部分がないとTkinter上にwebカメラからのリアルタイムの映像が表示されない(関数内でTkinterでの画像表示も組み込んでいるため)
app.mainloop()      #GUIの表示(この処理がないと一瞬表示されて消えるので表示されていないように見える)
```
</details>

# 結果
下に結果を示します。

<details><summary>実行結果</summary>
<iframe width="560" height=315" src="https://www.youtube.com/embed/Lacg48cuWFc?si=pXi9Xi_39dezBFN6?mute=1&controls=0&rel=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope;" allowfullscreen></iframe>

</details>

# まとめ
今回は、[**前回のTwitter(X)のアンケート**](https://twitter.com/0ca00118726208m/status/1695006241549058293)でトップだった<font color="red"><ins>**動画像処理**</ins></font>から<font color="red"><ins>**webカメラから得られた映像に**</ins>**`γ変換`**<ins>**をかけて明るくした<font color="red">リアルタイム</font>の動画を**</ins>**`Tkinter`**<ins>**を用いて表示させ**</ins>**`γ`**<ins>**の値を**</ins>**`Tkinter`**<ins>**の**</ins>**`tkinter.Scale`**<ins>**で調整させる**</ins></font>プログラムを作成しました。
この記事が実際に役に立つかどうかは分かりませんが、誰かの役に立ってくれると嬉しいです。
記事を執筆する余力があれば、<ins>次回も記事を投稿する予定</ins>です。
次回の予定としては、[**今回のTwitter(X)のアンケート**](https://twitter.com/0ca00118726208m/status/1697546075236864130)でトップだった<font color="red"><ins>**ファイル操作**</ins></font>から **`HTML`** <ins>**で書かれた文字列から**</ins> **`HTML`** <ins>**タグを取り除いて**</ins> **`Windows`** <ins>**のメモ帳に**</ins> **`HTML`** <ins>**タグのない文章を書き込む**</ins><ins>(テキストファイル名には、**生成時の日付**が入っている)</ins>プログラムを作成できたのでそれに関する記事を投稿予定です!!