❄️

Streamlit in Snowflake (SiS) で画像検索を実現しよう Part1 -画像ギャラリーアプリを作る-

2024/09/22に公開

はじめに

世の中にはドキュメントや画像、動画、音声データなどの非構造化データが大量にあります。データ活用の世界においてこれらの非構造化データをそのまま利用することは少なく、メタデータなどを抽出して構造化データ化してから活用することが多いのではないかと思います。

今回は Streamlit in Snowflake を用いて画像検索を実現していきたいと思います。まずはその第一歩として画像ギャラリーアプリを作成し、Streamlit in Snowflake で画像データを簡単に活用できることを確認していきましょう。

機能概要

実現したいこと

  • ★Streamlit in Snowflake で画像データを表示する
  • Streamlit in Snowflake で画像に説明文を追加する
  • 画像の説明文を元にベクトルデータを生成する
  • Streamlit in Snowflake で画像検索を行う

★:Part1で実現する範囲

Part1 の完成イメージ


手元の写真を用いたイメージギャラリー

前提条件

  • Snowflake アカウントがあること

基本の確認

Streamlit in Snowflake で画像を表示する選択肢

Streamlit in Snowflake で画像を表示するためには主に以下5つの選択肢があります。

  1. Streamlit in Snowflake のデフォルト内部ステージを用いる
  2. 他の内部ステージを用いる
  3. 外部ステージを用いる
  4. テーブルに画像をテキストデータとして保存する
  5. 外部サイトの画像を参照する

1と2についてこれからやり方をご紹介します。(3 - 5については割愛します)

1. Streamlit in Snowflake のデフォルト内部ステージを用いる

一番シンプルな方法です。Streamlit in Snowflake のコードも分かりやすいので今回の記事ではこちらの方法で実装していきます。

Streamlit in Snowflake のアプリケーションを作成すると自動的に内部ステージが作成されます。この内部ステージに test_image.jpg という画像ファイルをアップロードしました。


SiS アプリの内部ステージに画像をアップロード

続いてこの画像を表示する最小限の Streamlit in Snowflake ソースコードはこちらです。とてもシンプルです。

import streamlit as st
from snowflake.snowpark.context import get_active_session

# Snowflakeセッションの取得
session = get_active_session()

# 画像の表示
st.image('test_image.jpg')

実行結果は以下の通りとなります。


実行結果

(もっと言えばアクティブセッションも不要なので以下2行でも同じ結果を得られます)

import streamlit as st
st.image('test_image.jpg')

2. 他の内部ステージを用いる

Streamlit in Snowflake のデフォルト内部ステージは手軽ですが、このままだと1つのアプリケーション専用の画像データという位置付けとなります。そのため、複数のアプリケーションなどで共有したい画像データの場合は別途画像格納用の内部ステージを作成すると便利です。

Snowsight でスキーマを選択した後、作成 > ステージ > Snowflake による管理を選択します。


Snowsight 上から内部ステージを作成

ステージ名を適宜入力し、ディレクトリテーブルを有効化し、サーバー側の暗号化にチェックを入れ、作成ボタンを押します。アクセスは署名付き URL を用いるため、必ずサーバー側の暗号化を有効化してください。


内部ステージのプロパティを設定

この画像を表示する最小限の Streamlit in Snowflake ソースコードはこちらです。署名付き URL を生成するなどしている点が1の手順と異なる点です。

import streamlit as st
from snowflake.snowpark.context import get_active_session

# Snowflakeセッションの取得
session = get_active_session()

# 署名付きURLの生成
img_df = session.sql(f"""
SELECT
RELATIVE_PATH AS FILE_NAME,
GET_PRESIGNED_URL(@IMAGE, RELATIVE_PATH) AS IMG_URL
FROM DIRECTORY(@IMAGE)
"""
).collect()

# 画像の表示
st.image(img_df[0]["IMG_URL"])

実行結果は1と同様なので省略します。

手順

新規で Streamlit in Snowflake のアプリを作成

Snowsight の左ペインから『Streamlit』をクリックし、『+ Streamlit』ボタンをクリックし SiS アプリを作成します。

SiS アプリが起動したら、ブラウザに表示されている URL を確認します。URL 末尾は

https://(中略)/streamlit-apps/<DB名>.<スキーマ名>.<Streamlitオブジェクト名>

となっているため、Streamlit オブジェクト名を手元に控えます。
※ SiS アプリのタイトルとは異なるため注意してください。
SHOW STREAMLITS コマンドで確認することも可能です。

デフォルトの内部ステージに画像をアップロードする

Streamlit in Snowflake のアプリ作成時に自動的に作られる内部ステージに画像をアップロードします。内部ステージ名は先ほど確認した Streamlit オブジェクト名となります。今回は /image というプレフィックス (フォルダ) を切って、その中に26枚の写真をアップロードしました。


/image 配下に画像をアップロード

Streamlit in Snowflake のアプリを実行

Streamlit in Snowflake アプリの編集画面で以下コードをコピー&ペーストで貼り付けて完了です。

import streamlit as st
import os
from snowflake.snowpark.context import get_active_session

# Snowflakeセッションの取得
session = get_active_session()

# Streamlitのページ設定
st.set_page_config(layout="wide", page_title="Image Gallery")

# アプリケーションタイトル
st.title("Image Gallery")

# 画像フォルダのパス
IMAGE_FOLDER = "image"

# 画像データの取得関数
@st.cache_data
def get_image_data():
    image_files = [f for f in os.listdir(IMAGE_FOLDER) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif'))]
    return [{"FILE_NAME": f, "IMG_PATH": os.path.join(IMAGE_FOLDER, f)} for f in image_files]

# 列数の選択
num_columns = st.slider("Width:", min_value=1, max_value=5, value=4)

# ギャラリーの表示
img_df = get_image_data()
cols = st.columns(num_columns)
for i, img in enumerate(img_df):
    with cols[i % num_columns]:
        st.image(img["IMG_PATH"], caption=None, use_column_width=True)

最後に

いかがだったでしょうか?簡単な手順で画像ギャラリーを作成できることが分かっていただけたのではないかと思います。

しかし、まだ画像データの活用には至っているとは言い難いため、以下 Part2 の記事で画像データにキャプションを追加し画像データを活用できるようにしていきましょう。

https://zenn.dev/tsubasa_tech/articles/b6b9928d33ae58

宣伝

X で Snowflake の What's new の配信してます

X で Snowflake の What's new の更新情報を配信しておりますので、是非お気軽にフォローしていただければ嬉しいです。

日本語版

Snowflake の What's New Bot (日本語版)
https://x.com/snow_new_jp

English Version

Snowflake What's New Bot (English Version)
https://x.com/snow_new_en

変更履歴

(20240922) 新規投稿

Discussion