フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

pythonのrembgを利用して背景を削除して新しい背景に合成させる

初めに

  • 下記のrembgを利用して画像の背景を切り抜き異なる背景と合成するサンプルを作成する

https://github.com/danielgatis/rembg

インストール

pip install rembg

サンプルコード

from rembg import remove
from PIL import Image

# 背景を除きたい画像(人混みなどの画像はうまく切り出せない)
base_file = 'base.jpg'
backgroud_without_output_file = 'without_background.png'
base_image = Image.open(base_file)
output = remove(base_image)
output.save(backgroud_without_output_file)

# 背景画像を開く
background_path = 'backgroud.jpeg'
background = Image.open(background_path)

# 背景画像をリサイズ
background = background.resize(output.size, Image.ANTIALIAS)

# 合成
combined = Image.alpha_composite(background.convert('RGBA'), output)

# 結果を保存
combined_path = 'combined_image.png'
combined.save(combined_path)

実行結果

上記のコードで生成された画像

利用した画像

  • 下記の画像を利用させて頂き検証しました。

www.photo-ac.comwww.photo-ac.com

stock.adobe.com

docker環境のpythonでdiffusersを動かす

はじめに

  • docker環境のpythonでdiffusersを動かす。

インストールするパッケージ

- diffusersだけ動かすならdiffusersとpytorch_lightningだけでも良い

fastapi[all]
diffusers
transformers
accelerate
safetensors
omegaconf
pytorch_lightning

Dockerfile

  • pytorchのインストールするコマンドは、各自の動作させる環境にあわせてコマンドを変える

pytorch.org

FROM tiangolo/uvicorn-gunicorn-fastapi:latest

RUN apt-get update && \
    apt-get install -y libpq-dev gcc

WORKDIR /app

RUN python -m pip install --upgrade pip setuptools wheel

## pytorchのインストールするコマンドは環境にあわせてコマンドを変える
RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

COPY requirements.txt /app/requirements.txt

RUN pip install -r requirements.txt && \
    pip install diffusers

docker-compose.yaml

version: '3.9'
services:
  backend:
    container_name: backend
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    tty: true
    volumes:
      - ../backend:/app
    networks:
      - app-network

pythonのコード

import torch
import datetime
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
from diffusers.models import AutoencoderKL

# モデルの指定
model_id = "CompVis/stable-diffusion-v1-4"

if torch.cuda.is_available():
    device = "cuda"
else:
    device = "cpu"

# モデルの読み込み
pipe = StableDiffusionPipeline.from_pretrained(model_id)

# スケジューラーの設定
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)

# デバイスの設定
pipe = pipe.to(device)


# 画像生成
# 
#例 payloadの値
# prompt='A small cabin on top of a snowy mountain in the style of Disney, artstation' negative='low quality, ugly' count=1 width=512 height=512 scale=7.5 steps=30 seedList=[5335531]

images_list = pipe(
  [payload.prompt] * payload.count,
        width=payload.width,
        height=payload.height,
        negative_prompt=[payload.negative] * payload.count,
        guidance_scale=payload.scale,
        num_inference_steps=payload.steps,
        generator=generator_list,
)

images = []
# 画像を保存
for i, image in enumerate(images_list["images"]):
 file_name = (
       "./outputs/image_sample.png"
       )
      image.save(file_name)
      images.append(image)

作成された画像

感想

  • ローカルで画像を生成すると2分ほど掛かる

Laravel・S3署名付きURLを生成する

はじめに

  • Laravelで署名付きURLを生成する。

S3にファイルを保存

  • S3にファイルをアップロードする際にタグの情報を付与することが出来る。タグの情報は署名付きURLを取得する際にタグと同じ条件のユーザーのみ取得できるようにするためにファイルにタグを付与している
      $object_key = Storage::disk('s3')->putFile($this->user->id.'/chat', $request->file('file'), [
        'Tagging' => 'hogehogeid='. $this->hogehogeid
      ]);

S3に保存されているファイルを署名付きURLの生成方法

  • 署名付きURLの生成メソッド
    protected function _getS3SignatureImageURL($key)
    {
      // S3Clientを設定
      $s3Client = new S3Client([
          'version' => 'latest',
          'region' => config("filesystems.disks.s3.region"),
          'credentials' => [
              'key' => config("filesystems.disks.s3.key"),
              'secret' => config("filesystems.disks.s3.secret"),
          ],
      ]);
      $bucket = config("filesystems.disks.s3.bucket");

      // タグの情報を取得
      $tags = $s3Client->getObjectTagging([
        'Bucket' => $bucket,
        'Key' => $key,
      ]);
      // hogehogeidとは異なるタグが設定されている場合、署名付きURLはNULLで返す
      if ($tags['TagSet'][0]['Value'] === $this->hogehogeid) {
        // S3オブジェクトのキーを指定して、署名付きURLを生成
        $expires = '+180 minutes'; // 有効期限
        $cmd = $s3Client->getCommand('GetObject', [
            'Bucket' => $bucket,
            'Key' => $key,
        ]);
        $request = $s3Client->createPresignedRequest($cmd, $expires);
   // 署名付きURLを取得する
        $presignedUrl = (string)$request->getUri();
        return $presignedUrl;
      } else {
        return null;
      }
    }

