Numpy平移,旋轉,鏡像操作


一、圖像平移

 二、圖像水平鏡像

 三、圖像垂直鏡像

 四、圖像縮放

 五、圖像旋轉(順時針)

 正確代碼:

import cv2 import math import numpy as np class Img: def __init__(self,image,rows,cols,center=[0,0]): self.src=image #原始圖像
        self.rows=rows #原始圖像的行
        self.cols=cols #原始圖像的列
        self.center=center #旋轉中心,默認是[0,0]

    def Move(self,delta_x,delta_y):      #平移
        #delta_x>0左移,delta_x<0右移
        #delta_y>0上移,delta_y<0下移
        self.transform=np.array([[1,0,delta_x],[0,1,delta_y],[0,0,1]]) def Zoom(self,factor):               #縮放
        #factor>1表示縮小;factor<1表示放大
        self.transform=np.array([[factor,0,0],[0,factor,0],[0,0,1]]) def Horizontal(self):                #水平鏡像
        self.transform=np.array([[1,0,0],[0,-1,self.cols-1],[0,0,1]]) def Vertically(self):                #垂直鏡像
        self.transform=np.array([[-1,0,self.rows-1],[0,1,0],[0,0,1]]) def Rotate(self,beta):               #旋轉
        #beta>0表示逆時針旋轉;beta<0表示順時針旋轉
        self.transform=np.array([[math.cos(beta),-math.sin(beta),0], [math.sin(beta), math.cos(beta),0], [ 0, 0, 1]]) def Process(self): self.dst=np.zeros((self.rows,self.cols),dtype=np.uint8) for i in range(self.rows): for j in range(self.cols): src_pos=np.array([i-self.center[0],j-self.center[1],1]) [x,y,z]=np.dot(self.transform,src_pos) x=int(x)+self.center[0] y=int(y)+self.center[1] if x>=self.rows or y>=self.cols or x<0 or y<0: self.dst[i][j]=255
                else: self.dst[i][j]=self.src[x][y] if __name__=='__main__': src=cv2.imread('.\jay.bmp',0) rows = src.shape[0] cols = src.shape[1] cv2.imshow('src', src) img=Img(src,rows,cols,[248,231]) img.Vertically() #鏡像
 img.Process() ''' img.Rotate(-math.radians(30)) #旋轉 img.Process() img.Move(-50,-50) #平移 img.Process() img.Zoom(0.5) #縮放 img.Process() ''' cv2.imshow('dst', img.dst) cv2.waitKey(0)

旋轉易錯點:

                       

           原始圖                                    beta=-30°

  再Rotate的函數中,我們的transform矩陣完全是按照beta>0時為為逆時針旋轉。但是我們需要注意到 時process:self.dst[i][j]=self.src[x][y];相當於又一次取反。最終,當beta>0時,我們是順時針旋轉

  這個時候你可能產生疑問,我直接寫成:self.dst[x,y]=self.src[i,j]不就是逆時針的了????

結果如下:

 原因分析:可能是因為在遍歷過程中dst的元素無法全部訪問到,會保留默認的像素值為0的點。

六、旋轉延拓

  上述方法的旋轉之后的圖像大小與原圖像大小相等,接下來我們來看一個完全保留旋轉后圖像的方法:

import cv2 import math import numpy as np def XRotate(image, angle): h, w = image.shape anglePi = angle * math.pi / 180.0 cosA = math.cos(anglePi) sinA = math.sin(anglePi) X1 = math.ceil(abs(0.5 * h * cosA + 0.5 * w * sinA)) X2 = math.ceil(abs(0.5 * h * cosA - 0.5 * w * sinA)) Y1 = math.ceil(abs(-0.5 * h * sinA + 0.5 * w * cosA)) Y2 = math.ceil(abs(-0.5 * h * sinA - 0.5 * w * cosA)) hh = int(2 * max(Y1, Y2)) ww = int(2 * max(X1, X2)) emptyImage2 = np.zeros((hh, ww), np.uint8) for i in range(hh): for j in range(ww): x = cosA * i + sinA * j - 0.5 * ww * cosA - 0.5 * hh * sinA + 0.5 * w y =  cosA * j- sinA * i+ 0.5 * ww * sinA - 0.5 * hh * cosA + 0.5 * h x = int(x) y = int(y) if x > -1 and x < h and y > -1 and y < w : emptyImage2[i, j] = image[x, y]*255
 
    return emptyImage2 # image = cv2.imread("e:\\lena.bmp")
iXRotate12 = XRotate(img[:,:,1], 30) cv2.imshow('image', img) cv2.imshow('iXRotate12', iXRotate12) cv2.waitKey(0)

   代碼解釋:X1, X2, Y1, Y2的求解是考慮到了beta的正負;其次在兩層的for循環里,cosA * i + sinA * j代表我們的transform矩陣是順時針旋轉;- 0.5 * ww * cosA - 0.5 * hh * sinA + 0.5 * w代表的是:根據圖像中心進行旋轉;同樣的,由於我們 emptyImage2[i, j] = image[x, y]*255 操作,我們transform雖然是按照順時針生成,但是最終結果會相反一下,為逆時針。

 

                          

 原始圖像                                                       旋轉之后

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM