Pythonでいろいろやってみる

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

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技術ブログへ
にほんブログ村

国旗の色比率を円グラフにする

 TBSのクイズ番組「東大王」で、国旗の色比率を円グラフにしたものを見て国旗を当てる、というクイズをやっていたのを見て同じようなグラフを作ってみました。   

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.8.8
  • OpenCV 4.5.5
  • pandas 1.4.0
  • matplotlib 3.5.1
準備

 国旗画像は国旗 | 地図に使えるフリー素材.jpからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリに保存しました。

コード

 まず、OpenCVで画像を読み込み全画素の色リストを作ります。その際に色情報を処理しやすいようBx1000000+G*1000+Rと1つの数字にまとめます。collections.Counterで色の出現回数を求め、出現回数(ピクセル数)と色情報をpandasのデータフレーム化します。ピクセル数が全体の1%未満の色をノイズとして削除し降順に並べ替えます。ピクセル数と色のリストを作り、matplotlibで円グラフを作ります。
 まず、UAEの国旗でやってみます(ファイル名 'UAE.png')

import cv2
import collections
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 国旗画像読み込みと、サイズの取得
img = cv2.imread('UAE.png')
h, w, _ = img.shape

# 全画素の色リストを作成
# 色情報は B*1000000 + G*1000 + R に変換し
# 0埋めした9桁の文字列に  
color_list = []
for y in range(h):
    for x in range(w):
        color_list.append(str(img[y, x, 0]*1000000 +
                          img[y, x, 1]*1000 + 
                          img[y, x, 2]).zfill(9))
        
# 出現回数(ピクセル数)をカウントする        
counter = collections.Counter(color_list)

# ピクセル数と色をpandasデータフレーム化
df = pd.DataFrame(data=[list(counter.values()), list(counter.keys())],
                 index = ['pixels', 'BGR']).T

# ピクセル数が全体の1%未満の行を削除(ノイズとみなす)
df2 = df[df['pixels'] > h*w*0.01]

# 降順に並べ替え
df3 = df2.sort_values(by=['pixels'], ascending=False)

# ndarrayに変換し一行ずつ読み出しリストに追加
# 色情報は9桁の文字列なので3文字ずつ読み出し 
# 255で割って0~1の数字に変換
# 順番をBGR→RGBに変更
x_list =[]
rgb_list =[]
for i in df3.to_numpy():
    x_list.append(i[0])  
    rgb_list.append([int(i[1][6:9])/255, 
                     int(i[1][3:6])/255,
                     int(i[1][0:3])/255])

# 円グラフの作成
plt.pie(x_list, 
        colors=rgb_list, 
        wedgeprops={'linewidth': 1, 'edgecolor':'black'}, 
        counterclock=None, 
        startangle=90)
plt.show()
実行結果

国旗の色比に応じた円グラフが作成されます。

もとの国旗画像はこちら。


別の国旗を試します。
スリランカの国旗(ファイル名 'Sri_Lanka.png' )を使います。

実行結果

国旗の色比に応じた円グラフが作成されます。

もとの国旗画像はこちら。

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

子供の落書き帳 Renaissance > [pandas]特定の条件を満たす行を削除する
note.nkmk.me > Pythonで文字列・数値をゼロ埋め(ゼロパディング)

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

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

徐々に画像がはっきりするgif動画

 画像が徐々にハッキリしていくgif動画を作ります。画像処理ライブラリPillowのeffect_spreadで画像をぼかすことができますが、そのぼかし具合を少しずつ減らすことで画像を徐々にハッキリさせます。   

関連記事

少しずつ画像がはっきりする動画

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.8.8
  • Pillow 8.2.0
準備

 以下の画像ファイルをフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにファイル名'hongkong.jpg'で保存しました。

コード
from PIL import Image

im = Image.open('hongkong.jpg')  

# gifファイル作成用リスト
images = []

for i in range(50, -1, -1):
    # effect_spread処理
    spread = im.effect_spread(i)     
    # gifファイル作成用イメージリストにフレームを追加
    images.append(spread)
        
# gif動画保存
images[0].save('spread.gif', save_all=True, append_images=images[1:], 
               optimize=False, duration=150, loop=0)     

実行結果

ボケていた画像が徐々にハッキリするgif動画が作られます。

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

Pythonの文法メモ > 【Pillow】Image.effect_spreadによる画像のぼかし

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

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

パソコンの内蔵カメラで動画を撮る

 パソコンの内蔵カメラで動画を撮ります。OpenCVの cv2.VideoCapture で引数に動画ファイル名を指定した場合は、動画ファイルが開かれビデオキャプチャーオブジェクトに入力されますが、デバイス番号でカメラを指定すると、ビデオキャプチャーオブジェクトにカメラの画像が入力されます。デバイス番号は内蔵カメラの場合0、増設したUSBカメラは1,2・・・のように指定します。

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 6.4.6
  • Python 3.8.12
  • OpenCV 4.5.5
