把照片中人头的像素坐标进行3D转换,在Unity中显示人群

这篇博客介绍了如何使用OpenCV在Unity屏幕坐标系中进行透视转换。首先,通过鼠标选取四个点来定义源和目标坐标,然后计算透视变换矩阵。接着,应用该矩阵将图像进行透视变换,并将头点坐标也进行相同转换。最后,将转换后的头点坐标写入新的CSV文件中。
摘要由CSDN通过智能技术生成

示例图

示例图片如下,每个粉色点代表算法识别出来的一个人。算法提取出了其像素坐标(2D)
在这里插入图片描述
图片详细信息如下:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Unity屏幕坐标系

Screen Space(屏幕坐标):以像素来定义的,以屏幕的左下角为(0,0)点,右上角为(Screen.width,Screen.height)
输出:

Debug.Log("Screen.width: " +  Screen.width);
Debug.Log("Screen.height: " + Screen.height);

在这里插入图片描述

最终方案:python opencv: perspectiveTransform

注意事项:

  1. 读取图片的路径用单正斜杠;
  2. 读取图片的路径不能有空格;
  3. imread之后可以print一下img,不是none才正常。
  4. 显示图片用windowNm = "1"cv2.namedWindow(windowNm,cv2.WINDOW_NORMAL) 是为了让图片可以拉伸,不然图片太大屏幕放不下还不能缩放
  5. 显示图片cv2.imshow(windowNm,newImg)之后,if cv2.waitKey(0) & 0xff == 27: cv2.destroyAllWindows() 是为了使图片正常显示(不闪退),并且能正常关掉。
  6. cv2.getPerspectiveTransform(points,trans) and newImg = cv2.warpPerspective(imgDogs, H, (4000, 1500)) 这两个函数里输入的points一定得是np.float32, 不能是list也不能不是float32
  7. newHeadPoints = cv2.perspectiveTransform(headPoints[None, :, :], H) 这里的headPoints一定要弄成三维,不然报错。
# 视角坐标转换
##
import cv2
import numpy as np

def draw_circle(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img,(x,y),100,(255,0,0),-1)


# 1. 读取图片
points = []
#img = cv2.imread("Z:/EPIC/KAU-AI/WP6/MyCode/with_hmy/projective_trans_sample.png")
# img = cv2.imread("E:/documents/[2021.03.29] Limo/test_img'/2.jpg") # 可能是路径中不能有空格
imageId = 6
basePath = "E:/documents/LimoExp/"

img = cv2.imread(basePath + str(imageId) + ".jpg")
imgDogs  = cv2.imread(basePath + str(imageId) + "a.jpg")
#
# 2.jpg: points: [[565, 1218], [677, 1225], [1172, 2045], [319, 2038]]
# [581, 1233], [686, 1233], [258, 2038], [1115, 2009]
print(img)

#img = cv2.imread("C:/Users/Think/Desktop/video_1.jpg")
windowNm = "1"
cv2.namedWindow(windowNm,cv2.WINDOW_NORMAL)

# 2. 鼠标取点
cv2.setMouseCallback(windowNm,lambda event,x,y,flgs,prm: points.append([x,y]) if event==cv2.EVENT_FLAG_LBUTTON else None)
while(1):
    cv2.imshow(windowNm,img)
    if cv2.waitKey(0) & 0xff == 27:
        cv2.destroyAllWindows()
        break
print(points)

# [[845, 817], [1704, 920], [8, 791],[2036, 1356]]
##
# 3. 求出转化矩阵H
# points, trans, imageId
import cv2
import numpy as np
import csv

basePath = "E:/documents/LimoExp/"

img = cv2.imread(basePath + str(imageId) + ".jpg")
imgDogs  = cv2.imread(basePath + str(imageId) + "a.jpg")
'''2.jpg获取转换矩阵H'''
# necessary to make them float32


points = np.float32([[581, 1233], [686, 1233], [258, 2038], [1115, 2009]])
trans = np.float32([[258, 1233], [1115, 1233],[258, 2038], [1115, 2009]])

if imageId == 5:
    points = np.float32([[324, 482], [409, 476],
                         [104, 837], [899, 634]])
    trans = np.float32([[104, 1482], [1500, 1482],
                        [104, 837], [899, 837]])
elif imageId == 6:

    points = np.float32([[800, 817], [1740, 920],
                         [8, 791],[2036, 1356]])
    points = np.float32([[880, 816], [1426, 880], [20, 796], [1036, 1125]])
    trans = np.float32([[0, 0], [1000, 0],
                        [0, 1000],[1000, 1000]])

H = cv2.getPerspectiveTransform(points,trans)
print(H)
# 检验图片
newImg = cv2.warpPerspective(imgDogs, H, (4000, 1500))
windowNm = "1"
cv2.namedWindow(windowNm,cv2.WINDOW_NORMAL)
cv2.imshow(windowNm,newImg)
cv2.waitKey()



##
# 4. 转换

headPoints = []
with open(basePath +"output" + str(imageId) + ".csv", 'r', encoding='utf8') as f:
    f_read = list(csv.reader(f))
    for row in range(0,len(f_read)):
        x = int(f_read[row][2])
        z = int(f_read[row][4])
        headPoints.append([x,z])
    print("finished reading")

headPoints = np.float32(headPoints)
print(headPoints)
##
newHeadPoints = cv2.perspectiveTransform(headPoints[None, :, :], H) # this is very important points[None, :, :]
##

print(newHeadPoints)
print(newHeadPoints.shape[1])
print()
##
with open(basePath +"outputTranss" + str(imageId) + ".csv", 'a', newline="") as f2:
    cw = csv.writer(f2)
    index = 1
    for i in range(newHeadPoints.shape[1]):
        cw.writerow([0,index,newHeadPoints[0,i,0], 0,newHeadPoints[0,i,1]])
        index +=1
print("finish writing file")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值