Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

フォルダ内の写真のファイル名を撮影時刻に変更する

 デジカメ等で写真を撮ると「DSC-1234」のように連番のファイル名が付きますが、「DSC-9999」の次は「DSC-0001」となるため、ファイルを連続処理する場合など少し面倒です。ファイルのEXIF情報から撮影時刻を取得し、ファイル名を撮影時刻に変更します。

関連記事

写真のexifから緯度・経度を取得する

準備

 ファイル名を変更したい画像ファイル(デジカメで撮影した写真)3つを、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'rename'を作成しその中に保存しました。

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 6.4.6
  • Python 3.10.4
  • Pillow 9.1.0
コード

 フォルダ'rename'に保存されたファイルをリスト化し、ひとつづつ読みだしPillowのImage.openで開きます。開いた画像ファイル(写真)に対して._getexif()メソッドでexif情報を取得します。画像ファイルを開いたままだとファイル名変更の際エラーとなるのでImage.closeで閉じます。exif情報のタグ306の撮影時刻情報を取得、撮影時刻情報は、コロンで区切られたYYYY:MM:DD hh:mm:ss(年:月:日 時:分:秒)の書式なので、そこからコロンを除いたYYYYMMDD-hhmmssの形式でファイル名を作成、ファイル名を変更します。

import os 
from PIL import Image

# renameフォルダ中のファイルをリストに
files = os.listdir('rename/')

# renameフォルダ中のファイルを順番に読みだす
for file in files:
    img = Image.open('rename/'+file) # 画像を開く
    exif = img._getexif() # EXIF情報を得る
    img.close() # 画像を閉じる
    
    # EXIF情報からタグ306(撮影時刻)を抽出
    # コロンを除いたデータからファイル名作成
    for tag, value in exif.items():
        if tag == 306: 
            filename = (value[0:4]
                       +value[5:7]
                       +value[8:10]
                       +'-'
                       +value[11:13]
                       +value[14:16]
                       +value[17:19])

            # 撮影時刻から作成したファイル名に変更する
            os.rename('rename/'+file, 'rename/'+filename+'.jpg')      
実行結果

ファイル名が撮影時刻に変更されます。

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村

動画をキャプチャーしてタイムラプス動画を作成する

 動画をキャプチャーしてタイムラプス動画を作成します。ライブラリPyAutoGUIを使うとパソコン画面のスクリーンショットを取得できます。動画を再生しているパソコンのスクリーンショット画像を一定間隔で取得し、OpenCVで動画ファイルに書き込むことでタイムラプス動画を作成します。

関連記事

パソコンの画面を録画する

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 6.4.6
  • Python 3.10.4
  • pyautogui 0.9.53
  • numpy 1.21.5
  • OpenCV 4.5.5
コード

 コードを実行すると、まず12秒間スリープします。その間に取り込みたい動画を全画面表示します。その後0.5秒おきに全画面(ここでは1920x1080ピクセル)をキャプチャーしリストに格納します。360画面をキャプチャーした後、リストから1画像ずつ取り出しmp4形式で1920x1080、30fpsの動画を作成します。  なお、作成したタイムラプス動画の用途によりますが元動画の著作権には注意が必要です。このプログラムの動作確認にはYoutube
Unbelievable Most Beautiful Waterfalls | Drone | Free stock footage | Free HD Videos - no copyright
を用いています。こちらは「動画そのものを売る以外は自由に使用してかまわない」と説明されており著作権の点で問題がありません。

import time
import pyautogui
import cv2
import numpy as np

# 12秒スリープ
time.sleep(12)

# 動画のフレームレート
fps=30 

# キャプチャー領域
cap_region = (0,0, 1920, 1080)

# キャプチャー画像を格納するリスト
frames = []

# 0.5秒おきに画面をキャプチャーしリストに保存
for i in range(360):
    
    # 画面をキャプチャー
    cap = pyautogui.screenshot(region = cap_region)
    
    # pillow形式からOpenCV形式に変換
    img = cv2.cvtColor(np.array(cap), cv2.COLOR_RGB2BGR)
    
    # リストにキャプチャー画像を追加
    frames.append(img)

    # 0.5秒スリープ
    time.sleep(0.5)
        
