[python] 作業記錄一、利用opencv,numpy旋轉圖片無黑邊(輪子必須由我造!!!)
- 1. 第三方庫的安裝
- 2. 程式目的
- 3. 圖片理解
- 4. 撰寫代碼
- (1).旋轉順時針90°
- (2).逆時針旋轉90°
- (3).旋轉180°
- (4).水平翻轉與垂直翻轉
- 總結
- 代碼
- 寄語
1. 第三方庫的安裝
opencv和numpy不是python的自帶庫,所以需要我們進行手動安裝( 注意是opencv-python )
pip install opencv-python
pip install numpy
2. 程式目的
領導要求把圖片進行旋轉但不能有黑邊…

領導安排的作業能不做嗎? 不能,不關錢的事,主要就是想打代碼了
opencv自帶有旋轉圖片的方法,不過輪子必須由我造貫徹一切

3. 圖片理解
簡單來說,彩色圖片在python-opencv中是以這樣的形式存在的,如下圖
把矩陣看成只有三層的正方體,也就是三通道,每一層都是一串十六進制編碼,每一個像素點都是從上向下組成的,例如:0xd5c5a5 ,形成一個顏色像素點,這就是平時程式使用的RGB顏色"#******",通過像素點的組合才形成我們看到的圖片,(圖是自己畫的,有點丑,)

4. 撰寫代碼
從路上拍張動物園里的大熊貓來測驗

(1).旋轉順時針90°
思路:創建一個與原本影像尺寸一致的空矩陣,遍歷原始影像的長寫入空矩陣的寬保持通道數不變尺寸不變,開擼~
src = cv.imread(pictrue_path)
height = src.shape[0] # 圖片的高度、圖片的垂直尺寸
width = src.shape[1] # 圖片的寬度、圖片的水平尺寸
channels = src.shape[2] # 通道
img = np.zeros([width, height, channels], np.uint8)
for row in range(height):
img[:, height - row - 1, :] = src[row, :, :]
旋轉結果:

(2).逆時針旋轉90°
思路:```同上,當然了,得改變一下寫入的位置
src = cv.imread(pictrue_path)
height = src.shape[0] # 圖片的高度、圖片的垂直尺寸
width = src.shape[1] # 圖片的寬度、圖片的水平尺寸
channels = src.shape[2] # 通道
img = np.zeros([width, height, channels], np.uint8)
for row in range(height):
img[:, row, :] = src[row, :, :]
旋轉后:

可以看到圖片還不是我們想要的效果,還得上下翻轉一下
新增陳述句:
img = img[::-1]
旋轉結果:

當當當當~!正確旋轉
(3).旋轉180°
思路:上下翻轉后看看結果
src = cv.imread(pictrue_path)
height = src.shape[0] # 圖片的高度、圖片的垂直尺寸
width = src.shape[1] # 圖片的寬度、圖片的水平尺寸
channels = src.shape[2] # 通道
temp = src[::-1]

思路:現在得水平翻轉一下才能達到我們的效果,創建一個與原本影像尺寸一致的空矩陣,遍歷原始影像的第一個寬寫入空矩陣的最后一個寬保持通道數不變尺寸不變
添加代碼:
img = np.zeros([height, width, channels], np.uint8)
for col in range(width):
img[:, width - col - 1, :] = temp[:, col, :]
旋轉結果:

完全正確~?
(4).水平翻轉與垂直翻轉
認真看的小伙伴應該已經看到了
水平翻轉:
src = cv.imread(pictrue_path)
height = src.shape[0] # 圖片的高度、圖片的垂直尺寸
width = src.shape[1] # 圖片的寬度、圖片的水平尺寸
channels = src.shape[2] # 通道
img = np.zeros([height, width, channels], np.uint8)
for col in range(width):
img[:, width - col - 1, :] = src[:, col, :]
旋轉結果:

垂直翻轉:
src = cv.imread(pictrue_path)
height = src.shape[0] # 圖片的高度、圖片的垂直尺寸
width = src.shape[1] # 圖片的寬度、圖片的水平尺寸
channels = src.shape[2] # 通道
img = src[::-1]
旋轉結果:

總結
上述所有的旋轉代碼在我的電腦運行基本只需要0.14s,跟opencv自帶的旋轉圖片不相上下,旗鼓相當,鑼鼓喧天,鞭炮齊鳴,紅旗招展,人山人海····
代碼
我將代碼寫成一個方法,便于使用
def create_image(pictrue_path, width, height, channel, img, angle):
global img1
if angle == 90: # 右旋90°
img1 = np.zeros([width, height, channel], np.uint8)
for row in range(height):
img1[:, height - row - 1, :] = img[row, :, :]
elif angle == 270: # 左旋轉90° 右旋270°
img1 = np.zeros([width, height, channel], np.uint8)
for row in range(height):
img1[:, row, :] = img[row, :, :]
img1 = img1[::-1]
elif angle == 180: # 旋轉180°
temp = img[::-1]
img1 = np.zeros([height, width, channel], np.uint8)
for col in range(width):
img1[:, width - col - 1, :] = temp[:, col, :]
elif angle == -180: # 垂直翻轉180°
img1 = img[::-1]
elif angle == -90: # 水平翻轉90°
img1 = np.zeros([height, width, channel], np.uint8)
for col in range(width):
img1[:, width - col - 1, :] = img[:, col, :]
new_img = os.path.split(pictrue_path)[1].split('.')[0] + '副本.jpg'
cv.imencode('.jpg', img1)[1].tofile(new_img)
return {'status': 1, 'msg': '成功處理圖片!', 'path': new_img}
def run_pictrue_spin(pictrue_path, angle):
if not os.path.exists(pictrue_path):
return {'status': 2, 'msg': '檔案路徑不存在!'}
src = cv.imread(pictrue_path)
height = src.shape[0] # 圖片的高度、圖片的垂直尺寸
width = src.shape[1] # 圖片的寬度、圖片的水平尺寸
channels = src.shape[2] # 通道
result = create_image(pictrue_path, width, height, channels, src, angle) # angle=90 or 270 or 180 or -90 or -180
return result
寄語
路過的小伙伴一鍵三連唄!不許下次!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298755.html
標籤:其他
