天空盒转全景图(python实现)

思路:

天空盒文件中包含 上、下、左、右、前、后 6幅正方形图片

将“上”剪开,得到4个等腰直角三角形

假设三角形有黏连性质

拉住直角顶点,向两边拉开,则直角顶点变成直线,三角形变成矩形

将“下”剪开,得到4个等腰直角三角形......同上操作,拼接即可

具体步骤为:

1.设“上”三角形直角顶点为O

2.设i=1

3.在底边从左至右取第i个像素点A

4.取得线段OA

5.设点A对应  前后左右图片中  正方形下底边的点为B点

6.取得线段AB

7.设“下”三角形直角顶点为P

8.取得线段BP

9.拼接线段 OA+AB+BP

10.将线段 OA+AB+BP压缩到长度为   正方形边长*2

11.重复   i=2  至  i=正方形边长W

12.拼接 全部 W 条线段

 

代码如下:

import cv2
import numpy as np
import math

from numpy.lib.function_base import angle

sdir="e:\\dds2png\\"
sfile="tkh.png"
outfile="o.png"

img=cv2.imread(sdir+sfile,cv2.IMREAD_UNCHANGED)


iwidth=img.shape[0]

def imgsplit(img,i):
    return img[0:iwidth,(i-1)*iwidth:i*iwidth]

img_left=imgsplit(img,2)
img_front=imgsplit(img,5)
img_right=imgsplit(img,1)
img_back=imgsplit(img,6)
img_top=imgsplit(img,4)
img_bottom=imgsplit(img,3)

xlength=math.ceil((iwidth/2)*(2**0.5))
linesque_t=np.zeros([xlength,iwidth*4],dtype=np.uint8)
linesque_t=cv2.cvtColor(linesque_t,cv2.COLOR_GRAY2BGR)
linesque_b=linesque_t.copy()
list_t=[]

def rotate(imgr,centerP,angle,pos):
    M = cv2.getRotationMatrix2D(centerP, angle, 1.0)    
    M[0,2] += iwidth//2-centerP[0]
    M[1,2] += iwidth-centerP[1]-1       
    rotated = cv2.warpAffine(imgr, M,(2*xlength,2*xlength))    
    y=np.dot(M,np.array([[pos[0]],[pos[1]],[1]]))[1][0] 
   
    x1=iwidth//2
    y1=int(iwidth-1)
    y=round(y)
    y=max(y,iwidth-xlength)
    return rotated[y:y1+1,x1:x1+1] , y1-y+1

