python 事始め (7) 画像の回転 第3弾

ちょっと時間がかかりましたが,回転の部分を組み込みました。

下記がプログラム,全文です。

 ライブラリのインポート
import cv2
import tkinter as tk
from PIL import Image, ImageTk
import os
import matplotlib.pyplot as plt
import numpy as np

# ファイル名を配列に格納
file_names = ['00.jpg', '01.jpg', '02.jpg','03.jpg','04.jpg','05.jpg','06.jpg','07.jpg','08.jpg','09.jpg','10.jpg',\
		'11.jpg','12.jpg','13.jpg','14.jpg','15.jpg','16.jpg','17.jpg','18.jpg','19.jpg','20.jpg','21.jpg',\
		'22.jpg','23.jpg','24.jpg','25.jpg','26.jpg','27.jpg','28.jpg','29.jpg','30.jpg','31.jpg','32.jpg',\
		'33.jpg','34.jpg','35.jpg','36.jpg','37.jpg','38.jpg','39.jpg','40.jpg','41.jpg','42.jpg','43.jpg',\
		'44.jpg','45.jpg','46.jpg','47.jpg','48.jpg','49.jpg','50.jpg','51.jpg','52.jpg','53.jpg','54.jpg',\
		'55.jpg','56.jpg','57.jpg','58.jpg','59.jpg','60.jpg','61.jpg','62.jpg','63.jpg','64.jpg','65.jpg']
file_names1 = [ '0.jpg', '1.jpg', '2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg','9.jpg','10.jpg',\
		'11.jpg','12.jpg','13.jpg','14.jpg','15.jpg','16.jpg','17.jpg','18.jpg','19.jpg','20.jpg','21.jpg',\
		'22.jpg','23.jpg','24.jpg','25.jpg','26.jpg','27.jpg','28.jpg','29.jpg','30.jpg','31.jpg','32.jpg',\
		'33.jpg','34.jpg','35.jpg','36.jpg','37.jpg','38.jpg','39.jpg','40.jpg','41.jpg','42.jpg','43.jpg',\
		'44.jpg','45.jpg','46.jpg','47.jpg','48.jpg','49.jpg','50.jpg','51.jpg','52.jpg','53.jpg','54.jpg',\
		'55.jpg','56.jpg','57.jpg','58.jpg','59.jpg','60.jpg']

#グローバル変数の定期
img=file_names[0]
kaisu=0
kaisu1=0
imagetk_list = list()

# ベースパスを設定
base_path = 'E:/python-kaihatu/nanikana/mask-jp'
base_path1 = 'E:/python-kaihatu/nanikana/mask-r1'

# tkオブジェクトの作成
root = tk.Tk()
root.title("なにかな") #ウィンドウのタイトルを設定
root.geometry("700x570") #ウィンドウのサイズを設定

### キャンバス作成
canvas=tk.Canvas(root,width=550, height=550)
canvas.place(x = 10,y = 10)

#背景画像を読み込み
img1 = cv2.imread('E:/python-kaihatu/nanikana/gazou/buta1.jpg')

def gazou_over():
	global kaisu

	# フルパスを作成
	full_path = os.path.join(base_path, file_names[kaisu])

	# マスクファイルを開く
	mask = cv2.imread(full_path)

	if mask is not None:
		#画像の合成
		result = cv2.bitwise_and(mask,img1)
		#BRG読み込みをRGBに変換
		result = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
		#フォーマットをPILに変換
		result = Image.fromarray(result)
	return result

def kaiten():
	global result1,mask
	# フルパスを作成
	full_path1 = os.path.join(base_path1, file_names1[kaisu1])

	# マスクファイルを開く
	mask = cv2.imread(full_path1)
	
	#画像の合成
	result1 = cv2.bitwise_and(mask,img1)

	#cv2.imshow('test', result)

	#BRG読み込みをRGBに変換
	result1= cv2.cvtColor(result1, cv2.COLOR_BGR2RGB)

	#フォーマットをPILに変換
	result1 = Image.fromarray(result1)
	
	#TkinterのPhotoImageに変換
	result1=ImageTk.PhotoImage(result1)

	canvas.create_image(273,273,image = result1,tag='p1')

def on_button_click():
	global kaisu,imagetk_list
	if  kaisu<65:
		kaisu= kaisu+1

		#旧画像の削除
		canvas.delete('p1')

		result= gazou_over()
		result=ImageTk.PhotoImage(result)
		imagetk_list.append(result)
		canvas.create_image(273,273,image = result,tag='p1')

def on_button1_click():
	global kaisu,imagetk_list
	if  kaisu>0:
		kaisu= kaisu-1

		#旧画像の削除
		canvas.delete('p1')

		result= gazou_over()
		result=ImageTk.PhotoImage(result)
		imagetk_list.append(result)
		canvas.create_image(273,273,image = result,tag='p1')

def on_button2_click():
	global kaisu1,imagetk_list
	if kaisu1<60:
		kaisu1=kaisu1+1
		kaiten()


		#imagetk_list.append(result1)
		#canvas.create_image(273,273,image = result1,tag='p1')

def on_button3_click():
	global kaisu1,imagetk_list
	if kaisu1>0:
		kaisu1=kaisu1-1
		kaiten()

#PILでjpgを使用
img_pil=gazou_over()
img_pil=ImageTk.PhotoImage(img_pil)
#画像ファイルをキャンバスの(0,0)に合わせて表示してみる
canvas.create_image(273,273,image = img_pil,tag='p1')

# ウィジェットの配置や、イベント処理などを記述
button = tk.Button(root, text="開く", command=on_button_click, bg="cyan4", fg="white",width=8, height=1)
button.place(x=595, y=30)
button1 = tk.Button(root, text="閉じる", command=on_button1_click, bg="cyan4", fg="white",width=8, height=1)
button1.place(x=595, y=100)
button2 = tk.Button(root, text="回転", command=on_button2_click, bg="cyan4", fg="white",width=8, height=1)
button2.place(x=595, y=170)
button3 = tk.Button(root, text="逆回転", command=on_button3_click, bg="cyan4", fg="white",width=8, height=1)
button3.place(x=595, y=200)

# メインループの実行
root.mainloop()

python 事始め (6) 画像の回転 第2弾

下準備として,マスク画像の処理が終わりました。

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 画像読込
img = cv2.imread("E:/python-kaihatu/nanikana/mask-jp/01.jpg")
img1=  cv2.imread("E:/python-kaihatu/nanikana/mask-jp/00.jpg")

# 画像サイズ
height = img.shape[0]  # 高さ
width  = img.shape[1]  # 幅

#ベースパスの設定
base_path = 'E:/python-kaihatu/nanikana/mask-r1'

for i in range(60):
	s = str(i+1)
	s=s+".jpg"
	full_path = os.path.join(base_path, s)

	#画像の回転行列
	rot_matrix = cv2.getRotationMatrix2D((width/2,height/2),  # 回転の中心座標
						i*(-6),                 # 回転する角度
						1,                  # 画像のスケール
					)

	# アフィン変換適用
	afin_img = cv2.warpAffine(img,rot_matrix,(width,height))

	#画像の保存
	img_OR = cv2.bitwise_or(img1, afin_img)
	cv2.imwrite(full_path, img_OR)

cv2.waitKey(0)
cv2.destroyAllWindows()

画像の回転部分は,あるサイトの丸パクリです。回転を理解するには,何と,高校でもならってなかった行列
の式が必要なようでもうお手上げです。行列は,習いませんでしたらから,あれは,数Ⅲの領域なんでしょう
かね。回転には,あまり,立ち入らないことにします。

python 事始め (5) 画像の回転

昔作ったもにはなかった見えるところが回転するような機能を追加します。マスク画像を回転すればいいので
すが,回転すると四隅が黒くなります。

元画像

回転後画像(45度)


これではまずいので,回転後の画像について,下記の画像と OR をとって,四隅を消します。

ORをとる画像

できた画像


ということで,目的の画像ができましたが,これをプログラムでやると,変換に結構時間がかかるようですの
で,必要な画像を一括変化して保存後,その都度呼び出すようにします。
下記が回転に使ったプログラムです。

mport cv2
import numpy as np
import matplotlib.pyplot as plt

# 画像読込
img = cv2.imread("E:/python-kaihatu/nanikana/mask-jp/01.jpg")
img1=  cv2.imread("E:/python-kaihatu/nanikana/mask-jp/00.jpg")
# 画像サイズ
height = img.shape[0]  # 高さ
width  = img.shape[1]  # 幅

#画像の回転行列
rot_matrix = cv2.getRotationMatrix2D((width/2,height/2),  # 回転の中心座標
                                      -45,                 # 回転する角度
                                      1,                  # 画像のスケール
                                    )

# アフィン変換適用
afin_img = cv2.warpAffine(img,               # 入力画像
                          rot_matrix,        # 行列
                          (width,height)     # 解像度
                         )

# 画像表示
img_OR = cv2.bitwise_or(afin_img, img1)
img_OR = cv2.bitwise_or(img1, afin_img)
cv2.imshow('img',img_OR)
cv2.imwrite('E:/python-kaihatu/nanikana/mask-r1/45-m.jpg', img_OR)
cv2.waitKey(0)
cv2.destroyAllWindows()

python 事始め (4) マウスで操作(第二弾)

以前作ったものに,大分近づいてきました。ウインドウライクの画面に操作ボタンを配置し,そのボタンで操
作できるようにしました。作っている過程で,プログラム的には,間違いが無いのに,思った動作をしないこ
とがでてきました。グーグル先生に聞いてみると,下記のHPにたどり着きました。

tkinterで画像が表示されない現象について(ガベージコレクション)

どうやら,サブルーチンで,画像表示をしていたのが原因のようで,サブルーチンでの表示だと,ガベージコ
レクションで,ローカル変数が消去されてしまうらしい。大昔,BASICでプログラムを組んでいた頃,良く聞
いた言葉でした。このHPのように変更したら,見事うごきました。

下記が,プログラムの全文です。

# ライブラリのインポート
import cv2
import tkinter as tk
from PIL import Image, ImageTk
import os

# ファイル名を配列に格納
file_names = ['00.jpg', '01.jpg', '02.jpg','03.jpg','04.jpg','05.jpg','06.jpg','07.jpg','08.jpg','09.jpg','10.jpg',\
		'11.jpg','12.jpg','13.jpg','14.jpg','15.jpg','16.jpg','17.jpg','18.jpg','19.jpg','20.jpg','21.jpg',\
		'22.jpg','23.jpg','24.jpg','25.jpg','26.jpg','27.jpg','28.jpg','29.jpg','30.jpg','31.jpg','32.jpg',\
		'33.jpg','34.jpg','35.jpg','36.jpg','37.jpg','38.jpg','39.jpg','40.jpg','41.jpg','42.jpg','43.jpg',\
		'44.jpg','45.jpg','46.jpg','47.jpg','48.jpg','49.jpg','50.jpg','51.jpg','52.jpg','53.jpg','54.jpg',\
		'55.jpg','56.jpg','57.jpg','58.jpg','59.jpg','60.jpg','61.jpg','62.jpg','63.jpg','64.jpg']

#グローバル変数の定期
img=file_names[0]
kaisu=0

# ベースパスを設定
base_path = 'E:/python-kaihatu/nanikana/mask-jp'

# tkオブジェクトの作成
root = tk.Tk()
root.title("なにかな") #ウィンドウのタイトルを設定
root.geometry("700x570") #ウィンドウのサイズを設定

### キャンバス作成
canvas=tk.Canvas(root,width=550, height=550)
canvas.place(x = 10,y = 10)

#背景画像を読み込み
img1 = cv2.imread('E:/python-kaihatu/nanikana/gazou/buta1.jpg')

def gazou_over():
	global kaisu

	# フルパスを作成
	full_path = os.path.join(base_path, file_names[kaisu])

	# マスクファイルを開く
	mask = cv2.imread(full_path)

	if mask is not None:
		#画像の合成
		result = cv2.bitwise_and(mask,img1)
		#BRG読み込みをRGBに変換
		result = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
		#フォーマットをPILに変換
		result = Image.fromarray(result)
	return result

imagetk_list = list()
def on_button_click():
	global kaisu,imagetk_list
	if  kaisu<64:
		kaisu= kaisu+1

		#旧画像の削除
		canvas.delete('p1')

		result= gazou_over()
		result=ImageTk.PhotoImage(result)
		imagetk_list.append(result)
		canvas.create_image(273,273,image = result,tag='p1')

def on_button1_click():
	global kaisu,imagetk_list
	if  kaisu>0:
		kaisu= kaisu-1

		#旧画像の削除
		canvas.delete('p1')

		result= gazou_over()
		result=ImageTk.PhotoImage(result)
		imagetk_list.append(result)
		canvas.create_image(273,273,image = result,tag='p1')

#PILでjpgを使用
img_pil=gazou_over()
img_pil=ImageTk.PhotoImage(img_pil)

#画像ファイルをキャンバスの(0,0)に合わせて表示
canvas.create_image(273,273,image = img_pil,tag='p1')

# イベント処理記述
button = tk.Button(root, text="開く", command=on_button_click, bg="cyan4", fg="white",width=8, height=1)
button.place(x=595, y=30)
button1 = tk.Button(root, text="閉じる", command=on_button1_click, bg="cyan4", fg="white",width=8, height=1)
button1.place(x=595, y=100)

# メインループの実行
root.mainloop()

次は,ファイルの読み込みを入れてみようかなと思います。

python 事始め (3) マウスで操作

昔つっくったものは,確か,マウスで操作するものでした。今回の物も,マウスで操作できるようにしま
した。
paython では,

サブルーチンの作成
変数のフォーカス

が,慣れ親しんだ C とは,若干違うようで手間取りました。何とか,下記の動画のように操作できるも
ができました。

import cv2
import os

# ファイル名を配列に格納
file_names = ['00.jpg', '01.jpg', '02.jpg','03.jpg','04.jpg','05.jpg','06.jpg','07.jpg','08.jpg','09.jpg','10.jpg',\
		'11.jpg','12.jpg','13.jpg','14.jpg','15.jpg','16.jpg','17.jpg','18.jpg','19.jpg','20.jpg','21.jpg',\
		'22.jpg','23.jpg','24.jpg','25.jpg','26.jpg','27.jpg','28.jpg','29.jpg','30.jpg','31.jpg','32.jpg',\
		'33.jpg','34.jpg','35.jpg','36.jpg','37.jpg','38.jpg','39.jpg','40.jpg','41.jpg','42.jpg','43.jpg',\
		'44.jpg','45.jpg','46.jpg','47.jpg','48.jpg','49.jpg','50.jpg','51.jpg','52.jpg','53.jpg','54.jpg',\
		'55.jpg','56.jpg','57.jpg','58.jpg','59.jpg','60.jpg','61.jpg','62.jpg','63.jpg','64.jpg']

#グローバル変数の定期
img=file_names[0]
kaisu=0

# ベースパスを設定
base_path = 'E:/python-kaihatu/nanikana/mask-jp'

#背景画像を読み込み
ima1 = cv2.imread('E:/python-kaihatu/nanikana/gazou/buta1.jpg')

def gazou_over():
	global kaisu
	# フルパスを作成
	full_path = os.path.join(base_path, file_names[kaisu])
	# マスクファイルを開く
	mask = cv2.imread(full_path)
	if mask is not None:
		#画像の合成
		result = cv2.bitwise_and(mask,ima1)
	return result

def mouseEvents(event, x, y, flags, param):
	global kaisu
	try:
		# 処理を記入
		if event == cv2.EVENT_LBUTTONDOWN:
			img=""
			if kaisu<64:
				print("左クリック")
				kaisu=kaisu+1
				img=gazou_over()
				cv2.imshow("test_image", img)
		if event == cv2.EVENT_RBUTTONDOWN:
			img=""
			if kaisu>0:
				print("右クリック")
				kaisu=kaisu-1
				img=gazou_over()
				cv2.imshow("test_image", img)
	except Exception as e:
		print(e)

result=gazou_over()
cv2.imshow("test_image", result)
cv2.setMouseCallback("test_image", mouseEvents)
cv2.waitKey(0)

python 事始め (2)

ちょっと時間かかりましたが,3日目にして,昔作ったのの同じようなものができました。ただ,今回短時間
でできたのは,画像があったのと,マスクの画像があったからです。マスクの画像も,何のソフト使って作っ
たのかも忘れています。多分海賊版アド〇の画像ソフトだったかなと思います。
このソフトを動かすのに,64のマスク画像を使ってます。プログラムでやってるのは,元画像にマスクの画
像を重ねているだけです。

