ORB-SLAM2 论文&代码学习 —— 单目初始化

投影变换

在放射变换中,物体是在二维空间中变换的。如果物体在三维空间中发生了旋转,那么这种变换就成为投影变换,在投影变换中就会出现阴影或者遮挡,我们可以运用二维投影对三维投影变换进行模块化,来处理阴影或者遮挡。在OpenCV中有类似于getAffineTransform《函数》:getPerspectiveTransform(src,dst)《函数》 用来处理计算投影变换矩阵。与getAffineTransform《函数》不同的是传入的参数是三维空间坐标系的空间坐标,也就是4*2的二维ndarray,“其”中每一行代表一个坐标并且传入的数据类型必须为float32.示例:

import cv2
import numpy as np
src=np.array([[0,0],[100,0],[0,100],[100,100]],np.float32)
dst=np.array([[100,10],[100,10],[50,70],[200,150]],np.float32)
P=cv2.getPerspectiveTransform(src,dst)
print(P)

运行结果:

[[-7.77156117e-16 -1.00000000e+00  1.00000000e+02]
 [-2.77555756e-15 -1.00000000e-01  1.00000000e+01]
 [-2.66713734e-17 -1.00000000e-02  1.00000000e+00]]

由结果可以看出当前输出的类型是float64.对于仿射变换在OpenCV中提供了如下的《函数》
cv2.warpPerspective(src,M,dsize[,dst[,flags[,borderMode[,borderValue]]]])
输入的矩阵类型是3行3列的投影变换矩阵。示例:

import cv2
import numpy as np
import matplotlib


def Perspect(path):
    img=cv2.imread(path,cv2.IMREAD_GRAYSCALE)
    if not isinstance(img, np.ndarray):
        print('PASS')
        pass
    else:
        h,w=img.shape
       #设置变换坐标变化
        src=np.array([[0,0],[w-1,0],[0,h-1],[w-1,h-1]],np.float32)
        dst=np.array([[100,100],[w/3,100],[100,h-1],[w-1,h-1]],np.float32)
        #计算投影变换矩阵
        P=cv2.getPerspectiveTransform(src,dst)
        #利用变化矩阵进行投影变换
        r=cv2.warpPerspective(img,P,(w,h),borderValue=126)
        #显示图像
        cv2.imshow('A',img )
        cv2.imshow('B',r)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        print(P)
Perspect('img/aa.jpg')

极坐标变换

极坐标变换主要处理校正图像中的圆形物体或者在圆形中物体

1.将笛卡尔坐标转换为极坐标