def rotfilt():
    #第1块,[135度-180度)
    for i in range(iwidth//2):
        #print("1-",i)
        pos=(iwidth/2-1,iwidth/2-1)
        centerp=(0,i)
        angle=90+math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        
        linesque_t[xlength-y:xlength,i:i+1]=imgr

    #第2块,[180度-225度)
    for i in range(iwidth//2,iwidth):
        pos=(iwidth/2-1,iwidth/2)
        centerp=(0,i)
        angle=90-math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        linesque_t[xlength-y:xlength,i:i+1]=imgr

    #第3块,[225度-270度)
    for i in range(iwidth//2):
        pos=(iwidth/2-1,iwidth/2)
        centerp=(i,iwidth-1)
        angle=math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        linesque_t[xlength-y:xlength,i+iwidth:i+iwidth+1]=imgr

    #第4块,[270度-315度)
    for i in range(iwidth//2,iwidth):
        pos=(iwidth/2,iwidth/2)
        centerp=(i,iwidth-1)
        angle=-math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        linesque_t[xlength-y:xlength,i+iwidth:i+iwidth+1]=imgr

    #第5块,[315度-360度)
    for i in range(iwidth,iwidth//2,-1):
        pos=(iwidth/2,iwidth/2)
        centerp=(iwidth-1,i-1)
        angle=math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180-90
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        
        linesque_t[xlength-y:xlength,3*iwidth-i:3*iwidth-i+1]=imgr

    #第6块,[0度-45度)
    for i in range(iwidth//2,0,-1):
        pos=(iwidth/2,iwidth/2-1)
        centerp=(iwidth-1,i-1)
        angle=-90-math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        linesque_t[xlength-y:xlength,3*iwidth-i:3*iwidth-i+1]=imgr

    #第7块,[45度-90度)
    for i in range(iwidth,iwidth//2,-1):
        pos=(iwidth/2,iwidth/2-1)
        centerp=(i-1,0)
        angle=-180+math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        linesque_t[xlength-y:xlength,4*iwidth-i:4*iwidth-i+1]=imgr

    #第8块,[90度-135度)
    for i in range(iwidth//2,0,-1):
        pos=(iwidth/2-1,iwidth/2-1)
        centerp=(i-1,0)
        angle=-180-math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotate(img_top,centerp,angle,pos)
        list_t.append(y)
        linesque_t[xlength-y:xlength,4*iwidth-i:4*iwidth-i+1]=imgr


def rotateb(imgr,centerP,angle,pos):
    M = cv2.getRotationMatrix2D(centerP, angle, 1.0)   
    M[0,2] += iwidth//2-centerP[0]    
    M[1,2] += -centerP[1]   
    rotated = cv2.warpAffine(imgr, M,(2*xlength,2*xlength))    
    y=np.dot(M,np.array([[pos[0]],[pos[1]],[1]]))[1][0] 
    x1=iwidth//2
    y1=0       
    y=min(round(y),xlength-1) 
    return rotated[y1:y+1,x1:x1+1] , y-y1+1

def rotfilb():
    #第1块,[225度-180度)
    for i in range(iwidth,iwidth//2,-1):
        
        pos=(iwidth/2-1,iwidth/2)
        centerp=(0,i-1)
        angle=-90-math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),iwidth-i:iwidth-i+1]=imgr
        

    #第2块,[180度-135度)
    for i in range(iwidth//2,0,-1):
        pos=(iwidth/2-1,iwidth/2-1)
        centerp=(0,i-1)
        angle=math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180-90
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),iwidth-i:iwidth-i+1]=imgr

    #第3块,[135度-90度)
    for i in range(0,iwidth//2):
        pos=(iwidth/2-1,iwidth/2-1)
        centerp=(i,0)
        angle=-math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),i+iwidth:i+iwidth+1]=imgr

    #第4块,[90度-45度)
    for i in range(iwidth//2,iwidth):
        pos=(iwidth/2,iwidth/2-1)
        centerp=(i,0)
        angle=math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),i+iwidth:i+iwidth+1]=imgr

    #第5块,[45度-0度)
    for i in range(0,iwidth//2):
        pos=(iwidth/2,iwidth/2-1)
        centerp=(iwidth-1,i)
        angle=90-math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),2*iwidth+i:2*iwidth+i+1]=imgr

    #第6块,[360度-315度)
    for i in range(iwidth//2,iwidth):
        pos=(iwidth/2,iwidth/2)
        centerp=(iwidth-1,i)
        angle=90+math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),2*iwidth+i:2*iwidth+i+1]=imgr

    #第7块,[270度-315度)
    for i in range(iwidth,iwidth//2,-1):
        pos=(iwidth/2,iwidth/2)
        centerp=(i-1,iwidth-1)
        angle=180-math.atan((i-iwidth/2-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),4*iwidth-i:4*iwidth-i+1]=imgr

    #第8块,[180度-225度)
    for i in range(iwidth//2,0,-1):
        pos=(iwidth/2-1,iwidth/2)
        centerp=(i-1,iwidth-1)
        angle=180+math.atan((iwidth/2-i-1)/(iwidth/2-1))/math.pi*180
        imgr,y=rotateb(img_bottom,centerp,angle,pos)
        list_t.append(y)
        linesque_b[0:int(y),4*iwidth-i:4*iwidth-i+1]=imgr

rotfilt()
rotfilb()

orgout=np.zeros([xlength*2+iwidth,iwidth*4],dtype=np.uint8)
orgout=cv2.cvtColor(orgout,cv2.COLOR_GRAY2BGR)
orgout2=orgout.copy()

orgout[xlength:xlength+iwidth,0:iwidth]=img_left
orgout[xlength:xlength+iwidth,iwidth:iwidth*2]=img_front
orgout[xlength:xlength+iwidth,iwidth*2:iwidth*3]=img_right
orgout[xlength:xlength+iwidth,iwidth*3:iwidth*4]=img_back

orgout[0:xlength,0:iwidth*4]=linesque_t[0:xlength,0:iwidth*4]
orgout[xlength+iwidth:xlength*2+iwidth,0:iwidth*4]=linesque_b[0:xlength,0:iwidth*4]

finout=np.zeros([iwidth*2,iwidth*4],dtype=np.uint8)
finout=cv2.cvtColor(finout,cv2.COLOR_GRAY2BGR)

for i in range(iwidth*4):
    
    rimg=orgout[(xlength-list_t[i]):xlength+iwidth+list_t[i+iwidth*4],i:i+1]   
    orgout2[0:list_t[i]+iwidth+list_t[i+iwidth*4],i:i+1] =rimg       
    rimg=cv2.resize(rimg,(1,iwidth*2),interpolation=cv2.INTER_LINEAR)
    finout[0:iwidth*2,i:i+1]=rimg

cv2.namedWindow("Image")
cv2.imshow("Image", finout)
cv2.namedWindow("Image2")
cv2.imshow("Image2", orgout)

cv2.namedWindow("Image3")
cv2.imshow("Image3", orgout2)

cv2.imwrite(sdir+outfile,finout)

cv2.waitKey (0)
cv2.destroyAllWindows()

 

 

 


版权声明:本文为loverzai原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。