[英]OpenCV Python : rotate image without cropping sides
這是迄今為止我找到的旋轉圖像同時避免裁剪圖像的最佳解決方案。
import cv2
def rotate_image(mat, angle):
"""
Rotates an image (angle in degrees) and expands image to avoid cropping
"""
height, width = mat.shape[:2] # image shape has 3 dimensions
image_center = (width/2, height/2) # getRotationMatrix2D needs coordinates in reverse order (width, height) compared to shape
rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.)
# rotation calculates the cos and sin, taking absolutes of those.
abs_cos = abs(rotation_mat[0,0])
abs_sin = abs(rotation_mat[0,1])
# find the new width and height bounds
bound_w = int(height * abs_sin + width * abs_cos)
bound_h = int(height * abs_cos + width * abs_sin)
# subtract old image center (bringing image back to origo) and adding the new image center coordinates
rotation_mat[0, 2] += bound_w/2 - image_center[0]
rotation_mat[1, 2] += bound_h/2 - image_center[1]
# rotate image with the new bounds and translated rotation matrix
rotated_mat = cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h))
return rotated_mat
當角度為 90*n 時,您可以添加檢查以避免一些計算,但此函數將按原樣適用於任何角度。
如果您只關心 90 度旋轉 numpy 。 它更容易並且適用於opencv輸入:
import numpy as np
rotated_image = np.rot90(im)
由於我不知道您的代碼,我仍然猜想使用imutils.rotate_bound
函數可以解決問題。 例如: rotate = imutils.rotate_bound(image, angle)
這是使用 cv2.rotate(frame,rotateCode = 1) 旋轉圖像幀並使用幀的 cv2.CAP_PROP_FRAME_WIDTH 和 cv2.CAP_PROP_FRAME_HEIGHT 重新縮放或調整大小的最簡單方法。
import numpy as np
import cv2
cam = cv2.VideoCapture(2)
while(True):
# Capture frame-by-frame
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 640) # You can change frame width by chaning number.
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # You can change frame height by chaning number.
ret, frame = cam.read()
new_frame=cv2.rotate(frame,rotateCode = 1)
# Display the resulting frame
cv2.imshow('frame',new_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cam.release()
cv2.destroyAllWindows()
希望對您有所幫助。
雖然這個問題是針對 CV2 提出的,但您可以使用 python 的本機圖像庫來做到這一點。
rotate_degrees = -90
img = Image.open(input_file_path)
img2 = img.rotate(rotate_degrees, expand=True)
img2.save(output_file_path)
如果您在旋轉命令中省略expand=True
,您將得到一個看起來像 OP 右手照片的結果。
您也可以使用填充,即在圖像的兩側添加邊框,然后將其旋轉以避免從原始圖像中裁剪。
def rotate_im(image, angle)
image_height = image.shape[0]
image_width = image.shape[1]
diagonal_square = (image_width*image_width) + (
image_height* image_height
)
#
diagonal = round(sqrt(diagonal_square))
padding_top = round((diagonal-image_height) / 2)
padding_bottom = round((diagonal-image_height) / 2)
padding_right = round((diagonal-image_width) / 2)
padding_left = round((diagonal-image_width) / 2)
padded_image = cv2.copyMakeBorder(image,
top=padding_top,
bottom=padding_bottom,
left=padding_left,
right=padding_right,
borderType=cv2.BORDER_CONSTANT,
value=0
)
padded_height = padded_image.shape[0]
padded_width = padded_image.shape[1]
transform_matrix = cv2.getRotationMatrix2D(
(padded_height/2,
padded_width/2), # center
angle, # angle
1.0) # scale
rotated_image = cv2.warpAffine(padded_image,
transform_matrix,
(diagonal, diagonal),
flags=cv2.INTER_LANCZOS4)
return rotated_image
它很簡單,不需要任何warpaffine或任何計算檢查此代碼
import numpy as np
from PIL import ImageGrab
import cv2
angle = -90
scale = 1.0
while True:
img = ImageGrab.grab()
img_np = np.array(img)
frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
new = cv2.rotate(frame,rotateCode = 0)# this is the line to rotate the image
true = cv2.resize(new, (0,0), fx = 0.6, fy = 0.6) # with fxand fy u can control the size
cv2.imshow('output', true)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
這是來自SciPy的ndimage.rotate
的替代方法
from scipy.ndimage import rotate as rotate_image
#rotation angle in degree
rotated_img1 = rotate_image(img,90)
rotated_img2 = rotate_image(img,-110)
rotated_img3 = rotate_image(img,-45)
# angles extending beyond 360 are calculated appropriately:
rotated_img4 = rotate_image(img,390)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.