\(r=\sqrt{(x-(\overline{x})^2)+(y-(\overline{y})^2)}\)
\[\theta= \left\{ \begin{matrix} 2\pi +arctan2(y-\overline{y},x-\overline{x}), &y-\overline{y}\leq0\\ arctan2(y-\overline{y},x-\overline{x},&y-\overline{y}>0 \end{matrix} \right\} \]
以‘变换中’心为圆心的同一个圆心上的点,在极坐标系\(\theta\)or中显示为一条直线。“其”中\(\theta\)的取值范围为[0,2\(\pi\)],《函数》arctan2返回的角度和笛卡尔积坐标点所在的象限有关系。举例,(9,15)以(2,10)为中心进行极坐标的变换,示例代码:
#半径转换 r=math.sqrt(math.pow(9-2,2)+math.pow(15-10,2)); #角度转换 theta=math.atan2(15-10,9-2)/math.pi*180
该示例可以这样理解,先把坐标原点移动到(2,10)处,则(9,15)平移后的坐标变为(7,5),然后再以(0,0)为中心进行转换。在OpenCV中的《函数》cartToPolar(x,y[,magnitude[, angle[,angleIndegress ]]])实现的就是将原点移动到变换中心后的笛卡尔积坐标向极坐标的变换,返回值magnitude,angle是与参数x,y具有相同尺寸和数据类型的ndarray。angleInDegrees的值为True时,返回值为角度,反之返回值为弧度。
‘例如’:计算(0,0)、(1,0)、(2,0)、(0,1)、(1,1)、(2,1)、(0,2)、(1,2)、(2,2)这九个点以(1,1)为中心进行的坐标转换。首先将坐标原点移动到(1,1)处,按照平移放射矩阵计算出这九个点平移后的新坐标值,然后利用《函数》cartToPolar进行极坐标的转换。代码表示为:

import cv2
import numpy as np
x=np.array([[0,1,2],[0,1,2],[0,1,2]],np.float64)-1
y=np.array([[0,0,0],[1,1,1],[2,2,2]],np.float64)-1
r,theta = cv2.cartToPolar(x,y,angleInDegrees=True)
print("r: %s"%r)
print("theta: %s"%theta)

运行结果:
可以看到执行后的极坐标(\(\theta\),r)
以上九个点的图像表示就是以(1,1)为圆心的九个点,距离变换中心相等的点转换为极坐标后在极坐标系中位于同一条直线上。这样就直观的给出了极坐标变换是如何校正图像中的圆形物体或者圆环中的物体的。

国内jenkins搭建不再龟速的方式

2.将极坐标转换为笛卡儿坐标

(极坐标的)变换是可逆的,在已知极坐标和笛卡儿坐标的条件下,计算哪个笛卡儿坐标以(\(\overline{x}\),\(\overline{y}\))为中心的极坐标变换时(\(\theta\),r),计算公式为:
\[ x= \overline{x}+rcos\theta, y=\overline{y}+rsin\theta\]
在OpenCV中的实现《函数》是 cv2.polarToCart(magnitude,angle[,x[, y[, angleInDegrees ]]] )来实现将极坐标转化为笛卡尔坐标。其参数与cartToPolar参数类似。代码举例 实现 根据极坐标系的(30,20),(31,21),(30,10),(30,10)四个点计算迪卡儿坐标系的哪四个点以(-6,6)《为中心变换得到》的。

import cv2
import numpy as np
 # 将迪卡儿坐标转换为极坐标
angle = np.array([[30, 31], [30, 30]], np.float32)
r = np.array([[20, 21], [10, 10]], np.float32)
x, y = cv2.polarToCart(r, angle, angleInDegrees=True)
print("‘变换中’心为(0,0) 得到的四个迪卡儿坐标")
print("x: %s" % x)
print("y: %s" % y)

x+=-6
y+=6
print("‘变换中’心为(-6,6) 得到的四个迪卡儿坐标")
print("x: %s" % x)
print("y: %s" % y)

运行结果:

3.利用极坐标变换实现图像修正

我们利用极坐标和迪卡儿坐标的意义对应关系得到O的每一个像素值:
\[O(r,\theta)=f_{1}( \overline{x}+rcos\theta,\overline{y}+rsin\theta)\]
此公式中的图像输出是以1为步长进行离散化的,但是这样的化输出的图《像矩阵会出现失》真的情况,丢失跟多的图像信息,。【我们的解】决方法是将与(\(\overline{x}\),\(\overline{y}\))的距离范围为[\(r_{min}\),\(r_{max}\)]并且角度范围在 \([\theta_{min},\theta_{max}]\)内的点进行极坐标向笛卡尔坐标的变换,并且进行离散化。\(\theta\)的变换步长\(\theta_{step}\)一般取\(\tfrac{360}{180*N}\),N\(\ge\) 2,此时输出的宽为w \(\approx\) \(\tfrac{r_{max}-r_{min}}{r_{step}}\) 图像矩阵的第i行第j列可通过以下的公式进行计算:
\[O(i,j)= F_1 (\overline{x}+(r_{min}+r_{step}i)* cos(\theta_{min}+\theta_{step}j),\overline{y}+(r_{min}+r_{step}i)*sin(\theta_{min}+\theta_{step}j)) \]

下面我们通过一个具体的实例来实现极坐标的变换:将一个圆环图像变成矩形图像

import cv2
import numpy as np
import sys

#实现图像的极坐标的转换 center代表及坐标变换中心‘;r{是一个二元}元组,代表最大与最小的距离;theta代表角度范围
#rstep代表步长; thetastap代表角度的变化步长
def polar(image,center,r,theta=(0,360),rstep=0.5,thetastep=360.0/(180*4)):
    #得到距离的最小值、最大值
    minr,maxr=r
    #角度的最小范围
    mintheta,maxtheta=theta
    #输出图像的「高」、宽 O:指定形状类型的数组float64
    H=int((maxr-minr)/rstep)+1
    W=int((maxtheta-mintheta)/thetastep)+1
    O=125*np.ones((H,W),image.dtype)
    #极坐标转换  利用tile《函数》实现W*1铺成的r个矩阵  并对生成的[矩阵进行转置
    r=np.linspace(minr,maxr,H)
    r=np.tile(r,(W,1))
    r=np.transpose(r)
    theta=np.linspace(mintheta,maxtheta,W)
    theta=np.tile(theta,(H,1))
    x,y=cv2.polarToCart(r,theta,angleInDegrees=True)
    #最近插值法
    for i in range(H):
        for j in range(W):
            px=int(round(x[i][j])+cx)
            py=int(round(y[i][j])+cy)
            if((px>=0 and px<=w-1) and (py>=0 and py<=h-1)):
                O[i][j]=image[py][px]

    return O

if __name__=="__main__":
    img = cv2.imread("img/yu.jpg", cv2.IMREAD_GRAYSCALE)
    # ‘传入的图像宽’:600  「高」:400
    h, w = img.shape[:2]
    print("h:%s w:%s"%(h,w))
    # 极坐标的变换中心(300,200)
    cx, cy = 300, 200
    # 圆的半径为10 颜色:灰 “最小位数”3
    cv2.circle(img, (int(cx), int(cy)), 10, (255, 0, 0, 0), 3)
    L = polar(img, (cx, cy), (100, 350))
    # 旋转
    L = cv2.flip(L, 0)
    # 显示与输出
    cv2.imshow('img', img)
    cv2.imshow('O', L)
    cv2.waitKey(0)
    cv2.destroyAllWindows()



,

诚信在线

诚信在线(www.ludiealliedinstitute.com)现已开放诚信在线手机版下载。游戏公平、公开、公正,用实力赢取信誉。

Allbet Gaming声明:该文看法仅代表作者自己,与阳光在线无关。转载请注明:杭州灵隐寺:OpenCV图像变换二 投影变换与{极坐标变换}实现圆形图像修正
发布评论

分享到:

usdt不用实名买卖(www.uotc.vip):绑对信用卡 搭车也能赚外快
5 条回复
  1. 申傅电脑客户端下载
    申傅电脑客户端下载
    (2020-02-25 20:07:06) 1#

    sunbet 申博Sunbet 申博www.0379st.com信誉来自于每一位客户的口碑,Sunbet贴心的服务,让你尊享贵宾通道,秒速提现,秒速到账,同行业中体验最佳。这个文,很绝哦

    1. 温州新闻综合频道
      温州新闻综合频道
      (2020-03-26 06:25:09)     

      SunbetSunbet www.6358917.com Sunbet(www.sunbet.in)是进入Sunbet的主力站点。Sunbet开放Sunbet会员开户网址、Sunbet代理开户、Sunbet手机版下载、Sunbet电脑客户端下载等业务。我词穷了,反正很好

    2. 联博API
      联博API
      (2020-07-03 02:49:16)     

      Allbet Gmaing代理欢迎进入Allbet Gmaing代理(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。很可以啊

  2. 联博API
    联博API
    (2020-04-28 18:35:18) 2#

    Allbet Gmaing代理欢迎进入Allbet Gmaing代理(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。很可以啊

  3. 欧博ALLBET网址
    欧博ALLBET网址
    (2021-04-13 00:05:50) 3#

    欧博手机版下载欢迎进入欧博手机版下载(Allbet Game),欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。看我ID帅吗

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。