0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

matplotlibでRGBヒストグラムを描画し、画像に埋め込んでPythonによりストリーミング配信する

Last updated at Posted at 2024-12-03

前回の記事では、Rspberry Pi 5 + USBカメラで撮影した画像を、PythonのFlaskパッケージを利用することによりHTTPでストリーミング配信できることを紹介しました。今回は、 撮影した画像に、その画像のRGBヒストグラムを重ねて出力する プログラムの例を紹介します。本プログラムにより、以下のような表示を得ることができます。

Screencast-from-2024-12-03-19-53-05.gif

プログラムの実行方法

ヒストグラム付きのストリーミング映像を配信するWebサーバーのPythonコードをGitHubへpushしました。下記の手順でお試しいただけます。実装は、「 opencv-web-sandbox/opencv-web-sandbox/web_root/views/streams.py 」に埋め込んでいます。Pythonでapp.pyを実行した後はRaspberry Piの「 [IPアドレス]:5000/streams/stream 」へアクセスすることにより、ヒストグラムを含んだWebカメラの映像のストリーミング配信を見ることができます。

# ソースコードをGitHubより取得する
$ git clone https://github.com/xtrizeShino/opencv-web-sandbox.git
$ cd opencv-web-sandbox

# v0.1.0のタグのソースコードを取得
$ git checkout -b v0.2.0 refs/tags/v0.2.0

# 作業ディレクトリへ移動する
$ cd opencv-web-sandbox

# uvの仮想環境をセットアップする
$ uv sync

# 仮想環境に入る
$ . .venv/bin/activate

# app.pyを実行
(opencv-web-sandbox) $ python app.py
# * Serving Flask app 'web_root'
# * Debug mode : off
# * Running on akk addresses (0.0.0.0)
# * Running on http://127.0.0.1:5000
# * Running on http://192.168.10.140:5000
# Press CTRL+C to quit

############
###【終了するにはCtrl+c】
############

パッケージ管理ツール「uv」については以下をご参照ください。

ソースコードの概略

OpenCVは、cv2.calcHistによりヒストグラムを生成することができます。ただし、撮影した画像はRGBの3要素から構成されていますので、まず、撮影した画像をRGBチャンネルに分解します。分解したそれぞれの要素からヒストグラムを生成し、matplotlib.pyplotを利用してグラフを作成しました。

作成したグラフはio.BytesIO()を利用して、描画データを画像データへと変換し、元画像と同じ形式であるnumpy.array型に変換しました。最後にちょうど良い埋め込みサイズへとリサイズしています。こうして作られた画像データを、imageproc_resize_and_histのcv2.warpAffineにより、元画像に結合します。

# generate Histgram Image from input image
def generate_hist_image(image):
    # divide Image to RGB channels
    b, g, r = image[:,:,0], image[:,:,1], image[:,:, 2]
    # generate Histgram as each RGB
    hist_b = cv2.calcHist([b],[0],None,[256],[0,256])
    hist_g = cv2.calcHist([g],[0],None,[256],[0,256])
    hist_r = cv2.calcHist([r],[0],None,[256],[0,256])
    # write Plot
    plt.plot(hist_r, color='r', label="r")
    plt.plot(hist_g, color='g', label="g")
    plt.plot(hist_b, color='b', label="b")
    # set xlim, ylim
    plt.xlim(0, 255)
    # convert Histgram to numpy array
    buf = io.BytesIO()
    plt.savefig(buf, format='png')
    buf.seek(0)
    enc = np.array(Image.open(buf).convert('RGB'))
    plt.gca().clear()
    # resize
    enc = cv2.resize(enc, (320, 240))
    return enc

# Callback function for Image Proc            
def imageproc_resize_and_hist(image):
    # resize Image
    image = cv2.resize(image, (1024, 768))
    h, w = image.shape[:2]
    # put Histgram on Image
    enc = generate_hist_image(image)
    # set offset
    dx=10
    dy=10
    # set Matrix for affine
    M = np.array([[1, 0, dx],[0, 1, dy]], dtype=float)
    # put Image by warpAffine
    image = cv2.warpAffine(enc, M, (w, h), image, borderMode=cv2.BORDER_TRANSPARENT)
    # output image
    return image

簡単でしたね!何かの際にお役立てください!

参考にさせていただきました記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?