下面咱們來看看更一般一點的作法:以圖像的中心爲圓心進行旋轉。python
這裏涉及到一個座標系的轉換問題。看下圖:dom
在矩陣中咱們的座標系一般是AB和AC方向的,而傳統的笛卡爾直角座標系是DE和DF方向的。spa
令圖像表示爲M×N的矩陣,對於點A而言,兩座標系中的座標分別是(0,0)和(-N/2,M/2)code
矩陣中點(x',y')轉換爲笛卡爾座標系(x,y)的轉換關係爲:orm
逆變換爲blog
因而咱們獲得圖像以中心旋轉的思路圖片
因而獲得最後結果ip
python中numpy有矩陣運算能力,但這裏咱們直接進行數值計算就能夠了。用方程表示以下:utf-8
恩,圖片旋轉後其實真個圖片應該變大,而咱們仍是按原大小考慮的ci
那咱們要是要查看完整圖片呢。
咱們先得算出變換後圖片的大小
仍是看看下圖:
好吧。其實很簡單。原圖是裏面灰色部分。旋轉後,新圖片有效部分(紅色部分)的頂點落在新圖片四條邊上
取旋轉後四點座標中絕對值最大的x、y便可,事實上咱們只須要計算兩個點就能夠了。
相應的,咱們的計算公式也要作一些改動
N'和M'對應於新圖的寬和長
上面的方法不怎麼成功。。。。。。。。。。。。。。。。。。。。
下面是又一種。。。。。。。。。。。
1 # -*-coding:utf-8-*- 2 3 import cv2 4 from math import * 5 import numpy as np 6 from scipy.spatial.distance import pdist 7 8 # x=np.random.random(100) 9 # y=np.random.random(100) 10 # 11 # #方法一:根據公式求解,2維 12 # d1=np.dot(x,y)/(np.linalg.norm(x)*np.linalg.norm(y)) 13 # 14 # # print d1 15 # 16 # #方法二:根據scipy庫求解,n維 17 # X=np.vstack([x,y]) 18 # d2=1-pdist(X,'cosine') 19 20 # print d2 21 22 img = cv2.imread("/home/260158/code/Haikang/imgRotation.jpg") 23 height,width=img.shape[:2] 24 25 #(1)如何計算這個旋轉角度 26 # degree = np.dot(x,y)/(np.linalg.norm(x)*np.linalg.norm(y)) 27 degree=-30 28 29 #(2)旋轉後的尺寸 30 #@radians(),角度轉換爲弧度 31 heightNew=int(width * fabs(sin(radians(degree))) + height*fabs(cos(radians(degree)))) 32 widthNew=int(height * fabs(sin(radians(degree))) + width*fabs(cos(radians(degree)))) 33 34 #(3)求旋轉矩陣,以圖片中心點爲旋轉中心 35 matRotation = cv2.getRotationMatrix2D((width/2,height/2),degree,1) 36 37 38 matRotation[0,2] +=(widthNew-width)/2 #?????重點在這步,目前不懂爲何加這步 39 matRotation[1,2] +=(heightNew-height)/2 #?????重點在這步 40 41 #(4)最後獲得的圖像,邊界是黑色 42 imgRotation = cv2.warpAffine(img, matRotation, (widthNew,heightNew), borderValue=(0,0,0)) 43 44 45 #我把像素值 > 0 的區域提取出來 46 #做二值化,將閾值設置爲50,閾值類型爲cv2.THRESH_BINARY,則灰度在大於50的像素其值將設置爲255,其它像素設置爲0 47 #retval, dst = cv2.threshold(imgRotation, 50, 255, cv2.THRESH_BINARY) 48 49 cv2.imshow("img",img) 50 cv2.imshow("imgRotation",imgRotation) 51 #cv2.imwrite("imgRotation_1.jpg",imgRotation) 52 cv2.waitKey(0)