python の openCV のプログラムで,このマスクと,元画像を重ね合わせています。

次が動かしたプログラムです。たった,これだけです。

import os
import cv2


# ファイル名を配列に格納
file_names = ['00.jpg', '01.jpg', '02.jpg','03.jpg','04.jpg','05.jpg','06.jpg','07.jpg','08.jpg','09.jpg','10.jpg',\
		'11.jpg','12.jpg','13.jpg','14.jpg','15.jpg','16.jpg','17.jpg','18.jpg','19.jpg','20.jpg','21.jpg',\
		'22.jpg','23.jpg','24.jpg','25.jpg','26.jpg','27.jpg','28.jpg','29.jpg','30.jpg','31.jpg','32.jpg',\
		'33.jpg','34.jpg','35.jpg','36.jpg','37.jpg','38.jpg','39.jpg','40.jpg','41.jpg','42.jpg','43.jpg',\
		'44.jpg','45.jpg','46.jpg','47.jpg','48.jpg','49.jpg','50.jpg','51.jpg','52.jpg','53.jpg','54.jpg',\
		'55.jpg','56.jpg','57.jpg','58.jpg','59.jpg','60.jpg','61.jpg','62.jpg','63.jpg','64.jpg']

# ベースパスを設定
base_path = 'E:/python-kaihatu/nanikana/mask-jp'

#背景画像を読み込み
ima1 = cv2.imread('E:/python-kaihatu/nanikana/gazou/buta1.jpg')

# 配列から画像ファイルを開いて表示
for file_name in file_names:
    # フルパスを作成
	full_path = os.path.join(base_path, file_name)
    
    # マスクファイルを開く
	mask = cv2.imread(full_path)
    
	if mask is not None:
		#画像の合成
		result = cv2.bitwise_and(mask,ima1)

		# 画像を表示
		cv2.imshow('Image', result)

		#キー入力待ち
		cv2.waitKey(0)  # キー入力待ち
		#cv2.destroyAllWindows()
	else:
		print(f'Failed to load {full_path}')

python 事始め

サーバーの保存してある,古いファイルを整理していたら,昔,現役時代に作成したプログラムの片割れの,
データー(画像)がでてきました。当時,何冊もグラフィックの書籍を読みあさり,結構な期間をかけて,
VB(ビジアルベーシック)を使って,苦労して作ったものです。動かす,実行ファイルもあったのですが,
ウイルスに犯され,あえなく,削除しました。
この昔作ったプログラムを再現したくなりました。幸い,python というフリーのプログラムを使うと,画像
処理が簡単にできそうでしたので,早速始めてみました。
python は,簡単にインストールできましたが,openCV という,画像を操作するソフトのインストールに
手間どりました。多分,これは, python のバージョンが新しくて, openCV が対応してないのか,と
想像して一端,全削除して,インストールし直しました。最初インストールしたのは,3.13.2 ですが,イン
ストールし直したのは,3.12.9 です。思った通り,バージョンを落としたことで,openCV 問題なくイン
ストールできまた。

インストールの確認用にあった,プログラムを改編して,動かしました。

import cv2
import numpy as np
img = cv2.imread('E:/python-kaihatu/nanikana/gazou/test.jpg')
cv2.imshow('Image Test', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

結果,下記のような画像が,あっけなく表示できました。


この画像を使ってたのは,何年前でしょうかね。もう,20年以上前ですね。さらに,最終目的である,画像
の重ね合わせも何とかできました。

この画像を表示するのに,現役の時に,どれだけ時間をかけたか,ちょっと,ばからしくなりました。python
を使ったら何と二日で完成です。ただ,最終形にはまだ,時間かかりそうですが・・・・・。

import cv2
import numpy as np

ima1 = cv2.imread('E:/python-kaihatu/nanikana/gazou/test.jpg')
mask = cv2.imread('E:/python-kaihatu/nanikana/bmp/15.jpg')

result = cv2.bitwise_and(mask,ima1)

cv2.imshow('Image Test', result)

cv2.waitKey(0)
cv2.destroyAllWindows()