Vueでタグを入力および削除できるコンポーネントを作成する

はじめに

  • 下記のようなタグ入力フォームを作る

コンポーネント作成

  • components/TagInput.vue ファイルを作成する
<template>
  <div class="current-user-tag-wrapper">
    <v-chip class="current-user-tag-chip"" v-for="(tag, index) in newTags" :key="index" close @click:close="removeTag(index)">
      {{ tag }}
    </v-chip>
    <v-text-field
      v-model="newTag"
      @keydown.enter="addTag"
      label="タグを入力してください"
    ></v-text-field>
  </div>
</template>

<script>
export default {
  data() {
    return {
      newTags: [],
      newTag: "",
    };
  },
  methods: {  
    addTag() {
      if (this.newTag.trim() !== "") {
        this.newTags.push(this.newTag.trim());
        this.newTag = "";
      }
      this.$emit('changeTags',this.newTags)
    },
    removeTag(index) {
      this.newTags.splice(index, 1);
      this.tags = this.newTags
      this.$emit('changeTags', this.newTags)
    },    
  },
};
</script>
<style>
※Vutifyを利用しております
</style>

コンポーネントの呼び出し

  • pages/sample.vueファイルに下記のように記述する
<template>
        (省略)
       <TagInput @changeTags="receiveTags"/>
   (省略)
</template>

<script>
<script>
import TagInput from '@/components/TagInput.vue'

export default {
  data() {
      // https://github.com/apertureless/vue-chartjs/issues/17
      return {
        tags: '',
      }
  },
  methods: {
    receiveTags(tags){
      this.tags = tags
    },
  }
}
</script>

LaravelのJob / PHPでMP4の動画再生時間を取得する

MP4の動画再生時間を取得する

 インストール

composer require james-heinrich/getid3

 サンプルコード

use getID3;

// 再生時間を取得し秒数からH:i:s形式にして変換する
public function getMp4Duration($filePath)
{
    $getID3 = new getID3;
    $file = $getID3->analyze($filePath);
    $duration = $file['playtime_seconds'];
    $result = Carbon::parse($duration)->format('H:i:s');
    return $result;
}
````

# LaravelのJobのいろいろ

- ジョブのタイムアウトはデフォルトは300秒なので、1時間にする

class HogehogeJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public $timeout = 3600; // 1 hour
- ジョブはキャッシュが残るので、キャッシュをクリアしながら開発しないといけない。

php artisan queue:restart php artisan queue:work


## supervisor

- `php artisan queue`のコマンドを実行するのは大変なので、下記のsupervisorを利用して解消できる

sudo yum install supervisor

PHP環境でimagemagicをインストールしてgoogle driveにある画像を取得する方法(Redhat編・メモ・結論できなかった)

ImageMagicのインストール

  • 下記をインストールする際は、EC2のメモリ容量がt2.smallは最低限必要だった。  下記のコマンドだけで完了できたが他にもGDライブラリをインストールする必要がああった。
sudo dnf install epel-release
sudo dnf install ImageMagick ImageMagick-devel 
  • imagemagicをインストールすることができると下記のコマンドを実行することができる
convert -version

PHPのGD関連のライブラリをインストールする

  • PHPでImageMagicを利用する際にGDライブラリをインストールする必要がある

EPEL リポジトリを追加

sudo yum install epel-release

Remi リポジトリを追加:

sudo yum install http://rpms.remirepo.net/enterprise/remi-release-8.rpm

PHP 8.1-gd パッケージをインストール:

sudo yum install php-gd

php.iniの設定

  • /etc/php.iniファイルに下記の記述を追記する
[gd]
extension=gd.so

※Nginx,php-frmを再起動する

Laravelのパッケージをインストールする

composer require intervention/image
php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravelRecent"

コード

                    $interv = Image::make("https://drive.google.com/file/d/10AYZs5lNEJY2mtaCn-Ug-WlKU9DIznR1/view")->encode('jpg');

上記のパッケージでgoogleドライブ上にある画像を取得したかったがうまく取得できなかった。

github.com

EC2のサイズアップ手順

サイズアップするEC2を選択し停止する

ステータスが停止済みになったら

インスタンスタイプの指定

  • t2.microからt2.smallに変更する

停止中のインスタンスを起動する

  • 起動にはしばらく時間がかかるが、インスタンスサイズを変更することができました。