PostgreSQLのデータベースにpythonからアクセスしてみた
こんにちは松原です。
今期はワールドトリガーだけみてます。
今日はデータベースについてみていきます。
djangoでデータベースに少し触れましたが、一般的なSQLとかを全く使ったことがない。
最低限の教養な気がしてるので、習うより慣れろでとにかくやってみる。
とりあえず、以下の手順でやっていきます。
今日は1つ目だけ。
1. PostgreSQLで自分のPCにデータベース作成→自分のPCからPythonでアクセス
2. PostgreSQLで作成したEC2(aws)上のデータベースに自分のPCからPythonでアクセス
3. 2のデータベースサーバ上からPythonで画像を取得, 表示
ここまでできれば、どんなデータも一応はデータベースから取ってこれるようになるかなと。
で、今日はこの順番でやります。
1-1. PostgreSQLのインストール
1-2. SQLshellからデータベースをいじる
1-3. pythonからデータベースに接続
1. postgresqlのインストール
データベースやらテーブルやらを管理してくれるPostgreSQLをインストールする。
インストールはここから
Download PostgreSQL
途中で入力するパスワードは後で使うので、堅牢なものにしてメモしておく。
2. SQLshellからデータベースをいじる
PostgreSQLをインストールしたときに一緒にインストールされるSQLshellからデータベースをいじれます。
ここで作るだけ作って、あとでそれをPythonでみる。
スタートバーからSQLshellを検索, 実行。
エンターを押して行って、パスワードだけ1で設定したものを入力する。
とりあえず初期設定ではlocalhostのポート番号5432にある様子。
データベースをインターネットの海に放りこんだ場合でも、IPアドレスとポート番号等を指定すればこのデータベースにたどり着けるはず。
接続元の設定に注意だけど、今回はlocalhost→localhostのアクセスなので大丈夫。
データベース→テーブル→列やら行やらって階層構造があるらしく、それぞれをいじれる。
で、CUI上のコマンドはこちらを参考。
postgreSQLとSQL Shellを使ったpsqlコマンドでデータのリレーションをする方法を詳しく解説
一応めぼしいもののメモだけ書いておく。(コピペ用)
・データベース一覧
\l
・データベース作成
CREATE DATABASE mydb
・アクティブなデータベース変更
\c mydb
・テーブル作成
CREATE TABLE person(
id INT,
name VARCHAR(50),
birth_day DATE);
・テーブル一覧(?)
\d
・テーブル確認
\d person
・テーブルに実体としてのデータ入力
INSERT INTO person(
name,
birth_day)
VALUES('matsu', data '2001-12-01' );
このインサートを終えた後にselect * from personを実行すると、ちゃんと入っています。うれしい。
3. pythonからデータベースに接続
とりあえず値を引っ張ってきてprintするところまで。
ここを参考。
PythonからPostgreSQLに接続する方法 | アシスト
なんにせよライブラリをインストール。
conda install psycopg2
これがデータベースに接続, 値をprintするソースコード。
import psycopg2 #接続IPアドレス, ポート番号, データベース名等を指定してデータベースに接続 #EC2のデータベースにアクセスするときはlocalhostのところにIPアドレスを書き込むはず connection = psycopg2.connect("host=localhost port=5432 dbname=mydb user=postgres password=xxxxxxx") connection.get_backend_pid() #SQLを実行するためのなにかを持ってきている #なんだこれ #おそらくデータベースmydbをいじるためのUI cur = connection.cursor() #SQL実行 cur.execute("select version()") cur.execute("select id ,name from person") for row in cur: print(row[0], row[1]) # 各行の0,1番目の列の結果を取り出す
うーーーーーーーーーーーーーーーーーーーん。
恥ずかしながらSQLの基礎が弱いから、最後の部分でなにやってるかよくわかっていない。勉強しないと…
なにはともあれスクリプトからデータベースにアクセスするパスは通りました。
広げていくためのたたき台程度ということで。
それではまた次回。
AIをARに応用するぞ会 → (第10回) ~OpenCV取り込み~
お久しぶりです。
開発メンバーのYです。
最近は諸事情(ワクチンとか)あって勉強会はしばらく休止していました。
9,10月は隔週だと予定が合わないことが多かったので今後は月2回をノルマとして開催していきます。
さて今回は、OpenCVの取り込みをやりました。
プレビューしている映像から画像を抽出して推論までやりたかったのですが、
色々あって再度カメラプレビューから実装が必要になり、今回はOpenCVの取り込みまでで時間が来てしまいました。
その過程で、画像の保存形式について学びがあったので書いていきます。
0. 前回まで
↓前回のブログ
https://tottorisnow33.hatenablog.com/entry/2021/09/04/135235
前回はCameraX APIを使って、カメラで取得した映像をプレビューすることに成功しました。
いざOpenCVをいれてみよう!ということで以下ブログを参考に実装を試みましたが、
qiita.com
残念ながらOpenCVの取り込みで手詰まりしてしまいました。。
原因は使用していたAndroidstudioのバージョンがよくなかったとのことで、
今回は諦めてブログで使用しているバージョンに合わせていきます。
1. カメラプレビュー(失敗)
ブログを参考に環境構築をしたところ、無事カメラプレビューのプログラムを動かすところまでいけました。
何かがおかしい、、、
画像の輝度情報はとれてるけど色がなんだかおかしいようですね。
ソースコードを見る感じ、YUV形式で画像を扱っている箇所に問題がありそうなので原因を調査していきます。
2.原因
原因はどうやらYUV形式のフォーマット違いによるものでした。
YUVをRGBに変換する際に、指定するYUVフォーマットを誤っていたようです。
参考にしたコードはNV12形式を指定してRGBに変換をかけていましたが、本当はI420形式を指定しなければいけなかったようです。
変換フォーマットをI420形式に修正したところ、プレビューに成功しました。
3.画像の保存形式について
調べてみると、YUVというのは1つの形式ではなく、幾つかの形式の総称だということが分かりました。
YUVの中にもたくさんのフォーマットがあるそうで、メモリ構造に違いがあるそうです。
以下ブログを参考にYUV形式について学びました。
www.klab.com
今回のNV12とI420の違いについてまとめると以下のような感じです。
djangoでデータベースの内容を表示してみた
こんにちは松原です。
所要で北群馬に行きたいのですが、そろそろ雪が降り始めそう。
積もったら詰むので12月中旬まで降らないでほしい。
今日はdjangoでデータベースの中身を表示してみます。
前回はデータベースにadminサイトからアクセスしましたが、
一般ユーザーがみるサイト上でデータベースの中身を表示するということですね。
0. 概要
流れはこんな感じ
1 urls.pyにビューを登録
2 ビューを作成
・継承元を指定
・htmlを指定
・モデル(取り扱うデータベース)を指定
3 htmlを作成
・base_dirを指定
・base.htmlを作成
・html本体を作成
ビューというのが色々組み合わせて最終的にレスポンスを返してくれる大元っぽいです。
で、具体的には以下を指定して組み合わせます。
「継承元(djangoの方で用途に応じたビューを用意してくれているので、適切なビューを選んで継承する)」
「取り扱うデータベース」
「自分で作ったhtml」
継承元のビューを色々と用意してくれているのがdjangoのいいとこなのかな。
1. urls.pyにビューを登録
まず最初に、「このurlを指定されたときにこのビューを返す」という風にURLと対応付けます。
appの方のurls.pyでこう。
from django.contrib import admin from django.urls import path, include from .views import tempfunc from .views import KizaiList urlpatterns = [ path('temp/', tempfunc), path('kizai_list/', KizaiList.as_view()), ]
2. ビューを作成
次に先ほど登録したKizaiListビューを作成します。
appの方のviews.pyでこう。
from django.shortcuts import render from django.http import HttpResponse from .models import KizaiStatus # Create your views here. def tempfunc(request): return HttpResponse("temp") class KizaiList(ListView): model = KizaiStatus template_name = "kizai_list.html"
これでデータベースとして前回作成, データ入力したKizaiStatusを指定、利用するhtmlとしてkizai_list.htmlを指定したことになります。
で、このクラスはListViewというViewを参照しており、これはデータベース一覧を表示するのに適したビューとのこと。
親クラスのメンバとしてmodelとtemplate_nameがあって、それに入力することで色々組み合わせてくれてる様子。
3. htmlを作成
kizai_list.htmlを作成します。
まず最初に、ここにhtmlファイルたちを置くよということをdjangoのプロジェクトに教えてあげます。
プロジェクトのsetting.pyの一部をこう。
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR, "html_templates"], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
これで、manage.pyと同階層のhtml_templatesフォルダにhtmlたちが入ってることをdjangoに教えてあげました。
このフォルダはmanage.pyと同じ階層に自分で作ります。
この情報と2で記入したhtmlファイル名を合わせて、ビューはhtmlの場所を完全に把握することができます。
次はhtmlを実際に作ります。共用のパーツはbase.htmlに書いてしまいます。
コメントで書いてあるのが説明
<!DOCTYPE html> <html lang=en> <!--使いまわす部分は全部base.htmlに書いておく--> <head> </head> <body> <h1>機材管理</h1> <!--ページごとに違う部分だけprintfの変数のようなイメージでおいておく--> {% block content %} {% endblock content %} </body> </html>
で、kizai_list.htmlをこのように作成。
{% extends "base.html" %} {% block content %} {% for status in object_list %} <div> {{ status.kizai_name }} {{ status.using_person_name }} {{ status.user_memo }} </div> {% endfor %} {% endblock content %}
ListViewを継承しているのでobject_list という変数をもともと持っており、この中にデータベース情報がリストとして入っています。
なのでListViewを継承しているとデータベースの一覧表示に向いているんですね。
で、djangoの記法でfor文回してそれをprintしてるイメージ。
djangoの記法の一般的なのどこで覚えればいいんだ……
4. できたものとこれから
こんな感じにできました。
ここから進化させていくには、viewをたくさん覚えて使いこなしていく感じかなあと思います。
データベースに登録するビューやら更新するビュー、アカウントにサインインするビューなど色々あるようです。
で、これらをうまいこと組み合わせてデータベースに対してアクセスのよいサイトを作成。
また見た目をcss等で整える必要があるのは普通のサイトと同じですね。
一番苦手な作業。
ではまた次回。
djangoでデータベースを作成, adminサイトから情報を入力してみた
こんにちは松原です。
東京リベンジャーズをみました。
マイキーかっこいい。二期早くしてほしい。
0. 概要
さて今日は、djangoからデータベースを作成, アクセスする方法を見ていきます。
会社の機材管理表くらいのデータベース&見た目を何回かに分けて作っていく予定。
見栄えがいいものが出来るのはまだまだ先ですので、要素勉強くらいに見てください。
djangoではデータベースにアクセスする方法として、
1. djangoが用意してくれているadminサイトからアクセス
2. 自分で作成したWebサイト上でアクセス
の2通りがあるようです。
もちろん最終的に目指したいのは2番。
ユーザーが登録したり更新したりをサイト上で出来るようにしていく必要があります。
ちなみにadminサイトは、プロジェクト作成時urls.pyに初めから登録されています。
リリースするときは、不正アクセスされないようにURLを複雑にしておきましょう。
とりあえず今回は、データベースへの登録をadminからやっていきます。
作る流れとしては、
データベースに情報をadminから登録
→Weサイト上からデータベース内容を見られるようにする
→Webサイト上からデータベース内容を登録, 変更できるようにする
→見た目をきれいにする
でいこうかと。
で、今回はadminからデータベースに情報を登録していきます。
0. 概要
adminからデータベースにアクセスする手順は以下
1. models.pyにデータベースの形(どんな表なのか)を記入
2. djangoにデータベースの形を覚えてもらい作成(migration)
3. スーパーユーザーを作成
4. adminサイトにアクセス、データベース操作
プロジェクト作成やアプリ作成については前回のものを見てください。
1. データベースの形を作成
まずはデータベースの形を自分で記入。
自分がメインでやっていたCの記法に置き換えると、構造体の型を作るイメージ。
こんな感じに、アプリ内のmodels.pyに「こんな情報が入ったデータベースにしてね」と仕様を書いてあげます。
from django.db import models # Create your models here. class KizaiStatus(models.Model): kizai_name = models.CharField(max_length=100) using_person_name = models.CharField(max_length=100) user_memo = models.TextField()
あと、プロジェクトに「このアプリも対象にしといて」と教えてあげます。
プロジェクトのsettings.pyの一部を変更
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'kizai_kanri_app' ]
また、アプリのadmin.pyで、このmodelをadminサイトで取り扱うよと教えてあげます。
from django.contrib import admin from .models import KizaiStatus # Register your models here. admin.site.register(KizaiStatus)
2. djangoにデータベースの形を覚えてもらい作成
先ほど指定したデータベースの表の形を、djangoに教えてあげて実際にデータベースを作成してもらいます。
manage.pyのあるディレクトリでこれ
python manage.py makemigrations
その後にこれ
python manage.py migrate
その時点での表の形をメモして、その情報を利用してデータベース作成してるみたいですね。
makemigrationの時点で、中間生成物として0001_initial.pyのようなファイルを作成していて、その時点での表の形を中間生成物として出力しているとのこと。
これでdjangoがデータベースの形を覚えました。喜ばしい。
3. スーパーユーザーを作成
adminサイトに入れるユーザーをdjangoに覚えてもらいます。
データベースを簡単に閲覧, 変更できるサイトに誰でも入れたら大変なので。
manage.pyのあるディレクトリでこれ。
python manage.py createsuperuser
こんな感じになる。
4. adminサイトにアクセス、データベース操作
ローカルサーバを立てる
python manage.py runserver
adminサイトへ行って先ほど作ったスーパーユーザーの情報でログイン。
ちなみにURLはurls.pyで設定しているadminサイトのURL。
デフォルトなら( http://127.0.0.1:8000/admin )になるはず。
ログインすると、こんな感じにデータベースに登録できます。
データベースに色々入力して、自分で作成したWebサイトからも登録, 変更できるとよいですね。
という訳でデータベースの表作成→adminサイトから情報登録までの流れでした。
頭こんがらがりそうだけど、慣れたら便利そう。
というかどっかでdjango3に移行しないとなあ。
それではまた次回。
djangoでHello Worldしてみた
こんにちは松原です。
こないだ東武動物公園行ってきました。
ペリカンがものすごい絡んできた。駅前の無印が大きかった。
今日はdjangoでHello Worldしてみました。
動的なサイトを作るのに便利そうなフレームワークだなあという所感。
0. 概要
djangoはこんなデータフローでユーザーに返すらしい。
Webブラウザからリクエスト送信
→Webサーバにリクエストが届く
→プロジェクトのurl.pyで、そのリクエストを処理するアプリ(サブプロジェクトみたいなもの)を指定
→アプリのurls.pyで、リクエストを処理する関数またはクラスをviews.pyの中から指定
→views.py内の関数またはクラスがサイトを構築(この際テンプレートhtmlやデータベースのモデルをもってきてうまいこと組み合わせてくれる)
ということで、今回はリクエストをアプリのviews.pyまで通します。
フォルダ構造がややこしいので、最終的にこうなるよというフォルダ構造を先にお見せしときます。これ。
4. urls.pyを変更
プロジェクトのurls.py→アプリのurls.py→views.pyとリクエストが流れるようにする。
4.1 プロジェクトのurls.py
これでhelloというURLを指定されたとき、worldappというアプリ(サブプロジェクトのようなもの)のurls.pyに飛ばしてくれるようになる。
from django.contrib import admin from django.urls import path from django.urls import include urlpatterns = [ path('admin/', admin.site.urls), path('hello/', include("worldapp.urls")) ]
4.2 アプリのurls.py
自分でファイルを作成する。
これでhello/worldを指定されたとき、views.pyのhellofuncからレスポンスオブジェクトを要請するようになる。
from django.urls import path from .views import hellofunc urlpatterns = [ path('world/', hellofunc), ]
5. views.pyでレスポンスオブジェクト作成
ここからレスポンスオブジェクトをもらうと、urls.pyで指定されている関数。
レスポンスオブジェクトをどう作るかでサイトが決まるはず。
本来はデータベースから情報持ってきたりテンプレートのhtml使ったりするが、ここではhelloworldのみ。
ここまでで作りたいものは完成
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def hellofunc(request): return HttpResponse("helloworld")
6. runserverで確認
djangoにお願いするとローカルサーバーを立ててくれて、webブラウザからの様子を見せてくれる。
お願いするコマンドは、プロジェクトのmanage.pyのあるフォルダでこれ。
python manage.py runserver
Webブラウザからローカルホスト(http://127.0.0.1:8000/)を見て、さっきurls.pyで指定したURLをみるとHelloWorldが見られる。うれしい。
htmlとデータベースからの情報を自由に組み合わせられるなら色々作れそうですね。
ログインサイト作るのも簡単で堅牢と噂を聞いてるので、そういうのをひょいっと作るにはよさそう。
最後に、柵ごしに喧嘩するカピバラの画像をおいておきます。それでは。
C#でデスクトップアプリを開発してみた
こんにちは松原です。
C#でGUIソフトを作成するときのメモです。
いくつかフレームワークがあるらしいけど、マークアップ言語でデザインいじれるらしいので基本的にWPFを使っていきたい。
思った以上に簡単だった。
手順
1. visual studioをインストール(このとき設定のオプションで、.NETでのデスクトップ開発を選択しておく)
2. visual studioでプロジェクト作成(テンプレートをWPFアプリケーションにしておく)
3. 適当に作成
基本的にいじるのはcsファイルとxamlファイル
こんな感じにボタンなどのパーツをはれる。簡単。
ボタンをダブルクリックすると、押下時のイベントハンドラ関数が自動生成される。簡単。
あとはパーツへのアクションに対する処理を書いていくだけ。
画像はbitmapとして取り扱ってるとのこと。opencv等との変換がめんどくさそう。
temp.pngなどを経由して処理するのがよさそう。
あと、最初に配置する画像はビルドアクションをリソースにする必要があるらしい。
プロジェクトの内部に元々保有される画像と認識させる必要があるっぽい。
bitmapimageについてはここを参照。
BitmapImage Class (System.Windows.Media.Imaging) | Microsoft Docs
適当に画像ビューアを作成。
C#で画像ビューアを作ってみました!!! pic.twitter.com/1wxjgyLBwx
— tsukuruiroiropython33 (@tsukuruiroirop1) 2021年11月7日
ソースコードはこんな感じ。
・MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Button Content="画像変更" HorizontalAlignment="Left" Margin="105,108,0,0" VerticalAlignment="Top" Click="Button_Click"/> <Image x:Name="img_ctl" HorizontalAlignment="Left" Height="282" Margin="273,96,0,0" VerticalAlignment="Top" Width="429" Source="image/img_start.PNG" Stretch="Uniform"/> </Grid> </Window>
・MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { int image_cnt; public MainWindow() { image_cnt = 0; InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { /*画像のパス取得*/ string image_apth = @"C://Users/nasu/Desktop/local_wk/211107C#desk/WpfApp1/WpfApp1/image/img"; image_apth = image_apth + this.image_cnt.ToString(); image_apth = image_apth + ".jpg"; /*画像取得*/ BitmapImage bmp = new BitmapImage(); bmp.BeginInit(); bmp.UriSource = new Uri(image_apth, UriKind.RelativeOrAbsolute); bmp.EndInit(); /*画像設定*/ img_ctl.Source = bmp; /*画像のIDインクリメント*/ image_cnt = image_cnt + 1; image_cnt = image_cnt % 4; } } }
お手軽2クラス分類の限界調査1
ブログから記事を見つけたい場合はこちら
こんにちは松原です。寒いです。
今日は「簡単に作成できる2クラス分類はどの程度の精度なのか?」という点を調べてみました。
家で簡単に作れる識別器がどの程度のものなのか、把握しておいて損はないので。
めちゃくちゃ荒い調査ですので、調査の前の前調査くらいに思ってください。
状況と結論はこんな感じ。
■状況
・2クラス分類
・googleの公開しているresnetを転移学習
・学習画像は50枚ずつ
・バッチサイズ8, エポック数20
・テストデータ20枚ずつ
■結果
正解は(36/40)
分類するクラスは、犬の中でも特にかわいいパグと柴犬を選びました。
ちなみに私のTwitterアイコンのパグは、通り過ぎる幼稚園児に「犬みたいなのがいる」と犬と仮定された上で犬ではないと結論づけられたり、「あれパグかなブルドッグかな?」「ブルドッグじゃない?」とパグとブルドッグの2種類まで絞ったうえでブルドッグと判断されているそうです。かわいいです。
で、ソースコードはこれをほぼ流用。
事前学習済みモデルを学習させてみた - 茨城エンジニアのPython開発日記
転移学習元のモデルはこれ。
https://tfhub.dev/google/imagenet/resnet_v2_152/classification/5
パグ画像20枚に対してはこんな識別結果。
柴犬画像20枚に対してはこんな識別結果。
これで色々調べていって、100枚程度の画像でどのくらいの精度を簡単に実現できるのか、体系だてて調べていきたいです。
今日はその前準備くらいということで。
それではまた今度。