# 保存用動画ファイルのフォーマット設定
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') 
out = cv2.VideoWriter('timelapse.mp4', fourcc, fps, (1920, 1080))         

# キャプチャー画像を読み出して出力動画ファイルに追記
for img in frames:        
    out.write(img) 

# 出力動画ファイルをクローズ    
out.release()      
実行結果

動画からタイムラプス動画が作成されます。

以下のサイトを参考にさせていただきました

機械系エンジニアの備忘録 > 【python】デスクトップ画面をキャプチャ(録画)する簡易ソフトを作る

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村

WAVファイルのミキシング

 ライブラリpydubを使うことで音声ファイルを操作できます。ボーカルのみ、ピアノのみの2つのwavファイルを合成しボーカルに伴奏を付けます。

環境
  • windows10 home
  • Jupyter notebook 6.4.11
  • Python 3.10.4
  • pydub 0.25.1
準備  

ライブラリpydubをインストールします。
以下の2つのwavファイルを、jupyter notebookファイル(***.ipynb)と同じディレクトリに保存しました。vocal.wavは、ニューラルネットワークを用いたフリーの歌声シンセサイザーNEUTRINOで生成した合成音声による歌、piano.wavは同じメロディラインをピアノで演奏したものです。
vocal.wav

piano.wav

コード
from pydub import AudioSegment

# ボーカルとピアノのwavファイルを読みだす
vocal = AudioSegment.from_file('vocal.wav')
piano = AudioSegment.from_file('piano.wav')

# ミキシングとファイル出力
output = vocal.overlay(piano, position=0)
output.export('song.wav', format='wav')
実行結果

 2つのwavファイルがミックスされ、ボーカルにピアノ伴奏が付きます。


このままだとピアノの音が大きすぎるので調整します。

コード

 読み込んだオーディオオブジェクトに対して-20とすることで音量を20dB下げることができます。

from pydub import AudioSegment

# ボーカルとピアノのwavファイルを読みだす
vocal = AudioSegment.from_file('vocal.wav')
piano = AudioSegment.from_file('piano.wav')

piano -= 20  # ピアノの音量を20dB下げる 

# ミキシングとファイル出力
output = vocal.overlay(piano, position=0)
output.export('song.wav', format='wav')
実行結果

ピアノの音量が下がりました。

以下のサイトを参考にさせていただきました

stackoverflow > How do I mix audio files using python?
TechAcademyマガジン > PythonのPydubを利用して音声ファイルを処理する方法を現役エンジニアが解説【初心者向け】

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村</

Wikipedia-APIでWikipediaの記事を取得する

 ライブラリWikipedia-APIWikipediaAPIを簡単に制御できるラッパーで、これを使うとWikipediaの記事の要約や全文を短いコマンドで取得できます。

環境
準備  

ライブラリWikipedia-APIをインストールします。


記事の要約(summry)を取得する場合。

コード

 まず、wikiという名前でwikipediaオブジェクトを生成し、その際言語として日本語を指定します('ja')。さらに記事のタイトル(ここでは「台風」)をパラメーターとしてpageオブジェクトを生成します。pageオブジェクトのsummaryプロパティを出力させることで要約が表示されます。

import wikipediaapi

wiki = wikipediaapi.Wikipedia('ja')
page = wiki.page('台風')

print(page.summary)  
実行結果

「台風」のページの要約が表示されます。

台風(たいふう、颱風、英: Typhoon)とは、熱帯低気圧のうち北西太平洋または南シナ海に存在し、かつ低気圧域内の最大風速が約17.2 m/s(34ノット(kt)、風力8)以上にまで発達したものを指す呼称。 強風域や暴風域を伴って強い雨や風をもたらすことが多く、ほとんどの場合、気象災害を引き起こす。上空から地球に向かって見ると反時計回りの積乱雲の渦からなる。超大型と呼ばれる台風は風速15m/sの強風域が半径800km以上と、とても大きな台風となる。「年別台風記事一覧」も参照。


