質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1191閲覧

画像の拡大処理に合わせて位置が変わるランドマーク点の座標を取得したい

S.S_Japan

総合スコア14

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2022/10/21 10:47

前提

Pythonで画像処理について勉強しています。

実現したいこと

ある人の顔画像Aをopencvで読み込みます。
また画像Aにおける顔のランドマーク点が入ったリスト[(x0,y0),(x1,y1),...]を読み込みます。

イメージ説明

読み込んだ画像Aに対して、画像の中心座標(w/2, h/2)を原点として画像の拡大を行います。
この拡大した画像に合わせて変化した
各ランドマーク点の座標[(new_x0,new_y0),(new_x1,new_y1),...]を取得したいのですが、
どのような処理をすればいいのか分かりません。

イメージ説明

現時点での大まかなソースコードは以下の通りです。
以下の3点についてどのように処理を書けばいいのか分かりません。

・画像サイズは(w,h)のままで、画像中心(w/2, h/2)を原点として拡大する

・拡大率に合わせて各ランドマーク点の移動先の座標を取得する

・csvファイル内のランドマーク点の座標が入ったセルを、各ランドマーク点の移動先の座標に置き換える

該当のソースコード

import os import cv2 import csv import numpy as np import pandas as pd import matplotlib.pyplot as plt from PIL import Image def main(): height = ... # 高さ width = ... # 幅 for i in range(0,10): file_name_image = "image_"+str(i)+".bmp" file_name_csv = "image_"+str(i)+".csv" #各画像に対応したランドマーク点の座標が入ったcsvファイル print(file_name_image) #画像の読み込み image = cv2.imread(file_name_image) #csvファイルを読み込みリストに変換 image_csv = pd.read_csv(file_name_csv) landmark = pd.read_csv(openface_csv).values.tolist() #ランドマーク座標を取得 land_0_x = int(landmark[0][1]) land_1_x = int(landmark[0][2]) ... land_0_y = int(landmark[0][31]) land_1_y = int(landmark[0][32]) ... #拡張 image_big = *** #拡張した画像に合わせたランドマーク点の取得 new_land_0_x = *** ... new_land_0_y = *** ... #移動したランドマーク点の座標に書き換え *** #保存 image_csv.to_csv('new_image_"+str(i)+".csv') cv2.imwrite("new_image_"+str(i)+".bmp", image_big) if __name__ == '__main__': main()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/10/23 00:12 編集

http://trail.tsuru.ac.jp/dspace/bitstream/trair/839/1/Y0870019.pdf ナスカの地上絵の描き方を、「ヒモで拡大する方法」を使って説明できるように、 「画像の拡大した中心の座標から対象位置までの座標のベクトルを拡大倍率分だけ拡大」すればいけます。 分からない部分がありましたら具体的にご指摘ください。可能な範囲で回答いたします。
jbpb0

2022/10/24 04:18

> ・拡大率に合わせて各ランドマーク点の移動先の座標を取得する ランドマーク座標の原点(0, 0)が画像の左上だとして、こんな感じ ランドマーク座標の原点を画像中心にする (ランドマーク座標から、画像中心の座標を引き算する) ↓ ランドマーク座標に拡大率を掛け算する ↓ ランドマーク座標の原点を左上に戻す (ランドマーク座標に、画像中心の座標を足し算する) 座標の変数は、マイナスの値も扱える型である必要があります
S.S_Japan

2022/10/24 08:16

fourteenlengthさん、jbpb0さん、コメントありがとうございます。 拡大軸となる画像中心点から各ランドマーク点のベクトルを求め、 拡大後の画像中心点の座標に拡大後のランドマーク点の座標を足せばよかったのですね! さっそく実装してみたところ、正しく画像の拡大および ランドマーク点の拡大ができました。 拡大率を0~1倍にして縮小もできるということなので、縮小も試してみたいと思います。
guest

回答1

0

※fourteenlengthさん、jbpb0さんからいただいたコメントを元に、画像拡大とそれに合わせたランドマーク座標の拡大ができました。

csvファイルのセルの値の代入に関してはやはりよく分からなかったのですが、
新しく作成したcsvファイルに代入しなおすことで一旦解決はしました。

現時点ではちょっとごり押しなところもあるのでもう少しシャープなソースコードにできたら
いいなと思います。

完成版(一部省略)

