【plotlyで画像分析いろいろ】plotlyで動的な可視化をする【python,画像】



#plotlyで画像を簡単に分析してみます



![dd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2d3b3b41-f1e2-a36b-3fcc-0db5838d6ef5.gif)








#環境

python==3.8
plotly==4.10.0
scikit-image==0.17.2
requests==2.24.0
Pillow==7.2.0
matplotlib==3.3.2



#よくある画像の扱い

まずpillowつかっていきます


```python
import matplotlib.pyplot as plt
from PIL import Image
import requests
import io

url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg'
img = Image.open(io.BytesIO(requests.get(url).content))

plt.figure(figsize=(5,5))
plt.subplot(111)
plt.imshow(img)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e2432cca-3395-34ee-1ba8-bb9332d005f5.png)


いつものmatplotによる画像表示ができました
白黒にしましょう


```python
gray_img = img.convert('L')

plt.figure(figsize=(5,5))
plt.subplot(111)
plt.imshow(gray_img)
```


imageオブジェクトはconvertを使って白黒にできます



#skimageとplotlyを使った画像処理


plotlyで画像の表示をすると嬉しい所は拡大等ができることです


```python
import plotly.express as px
from skimage import io
img_sk = io.imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg')
fig = px.imshow(img_sk)
fig.show()
```


![dd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2d3b3b41-f1e2-a36b-3fcc-0db5838d6ef5.gif)



pillowで読み込んだイメージも扱えます

```python
fig = px.imshow(gray_img, color_continuous_scale='gray')
fig.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e95421be-09ed-a52c-baf3-ac97704d9a2c.png)



#画像の中で等高線をつくる

画像の輝度に対して等高線を付けることができます

Zの値に対して色を付ける等高線(Contour)plot
startからendまでの値を対象に監視します
sizeで等高線の間隔を指定
endとsizeを同じにすることで、指定の値になる部分を抽出できます
つまり輪郭抽出などに使える



```python
import plotly.graph_objects as go
fig = px.imshow(gray_img, color_continuous_scale='gray')
fig.add_trace(go.Contour(z=gray_img, showscale=True,
                         contours=dict(start=0, end=30, size=30,coloring='lines'),line_width=1))

fig.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d064203b-6022-0964-5c6c-d5907f800f0e.png)




```python
import plotly.express as px
import plotly.graph_objects as go
from skimage import data
img_camera = data.camera()
fig = px.imshow(img_camera, color_continuous_scale='gray')

fig.add_trace(go.Contour(z=img_camera, showscale=False,
                         contours=dict(start=0, end=70, size=70, coloring='lines'),
                         line_width=2))
fig.show()
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/7c9f2ee7-5fa2-938a-2f1a-93d13133ec17.png)




#色チャネルのヒストグラムをplotlyからつくる


```python
from plotly.subplots import make_subplots
from skimage import data

img_sk.shape

#(240, 240, 3)

plt.imshow(img_sk)


img_r = img_sk.copy()
img_r[:, :, 1] = 0
img_r[:, :, 2] = 0
plt.imshow(img_r)

img_g = img_sk.copy()
img_g[:, :, 0] = 0
img_g[:, :, 2] = 0
plt.imshow(img_g)

img_b = img_sk.copy()
img_b[:, :, 0] = 0
img_b[:, :, 1] = 0
plt.imshow(img_b)

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e5aff854-5bbb-7884-05d4-900281a64347.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/37bbaf84-0790-105c-293b-319a7a88b4bf.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/dc142307-9531-fa94-834d-0326acbce08e.png)





![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2c8912c7-b06a-edbe-7366-27a1aef3c5b1.png)







0以外をhistに

```python
ff=go.Figure()
ff.add_trace(go.Histogram(x=img_r.flatten()[img_r.flatten()!=0],marker_color='red',name='red'))
ff.add_trace(go.Histogram(x=img_g.flatten()[img_g.flatten()!=0],marker_color='green',name='green'))
ff.add_trace(go.Histogram(x=img_b.flatten()[img_b.flatten()!=0],marker_color='blue',name='blue'))
ff.update_layout(barmode='overlay')
ff.update_traces(opacity=0.3)
ff.update_layout(height=400)