記事の全文(text)を取得する場合。

コード

 まず、wikiという名前でwikipediaオブジェクトを生成し、その際言語として日本語を指定します('ja')。さらに記事のタイトル(ここでは「台風」)をパラメーターとしてpageオブジェクトを生成します。pageオブジェクトのtextプロパティを出力させることで全文が表示されます。

import wikipediaapi

wiki = wikipediaapi.Wikipedia('ja')
page = wiki.page('台風')

print(page.text)  
実行結果

「台風」のページのテキスト全文が表示されます。

台風(たいふう、颱風、英: Typhoon)とは、熱帯低気圧のうち北西太平洋または南シナ海に存在し、かつ低気圧域内の最大風速が約17.2 m/s(34ノット(kt)、風力8)以上にまで発達したものを指す呼称。 強風域や暴風域を伴って強い雨や風をもたらすことが多く、ほとんどの場合、気象災害を引き起こす。上空から地球に向かって見ると反時計回りの積乱雲の渦からなる。超大型と呼ばれる台風は風速15m/sの強風域が半径800km以上と、とても大きな台風となる。「年別台風記事一覧」も参照。
定義 気圧が最も低い位置を「気圧中心」といい、その位置と勢力で台風は定義される。温帯低気圧との最大の違いは、前線を伴っていないことである。


以下略

以下のサイトを参考にさせていただきました

pypi > Wikipedia-API
Men of Letters > Pythonでwikipedia-apiを使用し単一ページを取得する

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村</

Twitter APIでツイートを検索する

 Twitterはクレイピングが禁止されており、ツイートを検索する場合APIを使用します。tweepyはTwitter APIを使ってTwitterを操作するためのPythonライブラリで 利用者情報を入力したtweepy.Clientオブジェクトに対して.search_recent_tweets()メソッドを適用し、引数に検索ワードや件数を与えることで、最新ツイートが検索できます。

環境
  • windows10 home
  • Jupyter notebook 6.4.11
  • Python 3.10.4
準備  

Twitter API使うための登録を行い、APIキーやTOKENを用意します。

コード
import tweepy

# API情報
BEARER_TOKEN        = 'xxxxxxxxxxxxxxxxxx'
API_KEY             = 'xxxxxxxxxxxxxxxxxx'
API_SECRET          = 'xxxxxxxxxxxxxxxxxx'
ACCESS_TOKEN        = 'xxxxxxxxxxxxxxxxxx'
ACCESS_TOKEN_SECRET = 'xxxxxxxxxxxxxxxxxx'

# クライアント設定
client = tweepy.Client(bearer_token    = BEARER_TOKEN,
                       consumer_key    = API_KEY,
                       consumer_secret = API_SECRET,
                       access_token    = ACCESS_TOKEN,
                       access_token_secret = ACCESS_TOKEN_SECRET
                       )
    
# ツイート検索(検索ワード'東ブクロ'、件数10件)
tweets = client.search_recent_tweets(query = '東ブクロ', 
                                     max_results = '10')

# 検索結果表示
if tweets.data != None:
    for i in tweets.data:
        print(i)          

実行結果

検索結果が表示されます。

RT @gowasu1006higa: みんなの中に東ブクロはいる
だから、みんな東ブクロ
なれる素質があるんや
RT @gowasu1006higa: 100日後に消える東ブクロ
RT @higashidukuro: 東ブクロですよろしくお願いいたします https://t.co/qix09zLmIL
東ブクロのアカウントできてる!取れる思ったら、YouTubeか水曜日の企画なのか…
東ブクロいすぎやろ
さらば青春の光単独ライブ
初めて行ったけど2時間でコント8本で大満足の内容でした。もっと早くから行ってれば良かった。とにかくめちゃくちゃ面白かったな。東ブクロがそっちやるのwて思ったな。良い設定だわw
#五穀豊穣
#さらば青春の光 https://t.co/5Y69l0DHUF
RT @Onna__dakitai45: なんでこんなに東ブクロが増えとんの?どういうことや
サガン鳥栖の監督って何か東ブクロみたいだな
東ブクロ多いなあ
100日後に消える東ブクロ

以下のサイトを参考にさせていただきました

DXCEL WAVE > 【Python×Twitter】検索ツイートのデータ取得・分析|APIとtweepy活用による自動運用アプリ開発支援

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村

近くのラーメン屋を探す

 近くのラーメン屋を探します。GeoJSのAPIによりIPアドレスから現在地の位置情報を取得します。取得した位置情報より、リクルートWebサービスが提供するHotpepperグルメサーチAPIを使って「現在地から2000m以内のラーメン屋」を検索します。
Powered by ホットペッパー Webサービス

 HTTP通信ライブラリrequestsによりGeoJSにアクセスすると戻り値として位置情報が得られます。また、ホットペッパー Webサービスにアクセスし、検索クエリとして緯度・経度、距離(2000m以内)、キーワード('ラーメン')、件数(50)を送信します。得られたレスポンスから店名と住所を表示します。

関連記事

喫煙できる店を検索する

環境
  • windows10 home
  • Jupyter notebook 6.4.11
  • Python 3.10.4
準備  

HotpepperグルメサーチAPIを利用するにはAPIキーが必要になるため、こちらのサイトでメールアドレスを登録しキーを取得します。
webservice.recruit.co.jp
GeoJSのAPIは登録不要で、リクエストを送ればレスポンスが得られます。

コード

 まずrequests.getでGeoJSのリクエストURLにアクセスし位置情報を取得します。戻り値に含まれるキー'latitude'の値が緯度、'longitude'の値が経度になります。
 続いてHotpepperグルメサーチAPIのリクエストURLにアクセス、取得した緯度、経度を含む検索クエリを渡します。戻り値をresponceに入れ、json.loadsにより辞書形式に変換します。 APIリファレンスによると、店舗の情報は results>shop の構造となっており、その内容をresultに取り込みます。その中の'name'(店名)、'address'(住所)を表示します。
 コード中の'xxxxxxxxxxxxxxxxxx'には実際には予め取得したHotpepperグルメサーチのAPIキーを入れます。

import requests
import json

# GeoJSにリクエストしIPアドレスから現在地の緯度・経度を取得
geo_request_url = 'https://get.geojs.io/v1/ip/geo.json'
data = requests.get(geo_request_url).json()

# 検索クエリ
query = {
        'key': 'xxxxxxxxxxxxxxxxxx', # APIキー
        'lat': data['latitude'], # 現在地の緯度
        'lng': data['longitude'], # 現在地の経度
        'keyword': 'ラーメン', # キーワードに「ラーメン」
        'range': '4', # 2000m以内
        'count': 50, # 取得データ数
        'format': 'json' # データ形式json
        }

# グルメサーチAPIのリクエストURL        
url = 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1/'

# URLとクエリでリクエスト
responce = requests.get(url, query)

# 戻り値をjson形式で読み出し、['results']['shop']を抽出
result = json.loads(responce.text)['results']['shop']

# 店名、住所を表示
for i in result:
    print(i['name']+' : '+i['address'])

実行結果

現在地から2000m以内のラーメン店の一覧が表示されます。ただしIPアドレスから取得した現在地は大雑把なので実際の現在地には一致しません。   

中華料理 銀河楼 : 神奈川県横浜市神奈川区東神奈川2-41-1
すずき家 子安本店 : 神奈川県横浜市神奈川区子安通1-5-4
ラーメン大桜 東神奈川駅前店 : 神奈川県横浜市神奈川区西神奈川1-7-10
とんぱた亭 新子安店 : 神奈川県横浜市神奈川区新子安1-2-5 オルトモールコート2F
ShiNaChiKu亭 : 神奈川県横浜市神奈川区反町2-15-14 ヒルトップ反町1F
大雄ラーメン 入江町店 : 神奈川県横浜市神奈川区入江2-20-6
WOOD&PEACE : 神奈川県横浜市神奈川区六角橋1-4-4
横浜家系ラーメン 山崎家 白楽駅前店 : 神奈川県横浜市神奈川区白楽121-6

