opencv史诗级大坑-图像坐标系碰上投影变换

这也太坑了,才知道opencv的图像坐标系居然是这样的——

opencv史诗级大坑-图像坐标系碰上投影变换_第1张图片

 (图引用自【opencv】图像坐标系的理解_RobotLaw的博客-CSDN博客_opencv坐标系)

 虽然img.shape = h,w,C ,访问像素是[x,y], h代表x轴长度,即图像的高度,但是opencv会帮你做个转换,转成[y,x],然后用[y,x]去访问图片坐标系中的元素

平时单单用index访问还好,有opencv做转换,但是一旦涉及到鼠标选点,或者图片坐标系的变换(IPM)调用warpPerspective时,需要传入的图片参考点,就没人给你转了,这时候需要你自己处理。

本人就是因为这个问题,在做bev投影的时候被卡了好久,图片输出的 尺寸就是不对,无奈自己写了一个warpPerspective......

bug示例:

import os
import numpy as np
import cv2
import glob


dirlists = glob.glob('D:\\*',recursive=False)
dirname= dirlists[0]
basepic_path = os.path.join(dirname, 'camera_head_right.jpg')
bevpic_path = os.path.join(dirname, 'bev_visualize.jpg')
param_path = os.path.join(dirname, 'frame_infos.json')
label_path = os.path.join(dirname, 'semantic_label_cls3.png')

def ptlists(img):
    H,W,_=img.shape
    # return np.array([[0,0],[H-1,0],[0,W-1],[H-1,W-1]]).astype(np.float32)
    return np.array([[0,0],[0,H-1],[W-1,0],[W-1,H-1]]).astype(np.float32)

basepic = cv2.imread(basepic_path,cv2.IMREAD_COLOR)
bevpic = cv2.imread(bevpic_path,cv2.IMREAD_COLOR)
def genbev(matrix=None):
    if matrix is None:
        matrix = cv2.getPerspectiveTransform(ptlists(basepic), ptlists(bevpic))
        return cv2.warpPerspective(basepic,matrix, (bevpic.shape[1], bevpic.shape[0]),0), matrix
        # return cv2.warpPerspective(basepic, np.linalg.inv(matrix), (bevpic.shape[1], bevpic.shape[0]),0), matrix

    return cv2.warpPerspective(basepic, np.linalg.inv(matrix), (bevpic.shape[1], bevpic.shape[0]))

res, mat = genbev()
cv2.imshow('asd',res)
cv2.waitKey(0)

此程序是做bev投影的。如果把注释掉的部分回复,就是bug版本。主要区别在于定义参考点的时候的顺序。

另外,warpPerspective应该是默认开启了WARP_INVERSE这个flag的,所以传入的单应矩阵不用求逆。

下边是我自己写的warpPerspective,可以按正常坐标系顺序传参

def myownwarp(src,mat,size,scale=1):
    h,w,_=size
    h=int(h*scale)
    w=int(w*scale)
    out = np.zeros((h,w,3))
    coory,coorx = np.meshgrid(np.arange(0,w),np.arange(0,h))
    dst_coor = np.concatenate([
        np.expand_dims(coorx,2),
        np.expand_dims(coory,2),
        np.ones((h,w,1))],axis=2)
    src_coor = np.squeeze(mat @ np.expand_dims(dst_coor,3),3)
    # print(np.expand_dims(dst_coor,3)[1000,700].shape)
    # print(np.expand_dims(src_coor,3)[1000,700])
    # print(mat @ np.expand_dims(dst_coor,3)[1000,700])
    src_coor = src_coor / src_coor[:,:,2:]
    dst_coor=dst_coor[:,:,0:2].astype(np.int32).reshape(-1,2)
    src_coor=src_coor[:,:,0:2].astype(np.int32).reshape(-1,2)
    out[dst_coor[:,0],dst_coor[:,1]]=src[src_coor[:,0],src_coor[:,1]]
    return out.astype(np.int32)

matrix, _ = cv2.findHomography(ptlists(basepic), ptlists(bevpic),  0)
res = myownwarp(basepic,np.linalg.inv(matrix),bevpic.shape,1)
plt.imshow(res)

你可能感兴趣的:(opencv,计算机视觉,人工智能)