コード

 実行すると内蔵カメラから5秒間画像を取り込み、動画ファイルに保存されます。動画のサイズ・レート(fps)はカメラから取得し、その値を用いています。ファイル名は撮影時の時刻を設定しています。      

import datetime
import cv2

# 撮影時間
length = 5

# 現在時刻の文字列を取得
now = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')

# 内蔵カメラをビデオキャプチャーオブジェクトに設定
cap = cv2.VideoCapture(0)

# カメラのFPS、幅、高さ取得
fps = cap.get(cv2.CAP_PROP_FPS)
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 保存用動画ファイルのフォーマット設定
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') 
out = cv2.VideoWriter(now+'.mp4', fourcc, fps, (w, h)) 

# 撮影時間(秒) X フレームレートの回数画面取得し
# ビデオライターオブジェクトに記録
for i in range(int(length*fps)):
    ret, frame = cap.read()
    out.write(frame)

# キャプチャーオブジェクトのリリース    
cap.release()
# ビデオライターオブジェクトのリリース    
out.release()     
実行結果

内蔵カメラで5秒間録画されたmp4ファイルが保存されます。

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

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

画像でモザイク画を作る(フォトモザイク)

 画像をモザイク画に変換します。様々な色合いの画像を用意し15x10ピクセルに縮小、置き換え用画像にします。変換する画像を15x10ピクセルの碁盤目状のセルに分割し各セルのBGR平均値を出し、BGR平均値の近い置き換え用画像に置き換えます。

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 6.4.6
  • Python 3.8.12
  • numpy 1.21.5
  • OpenCV 4.5.5
準備

 変換する画像はフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'photos'を作成しその中に保存しました。

mamechi.jpg

 置き換え用画像は色味の異なる画像30枚、同じくフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'images'を作成しその中に保存しました。

コード

 変換する画像の15x10ピクセルに分割し、各セルのB,G,R値の平均を求めます。置き換え用画像30枚のB,G,R値と比較し、最も近い置き換え用画像を選びます。近さは
B値の差の二乗 + G値の差の二乗 + R値の差の二乗
により求め、この値が最も小さい置き換え用画像を選びます。
 

import os
import cv2
import numpy as np

# 置き換え用画像格納リスト
image_list = []

# 置き換え用画像BGR平均値格納リスト
bgr_list = []  

# セルのサイズ
xpitch = 15
ypitch = 10

# imagesフォルダ内のファイルのリスト生成
files = os.listdir('images/')  
# imagesフォルダからファイル名を1つずつ取り出して処理
for i in files:     
    pic = cv2.imread('images/'+i)    
    resize = cv2.resize(pic, (xpitch, ypitch))
    image_list.append(resize)
    bgr_list.append(np.mean(resize, axis=(1,0)))
    
# 変換する画像を読み出し、セルサイズの整数倍にリサイズ
# 同じサイズの黒画像(replace)を変換後画像用に作成
pic = cv2.imread('mamechi.jpg')
height, width, channel = pic.shape
resize = cv2.resize(pic, (width//xpitch*xpitch, height//ypitch*ypitch))
replace = np.zeros((height//ypitch*ypitch, width//xpitch*xpitch, 3), np.uint8)

# 変換する画像をセルサイズに分割して読み出し、各セルのBGR平均値を算出
# 置き換え用画像と比較し、最も近い画像を選択、変換後画像に張り付ける
for y in range(0, height//ypitch*ypitch, ypitch):
    for x in range(0, width//xpitch*xpitch, xpitch):
        part = pic[y:y+ypitch, x:x+xpitch]
        bgr = np.mean(part, axis=(1,0))
        min_distance = 195075
        for i in range(len(image_list)):
            j = image_list[i]
            k = bgr_list[i]
            distance = ((bgr[0]-k[0])**2+
                        (bgr[1]-k[1])**2+
                        (bgr[2]-k[2])**2)
            if distance<min_distance:
                min_distance = distance
                choice = j  
        replace[y:y+ypitch, x:x+xpitch] = choice

# 変換後画像の保存
cv2.imwrite('replace.jpg', replace)   
実行結果

モザイク画に変換された画像(replace.jpg)が保存されます


もう少しモザイク画を滑らかにするために、①xpitch = 9 ypitch = 6に変更②モザイク用画像を30→47枚に増やしました。だいぶ滑らかになりました。

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

Pythonの文法メモ > 【OpenCV】画像読み出しとサイズ・画素情報取得、切り抜き、貼り付け、チャネル操作
Pythonの文法メモ > 【OpenCV】画像サイズを変更するresize

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

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