以下のサイトを参考にさせていただきました

Zenn > ホットペッパーのAPIを使ってレストランのデータを取得する
note > 【Python】IPアドレスから位置情報を地図に表示してみた
Elsaの技術日記(徒然なるままに) > python/Go言語でのPCの位置情報取得(緯度・経度取得)

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村

喫煙できる店を検索する

 喫煙できる店を検索します。リクルートWebサービスが提供するHotpepperグルメサーチAPIを使って「北千住駅から300m以内で喫煙可能な店」を検索します。
Powered by ホットペッパー Webサービス
 HTTP通信ライブラリrequestsによりホットペッパー Webサービスにアクセスし、検索クエリとして北千住駅の緯度・経度、距離(300m以内)、件数(50)を送信します。得られたレスポンスからnon_smokingフィールドの値を得て'全面禁煙'となっている店を除外して表示します。

環境
準備  

APIを利用するにはAPIキーが必要になるため、こちらのサイトでメールアドレスを登録しキーを取得します。
webservice.recruit.co.jp

コード

 requests.getでリクエストURLにアクセス、検索クエリを渡します。戻り値をresponceに入れ、json.loadsにより辞書形式に変換します。 APIリファレンスによると、店舗の情報は results>shop の構造となっており、その内容をresultに取り込みます。その中の'non_smoking'フィールド(辞書のキーが'non_smoking')の値が「全面禁煙」となっているものを除外します。
 コード中の'xxxxxxxxxxxxxxxxxx'には予め取得したAPIキーを入れます。

import requests
import json

# 検索クエリ
query = {
        'key': 'xxxxxxxxxxxxxxxxxx', # APIキー
        'lat': '35.75012327488292', # 北千住駅の緯度
        'lng': '139.80508505043517', # 北千住駅の経度
        'range': '1', # 300m以内
        'count': 50, # 取得データ数
        'format': 'json' # データ形式json
        }

# グルメサーチAPIのリクエストURL        
url = 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1/'

# URLとクエリでリクエスト
responce = requests.get(url, query)

# 戻り値をjson形式で読み出し、['results']['shop']を抽出
result = json.loads(responce.text)['results']['shop']

# 'non_smoking'フィールドが'全面禁煙'以外の場合
# 店名、'non_smoking'フィールド、ジャンルを表示
for i in result:
    if i['non_smoking'] != '全面禁煙':
        print(i['name'],'■',
              i['non_smoking'],'■',
              i['genre']['name'])

実行結果

北千住駅から300m以内で「全面禁煙」ではない店が一覧で表示されます。

ダッキーダック Ducky Duck 北千住店 ■ 未確認 ■ カフェ・スイーツ
千寿籠太 北千住店 ■ 一部禁煙 ■ 居酒屋
八重寿 ■ 未確認 ■ 居酒屋
ROCKBAR 7thchord セブンスコード ■ 禁煙席なし ■ ダイニングバー・バル
ダーツ&ビリヤード Link リンク 北千住店 ■ 禁煙席なし ■ カラオケ・パーティ
それゆけ!鶏ヤロー! 北千住店 ■ 禁煙席なし ■ 居酒屋
かほりや ■ 一部禁煙 ■ 居酒屋
個室居酒屋 水面月 MINAMOTSUKI 北千住店 ■ 禁煙席なし ■ 居酒屋
個室居酒屋 ゆらり 北千住店 ■ 禁煙席なし ■ 居酒屋
おぼん de ごはん ルミネ北千住店 ■ 未確認 ■ その他グルメ
ここのつ ■ 一部禁煙 ■ 創作料理
久助 北千住 ■ 禁煙席なし ■ 居酒屋
目利きの銀次 北千住西口駅前店 ■ 一部禁煙 ■ 居酒屋
カラオケアイランド 北千住 ■ 一部禁煙 ■ カラオケ・パーティ

以下のサイトを参考にさせていただきました

Zenn > ホットペッパーのAPIを使ってレストランのデータを取得する

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村