import os import cv2 import csv import numpy as np import pandas as pd import matplotlib.pyplot as plt from PIL import Image def main(): height = *** #高さ width = *** #幅 center_h = *** #画像中心座標(x) center_w = *** #画像中心座標(y) big = 1.5 #拡大率の例 #csvファイルのヘッダー #(OpenFaceでランドマークを検出したときに出力されたcsvファイルと同じ形式で新規に作成します) data = ["-","-",..., "-","-"] data2 = ["0","0",...,"0","0"] for i in range(1,100): file_name_image = "image_"+str(i)+".bmp" file_name_csv = "image_"+str(i)+".csv" print(file_name_image) #画像の読み込み image = cv2.imread("D:\\***\\" + file_name_image) image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) #csvファイルの読み込み openface_csv = "D:\\***\\" + file_name_csv landmark = pd.read_csv(openface_csv).values.tolist() #csvファイルからランドマーク座標を取得(今回は左眉、右眉、左目、右目のみとします) #左眉 land_0_x, land_0_y = int(landmark[0][313]), int(landmark[0][381]) land_1_x, land_1_y = int(landmark[0][314]), int(landmark[0][382]) land_2_x, land_2_y = int(landmark[0][315]), int(landmark[0][383]) land_3_x, land_3_y = int(landmark[0][316]), int(landmark[0][384]) land_4_x, land_4_y = int(landmark[0][317]), int(landmark[0][385]) #右眉 land_5_x, land_5_y = int(landmark[0][318]), int(landmark[0][386]) land_6_x, land_6_y = int(landmark[0][319]), int(landmark[0][387]) land_7_x, land_7_y = int(landmark[0][320]), int(landmark[0][388]) land_8_x, land_8_y = int(landmark[0][321]), int(landmark[0][389]) land_9_x, land_9_y = int(landmark[0][322]), int(landmark[0][390]) #左目 land_10_x, land_10_y = int(landmark[0][332]), int(landmark[0][400]) land_11_x, land_11_y = int(landmark[0][333]), int(landmark[0][401]) land_12_x, land_12_y = int(landmark[0][334]), int(landmark[0][402]) land_13_x, land_13_y = int(landmark[0][335]), int(landmark[0][403]) land_14_x, land_14_y = int(landmark[0][336]), int(landmark[0][404]) land_15_x, land_15_y = int(landmark[0][337]), int(landmark[0][405]) #右目 land_16_x, land_16_y = int(landmark[0][338]), int(landmark[0][406]) land_17_x, land_17_y = int(landmark[0][339]), int(landmark[0][407]) land_18_x, land_18_y = int(landmark[0][340]), int(landmark[0][408]) land_19_x, land_19_y = int(landmark[0][341]), int(landmark[0][409]) land_20_x, land_20_y = int(landmark[0][342]), int(landmark[0][410]) land_21_x, land_21_y = int(landmark[0][343]), int(landmark[0][411]) #画像中心座標からの距離 land_B0_x, land_B0_y = land_0_x-center_w, land_0_y-center_h land_B1_x, land_B1_y = land_1_x-center_w, land_1_y-center_h land_B2_x, land_B2_y = land_2_x-center_w, land_2_y-center_h land_B3_x, land_B3_y = land_3_x-center_w, land_3_y-center_h land_B4_x, land_B4_y = land_4_x-center_w, land_4_y-center_h land_B5_x, land_B5_y = land_5_x-center_w, land_5_y-center_h land_B6_x, land_B6_y = land_6_x-center_w, land_6_y-center_h land_B7_x, land_B7_y = land_7_x-center_w, land_7_y-center_h land_B8_x, land_B8_y = land_8_x-center_w, land_8_y-center_h land_B9_x, land_B9_y = land_9_x-center_w, land_9_y-center_h land_B10_x, land_B10_y = land_10_x-center_w, land_10_y-center_h land_B11_x, land_B11_y = land_11_x-center_w, land_11_y-center_h land_B12_x, land_B12_y = land_12_x-center_w, land_12_y-center_h land_B13_x, land_B13_y = land_13_x-center_w, land_13_y-center_h land_B14_x, land_B14_y = land_14_x-center_w, land_14_y-center_h land_B15_x, land_B15_y = land_15_x-center_w, land_15_y-center_h land_B16_x, land_B16_y = land_16_x-center_w, land_16_y-center_h land_B17_x, land_B17_y = land_17_x-center_w, land_17_y-center_h land_B18_x, land_B18_y = land_18_x-center_w, land_18_y-center_h land_B19_x, land_B19_y = land_19_x-center_w, land_19_y-center_h land_B20_x, land_B20_y = land_20_x-center_w, land_20_y-center_h land_B21_x, land_B21_y = land_21_x-center_w, land_21_y-center_h #拡張(画像) xbig = center_w*big ybig = center_h*big size_after = (int(width*big), int(height*big)) resized_img = cv2.resize(image_gray, dsize=size_after) deltax = (width/2-center_w)-(resized_img.shape[1]/2-xbig) deltay = (height/2-center_h)-(resized_img.shape[0]/2-ybig) framex = int(width*big*2) framey = int(height*big*2) image_big = np.zeros((framey,framex),np.uint8) image_big[int(-deltay+framey/2-resized_img.shape[0]/2):int(-deltay+framey/2+resized_img.shape[0]/2), int(-deltax+framex/2-resized_img.shape[1]/2):int(-deltax+framex/2+resized_img.shape[1]/2)] = resized_img image_big = image_big[int(image_big.shape[0]/2-height/2):int(image_big.shape[0]/2+height/2), int(image_big.shape[1]/2-width/2):int(image_big.shape[1]/2+width/2)] #拡張(ランドマーク) data2[313], data2[381] = int(center_w + (land_B0_x*big)), int(center_h + (land_B0_y*big)) data2[314], data2[382] = int(center_w + (land_B1_x*big)), int(center_h + (land_B1_y*big)) data2[315], data2[383] = int(center_w + (land_B2_x*big)), int(center_h + (land_B2_y*big)) data2[316], data2[384] = int(center_w + (land_B3_x*big)), int(center_h + (land_B3_y*big)) data2[317], data2[385] = int(center_w + (land_B4_x*big)), int(center_h + (land_B4_y*big)) data2[318], data2[386] = int(center_w + (land_B5_x*big)), int(center_h + (land_B5_y*big)) data2[319], data2[387] = int(center_w + (land_B6_x*big)), int(center_h + (land_B6_y*big)) data2[320], data2[388] = int(center_w + (land_B7_x*big)), int(center_h + (land_B7_y*big)) data2[321], data2[389] = int(center_w + (land_B8_x*big)), int(center_h + (land_B8_y*big)) data2[322], data2[390] = int(center_w + (land_B9_x*big)), int(center_h + (land_B9_y*big)) data2[332], data2[400] = int(center_w + (land_B10_x*big)), int(center_h + (land_B10_y*big)) data2[333], data2[401] = int(center_w + (land_B11_x*big)), int(center_h + (land_B11_y*big)) data2[334], data2[402] = int(center_w + (land_B12_x*big)), int(center_h + (land_B12_y*big)) data2[335], data2[403] = int(center_w + (land_B13_x*big)), int(center_h + (land_B13_y*big)) data2[336], data2[404] = int(center_w + (land_B14_x*big)), int(center_h + (land_B14_y*big)) data2[337], data2[405] = int(center_w + (land_B15_x*big)), int(center_h + (land_B15_y*big)) data2[338], data2[406] = int(center_w + (land_B16_x*big)), int(center_h + (land_B16_y*big)) data2[339], data2[407] = int(center_w + (land_B17_x*big)), int(center_h + (land_B17_y*big)) data2[340], data2[408] = int(center_w + (land_B18_x*big)), int(center_h + (land_B18_y*big)) data2[341], data2[409] = int(center_w + (land_B19_x*big)), int(center_h + (land_B19_y*big)) data2[342], data2[410] = int(center_w + (land_B20_x*big)), int(center_h + (land_B20_y*big)) data2[343], data2[411] = int(center_w + (land_B21_x*big)), int(center_h + (land_B21_y*big)) #拡張(画像およびcsvファイルの保存) file_big_image = "image_"+str(i+10)+".bmp" file_big_csv = "image_"+str(i+10)+".csv" cv2.imwrite("D:\\***\\"+file_big_image+"",image_big) with open("D:\\***\\"+file_big_csv+"",'w',newline='') as f: writer = csv.writer(f) writer.writerow(data) writer.writerow(data2) #拡張(ランドマーク点を画像に描画) cv2.circle(image_big, (data2[313], data2[381]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[314], data2[382]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[315], data2[383]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[316], data2[384]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[317], data2[385]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[318], data2[386]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[319], data2[387]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[320], data2[388]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[321], data2[389]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[322], data2[390]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[332], data2[400]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[333], data2[401]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[334], data2[402]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[335], data2[403]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[336], data2[404]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[337], data2[405]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[338], data2[406]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[339], data2[407]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[340], data2[408]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[341], data2[409]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[342], data2[410]), 2, (0, 0, 255), -1) cv2.circle(image_big, (data2[343], data2[411]), 2, (0, 0, 255), -1) cv2.imwrite("D:\\***\\"+file_big_image+"",image_big) if __name__ == '__main__': main()

投稿2022/10/24 08:32

編集2022/10/24 08:34
S.S_Japan

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問