ff.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/78788a57-6e0a-5693-f429-3bb9bc310549.png)





拡大してみると10以下がメインのようなので10以上の分布を確認


```python
ff=go.Figure()
ff.add_trace(go.Histogram(x=img_r.flatten()[img_r.flatten()>10],marker_color='red',name='red'))
ff.add_trace(go.Histogram(x=img_g.flatten()[img_g.flatten()>10],marker_color='green',name='green'))
ff.add_trace(go.Histogram(x=img_b.flatten()[img_b.flatten()>10],marker_color='blue',name='blue'))
ff.update_layout(barmode='overlay')
ff.update_traces(opacity=0.3)
ff.update_layout(height=400)

ff.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9470f8db-a4c3-f65d-7841-755483a1d8de.png)



綺麗に分かれる場合だとこんな感じになる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/246ff643-54ab-7b97-939b-1f2e6dc30e0b.png)



#白黒に対しての確認は以下


```python
from skimage.color import rgb2gray

gray_img = rgb2gray(img_sk)


ff=go.Figure()
ff.add_trace(go.Histogram(x=gray_img.flatten()[gray_img.flatten()!=0],marker_color='pink',name='gray'))
ff.update_layout(barmode='overlay')
ff.update_traces(opacity=0.8)
ff.update_layout(height=400)

ff.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e4051f08-90de-c8d9-e4ed-2e31ade82ec9.png)



```python
ff=go.Figure()
ff.add_trace(go.Histogram(x=gray_img.flatten()[gray_img.flatten()>0.1],marker_color='pink',name='gray'))
ff.update_layout(barmode='overlay')
ff.update_traces(opacity=0.8)
ff.update_layout(height=400)

ff.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ac1a926d-b496-7e68-cca5-28a0144dd540.png)




#ついでに図中に画像を表示する方法


グラフの全面にアピール

```python
import plotly.express as px
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])

fig.add_layout_image(
        dict(
            source="https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg",
            xref="x",
            yref="y",
            x=0,
            y=16,
            sizex=4,
            sizey=15,
            sizing="stretch")
)

fig.update_xaxes(title_text="picture No")
fig.update_yaxes(title_text="view par day", hoverformat=".3f")

fig.show()
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/f243afc3-7576-8ce4-e9e7-4a10ca882fe8.png)



背面(below)でそっとアピール


```python
import plotly.express as px
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])

fig.add_layout_image(
        dict(
            source="https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg",
            xref="x",
            yref="y",
            x=0,
            y=16,
            sizex=4,
            sizey=15,
            sizing="stretch",
            opacity=0.5,
            layer="below")
)

fig.update_xaxes(title_text="picture No")
fig.update_yaxes(title_text="view par day", hoverformat=".3f")

fig.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/5d7160aa-5e97-0477-8883-af7a18e17ce8.png)


小さくして棒を付けたりテキストをいれたりする

```python
import plotly.express as px
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])

fig.add_layout_image(
        dict(
            source="https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg",
            xref="x",
            yref="y",
            x=1.68,
            y=16,
            sizex=3,
            sizey=3)
)

fig.update_layout(
    annotations=[
        dict(
            x=0.5,
            y=0.8,
            xref="paper",
            yref="paper",
            showarrow=True,
            arrowhead=0,
            opacity=0.5,
            ax=190,
            ay=100,
        )#,
#        dict(x=,y=,xref="paper",yref="paper",showarrow=True,arrowhead=0,opacity=0.5,ax=,ay=,)
    ]
)

fig.update_xaxes(title_text="picture No")
fig.update_yaxes(title_text="view par day", hoverformat=".3f")

fig.show()
```

画像のlayout imageはplotの位置に準ずる
plotのx,y軸が画像の左上位置x,yに相当する

棒線は画像の左下を0,0
中心を0.5,0.5とする
ax,ayは棒線の長さを表しており、指定位置x,yからx軸方向とy軸方向に伸ばした棒のベクトル合成した位置に伸びる



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2f3f923e-0fd2-27da-92a3-f7f1da5e786b.png)



#以上

とりあえず動かせればなんでも楽しい説