[OpenCV4.5.0]モザイク処理を試す

元画像

一部分を切り抜いて、縮小する

縮小した部分を拡大する

-> モザイクがかかったように見える(ドットを縮小して拡大したため)

これをプログラムで書く。
mosaic.py

import cv2

def mosaic(img, rect, size): # rectはモザイクをかける領域
	(x1, y1, x2, y2) = rect 
	w = x2 - x1 # width
	h = y2 - y1 # height
	i_rect = img[y1:y2, x1:x2]

	i_small = cv2.resize(i_rect, (size, size)) # 対象領域を指定したサイズに縮小
	i_mos = cv2.resize(i_small, (w, h), interpolation=cv2.INTER_AREA) # 対象領域に拡大
	img2 = img.copy()
	img2[y1:y2, x1:x2] = i_mos # 埋め込み
	return img2

app.py

import cv2
from mosaic import mosaic as mosaic

img = cv2.imread("cat.jpeg")
mos = mosaic(img, (50, 50, 400, 400), 10)

cv2.imwrite("cat-mosaic.png", mos)

なんやこれ、めっちゃ面白いな。
mosaic(img, rect, size): のsizeの値を小さくすると、モザイクが荒くなります。

[OpenCV4.5.0] haarcascadesで顔検出をやってみよう

OpenCVで顔検出をやりたい。画像は以下のサッカー中の二人。

元画像

### 前準備
– 顔検出に使うカスケードファイルを使います。
haarcascades
$ mkdir haarcascades
$ cd haarcascades
$ wget https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml

###

import cv2

cascade_file = "haarcascades/haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_file)

img = cv2.imread("1.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

face_list = cascade.detectMultiScale(img_gray, minSize=(150,150))

if len(face_list) == 0:
	print("false")
	quit()

for (x,y,w,h) in face_list:
	print(" 顔の座標=", x, y, w, h)
	red = (0, 0, 255)
	cv2.rectangle(img, (x, y), (x+w, y+h), red, thickness=20)

cv2.imwrite("face-detect.png", img)

$ python3 app.py
SystemError: returned a result with an error set

ん?
haarcascade_frontalface_alt.xmlを、opencvの公式からダウンロードして、上書き

$ python3 app.py
顔の座標= 141 47 60 60
顔の座標= 318 47 59 59

なんだこれ、やべーな。

[OpenCV4.5.0]基礎

### 画像の読み込み
imreadを使う

import cv2

img = cv2.imread("1.jpeg")
print(img)

[[254 255 253]
[254 255 253]
[254 255 253]

[254 255 253]
[254 255 253]
[254 255 253]]
… // 省略

### 画像の保存
imwrite(“*”, 読み込み画像) とする

import cv2

img = cv2.imread("1.jpeg")
cv2.imwrite("out.png", img)

### 画像のリサイズ

img = cv2.imread("1.jpeg")
img2 = cv2.resize(img, (600, 300))
cv2.imwrite("out.png", img2)

### 画像の切り取り

img = cv2.imread("1.jpg")
img2 = img[150:300, 150:300]
img2 = cv2.resize(img2, (300, 300))
cv2.imwrite("out.png", img2)

before

after

あ、これは面白いかも、顔認証して、顔だけアップとかできそうですね。

[tesseract4.1.1] 画像から文字を認識をしたい

tesseractを使います。

### install
$ sudo yum-config-manager –add-repo https://download.opensuse.org/repositories/home:/Alexander_Pozdnyakov/CentOS_8/
$ sudo rpm –import https://build.opensuse.org/projects/home:Alexander_Pozdnyakov/public_key
$ sudo yum update
$ sudo yum install tesseract
$ sudo yum install tesseract-langpack-jpn

### バージョン確認
$ tesseract -v
tesseract 4.1.1-rc2-20-g01fb
leptonica-1.78.0
libgif 5.1.4 : libjpeg 6b (libjpeg-turbo 1.5.3) : libpng 1.6.34 : libtiff 4.0.9 : zlib 1.2.11 : libwebp 1.0.0
Found AVX2
Found AVX
Found SSE

$ cd /usr/share/tesseract/4/tessdata/
$ sudo wget https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddata
$ sudo wget https://github.com/tesseract-ocr/tessdata/raw/master/jpn.traineddata

### テスト
– eng version

$ tesseract a.png output

– jpn version

$ tesseract test_jp.png output -l jpn

#### pyocr
tesseractをpythonで使えるようにする
$ sudo pip3 install pyocr

app.py

from PIL import Image
import sys
import pyocr

tools = pyocr.get_available_tools()
langs = tools[0].get_available_languages()

img = Image.open('test.png')
txt = tools[0].image_to_string(
	img,
	lang=langs[0],
	builder=pyocr.builders.TextBuilder(tesseract_layout=6)
)
print(txt)

vuitton画像にしてみる。
$ python3 app.py
LOUIS VUITTON

さて、そろそろラズパイやるか。

[OpenCV4.5.0] 試しに使ってみる: COLOR_BGR2GRAY

とりあえずCVを使ってみます。

$ sudo python3 -m pip install pillow

app.py

import cv2

img = cv2.imread("./img/ship.jpg")

imgG = img.mean(axis=2)

from PIL import Image
imgP = Image.fromarray(imgG)
imgP = imgP.convert('RGB')
imgP.save('./img/ship2.jpg')

before

after

ほう、そういうこと?

grayscale化

imgG = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

強力な武器を手に入れた気分だな。
武器の使い方が分からんから、本屋に行きたい。

[OpenCV4.5.0] CentOS8に入れる手順

centos8のvagrant boxを入れてから、opencvをインストールします。git cloneするため、gitのインストールも必要です。

$ vagrant box add generic/centos8
$ vagrant init generic/centos8
$ vagrant up
$ vagrant ssh
$ sudo yum update

$ git –version
-bash: git: command not found
$ sudo yum -y install gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
$ cd /usr/local/src/
// gitを入れる 省略

$ sudo su
$ dnf install epel-release make git gcc gcc-c++ cmake3 qt5-qtbase-devel python3 python3-devel python3-pip cmake python3-devel python3-numpy gtk2-devel libpng-devel libwebp-devel libjpeg-turbo-devel libtiff-devel tbb-devel freeglut-devel mesa-libGL mesa-libGL-devel boost boost-thread boost-devel gstreamer1-plugins-base -y
$ mkdir -p ~/opencv_build
$ cd ~/opencv_build
$ git clone https://github.com/opencv/opencv.git
$ git clone https://github.com/opencv/opencv_contrib.git

$ cd opencv
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D OPENCV_GENERATE_PKGCONFIG=ON -D OPENCV_EXTRA_MODULES_PATH=~/opencv_build/opencv_contrib/modules -D BUILD_EXAMPLES=ON ..
$ make -j4
// 凄い時間がかかる
$ make install
$ ln -s /usr/local/lib64/pkgconfig/opencv4.pc /usr/share/pkgconfig/
$ ldconfig
$ pkg-config –modversion opencv4
4.5.0

$ python3 -c “import cv2; print(cv2.__version__)”
4.5.0-dev

ぎゃあああああああああああああああああああああ
いい週末になった

[OpenCV4.5.0] CentOSインストール

Ubuntuに入れる予定ですが、まずはCentOSで試します。

### yum update
$ sudo yum update

### 依存パッケージインストール
$ sudo yum install -y git gcc bzip2 bzip2-devel openssl openssl-devel readline readline-devel sqlite-devel
$ sudo yum install -y cmake libjpeg-devel libtiff-devel libpng-devel jasper-devel
$ sudo yum install -y mesa-libGL-devel libXt-devel libgphoto2-devel nasm libtheora-devel
$ sudo yum install -y autoconf automake gcc-c++ libtool yasm openal-devel blas blas-devel atlas atlas-devel lapack lapack-devel
$ sudo yum install -y tbb-devel

### Git clone
https://github.com/opencv/opencv/tags
tagsを見ると、4.5.0が最新っぽい

$ cd /usr/local/src
$ sudo git clone https://github.com/opencv/opencv.git
$ sudo git clone https://github.com/opencv/opencv_contrib.git
$ cd opencv_contrib
$ sudo git checkout -b 4.5.0 refs/tags/4.5.0
$ cd ../opencv/
$ sudo git checkout -b 4.5.0 refs/tags/4.5.0

### Build
$ sudo mkdir build
$ cd build

$ sudo wget https://cmake.org/files/v3.6/cmake-3.6.2.tar.gz
$ sudo tar xvf cmake-3.6.2.tar.gz
$ cd cmake-3.6.2
$ sudo ./bootstrap && make && make install

$ cd ..
$ cmake -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D WITH_TBB=ON \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..
$ make -j7

あれ、これだと上手くいかんな。。。
CentOSは8系が最新だから、8系でテストしないといかんか。。。

[Django3.0]send_mailでメール送信

ログイン時にユーザ名を忘れたユーザがいたら、メールフォームにemailアドレスを入力してもらって、auth_usersにメールアドレスがあれば、そのメールアドレスにユーザ名を送信したい。パスワードは送信しない。

ログイン画面

メール入力画面

公式ドキュメント: send email

SMTPは開発環境なので、mailtrapを使います。
EMAIL_BACKEND = ‘django.core.mail.backends.console.EmailBackend’とすれば、コマンドラインに表示されます。

settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_HOST = 'smtp.mailtrap.io'
EMAIL_PORT = 587
EMAIL_HOST_USER = '******'
EMAIL_HOST_PASSWORD = '******'
EMAIL_USE_TLS = True

### views.py
auth_userテーブルから、一致するemailがあるか確認し、あれば、そのメールアドレスにusernameを送信する。
送信はsend_mailを使用する。
本文の改行は”\n”

from django.core.mail import send_mail

def username_send(request):
	if(request.method == 'POST'):
		data = User.objects.filter(email=request.POST['email']).first()
		if data is not None:
			subject = "【Hanai】ユーザ名のお知らせ"
			message = 'お問い合わせありがとうございます。\nログインに必要なユーザ名をお知らせします。\n\nユーザ名:' + data.username + '\n\n\n※本メールは販売管理システムの\n送信専用のメールアドレスから自動送信されています。\nご返信いただいても返信できませんのでご了承ください。\n本サービスに心上がりがない場合など、お問い合わせください。\n\nHanbai'
			from_email = 'master@hanbai.com'
			recipient_list = [ data.email ]
			send_mail(subject, message, from_email, recipient_list) 
		else:
			params = {
				'message': 'メールアドレスの登録がありません。'
			}
			return render(request, 'sales/username_forget.html', params)
	return render(request, 'sales/username_send.html')

メール受信

OK! 大分来た
さあ、この調子で続けてラズパイとopenCVやります。

[Django3.0]ユーザの削除処理

urls.py

urlpatterns = [
    // 省略
    path('delete/<int:id>', views.delete, name='delete'),
]
def delete(request, id):
	data = User.objects.get(id=id)
	data.delete()
	return render(request, 'myapp/delete_complete.html')

これだけ

ユーザ削除はアプリの機能には実装しないことが多いと思いますが、やり方は確認しておいて良かった。
さて、Authのカスタマイズはテストアプリで一通りなぞったので、これから実際に実装していきます。

[Django3.0]パスワード変更ページの作成

Djangoで用意されているPasswordChangeFormを使います。
PasswordChangeFormはログインユーザのみに使えます。

urls.py

urlpatterns = [
    //
    path('password', views.password, name='password'),
    path('password/complete', views.password_complete, name='password_complete'),
]

template
nameは、old_password、new_password1、new_password2を使用

<form action="/password/complete" method="POST">
		{% csrf_token %}
		- 現行パスワード<br>
		<input type="password" name="old_password" maxlength="128" placeholder="パスワードを入力してください" required><br>
		- 新しいパスワード<br>
		<input type="password" name="new_password1" maxlength="128" placeholder="パスワードを入力してください" required><br>
		- 新しいパスワード再入力<br>
		<input type="password" name="new_password2" maxlength="128" placeholder="パスワードを入力してください" required><br><br>
		
		<button type="submit" class="btn btn-success">更新</button>
	</form>

views.py

from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm

@login_required(login_url='/login/')
def password(request):
	user = request.user
	params = {
		'form': PasswordChangeForm(user),
	}
	return render(request, 'myapp/password.html', params)

@login_required(login_url='/login/')
def password_complete(request):
	user = request.user
	if(request.method == 'POST'):
		form = PasswordChangeForm(user=request.user, data=request.POST or None)
		if form.is_valid():
			form.save()
			update_session_auth_hash(request, form.user)
			return render(request, 'myapp/password_complete.html')
		else:
			params = {
				'message': ''
			}
			return render(request, 'myapp/password.html', params)
	return render(request, 'myapp/password_complete.html')

OK
次は最後、user削除。
これが終われば、auth機能は一通りカバー