Thật không may, câu trả lời của Oliver Wilken đã không dẫn đến hình ảnh được hiển thị.Có lẽ vì một phiên bản OpenCV khác nhau?Ở đây phiên bản được thông qua của tôi thêm một số tính năng:
- mở rộng quy mô và đệm của trực tràng, tức là để có được các bộ phận bên ngoài trực tràng ban đầu
- góc của hình ảnh kết quả có thể được cấu hình theo trực tràng, tức là góc 0 hoặc 90 [deg] sẽ trả về trực tràng theo chiều ngang hoặc theo chiều dọc
- Trả về ma trận dịch để xoay những thứ khác, ví dụ:điểm, dòng, ...
- Chức năng của người trợ giúp cho lập chỉ mục mảng Numpy và OpenCV và thao tác trực tràng
Mã số
import cv2
import numpy as np
def img_rectangle_cut[img, rect=None, angle=None]:
"""Translate an image, defined by a rectangle. The image is cropped to the size of the rectangle
and the cropped image can be rotated.
The rect must be of the from [tuple[center_xy], tuple[width_xy], angle].
The angle are in degrees.
PARAMETER
---------
img: ndarray
rect: tuple, optional
define the region of interest. If None, it takes the whole picture
angle: float, optional
angle of the output image in respect to the rectangle.
I.e. angle=0 will return an image where the rectangle is parallel to the image array axes
If None, no rotation is applied.
RETURNS
-------
img_return: ndarray
rect_return: tuple
the rectangle in the returned image
t_matrix: ndarray
the translation matrix
"""
if rect is None:
if angle is None:
angle = 0
rect = [tuple[np.array[img.shape] * .5], img.shape, 0]
box = cv2.boxPoints[rect]
rect_target = rect_rotate[rect, angle=angle]
pts_target = cv2.boxPoints[rect_target]
# get max dimensions
size_target = np.int0[np.ceil[np.max[pts_target, axis=0] - np.min[pts_target, axis=0]]]
# translation matrix
t_matrix = cv2.getAffineTransform[box[:3].astype[np.float32],
pts_target[:3].astype[np.float32]]
# cv2 needs the image transposed
img_target = cv2.warpAffine[cv2.transpose[img], t_matrix, tuple[size_target]]
# undo transpose
img_target = cv2.transpose[img_target]
return img_target, rect_target, t_matrix
def reshape_cv[x, axis=-1]:
"""openCV and numpy have a different array indexing [row, cols] vs [cols, rows], compensate it here."""
if axis < 0:
axis = len[x.shape] + axis
return np.array[x].astype[np.float32][[*[slice[None]] * axis, slice[None, None, -1]]]
def connect[x]:
"""Connect data for a polar or closed loop plot, i.e. np.append[x, [x[0]], axis=0]."""
if isinstance[x, np.ma.MaskedArray]:
return np.ma.append[x, [x[0]], axis=0]
else:
return np.append[x, [x[0]], axis=0]
def transform_np[x, t_matrix]:
"""Apply a transform on a openCV indexed array and return a numpy indexed array."""
return transform_cv2np[reshape_cv[x], t_matrix]
def transform_cv2np[x, t_matrix]:
"""Apply a transform on a numpy indexed array and return a numpy indexed array."""
return reshape_cv[cv2.transform[np.array[[x]].astype[np.float32], t_matrix][0]]
def rect_scale_pad[rect, scale=1., pad=40.]:
"""Scale and/or pad a rectangle."""
return [rect[0],
tuple[[np.array[rect[1]] + pad] * scale],
rect[2]]
def rect_rotate[rect, angle=None]:
"""Rotate a rectangle by an angle in respect to it's center.
The rect must be of the from [tuple[center_xy], tuple[width_xy], angle].
The angle is in degrees.
"""
if angle is None:
angle = rect[2]
rad = np.deg2rad[np.abs[angle]]
rot_matrix_2d = np.array[[[np.cos[rad], np.sin[rad]],
[np.sin[rad], np.cos[rad]]]]
# cal. center of rectangle
center = np.sum[np.array[rect[1]].reshape[1, -1] * rot_matrix_2d, axis=-1] * .5
center = np.abs[center]
return tuple[center], rect[1], angle
Example:
# Generate Image
img = np.zeros[[1200, 660], dtype=np.uint8]
# Draw some lines and gen. points
x_0 = np.array[[150,600]]
x_1 = np.int0[x_0 + np.array[[100, 100]]]
x_2 = np.int0[x_0 + np.array[[100, -100]]*2.5]
img = cv2.line[img,tuple[x_0],tuple[x_1],1,120]
img = cv2.line[img,tuple[x_0],tuple[x_2],1,120]
points = np.array[[x_0, x_1, x_2]]
# Get Box
rect = cv2.minAreaRect[np.argwhere[img]]
# Apply transformation
rect_scale = rect_scale_pad[rect, scale = 1., pad = 40.]
img_return, rect_target, t_matrix = img_rectangle_cut[
img,
rect_scale,
angle=0,
angle_normalize=True # True angel=0 vertical; angel=90 horizontal
]
# PLOT
fig, ax = plt.subplots[ncols=2, figsize=[10,5]]
ax = ax.flatten[]
ax[0].imshow[img]
box_i = reshape_cv[cv2.boxPoints[rect]]
ax[0].plot[*connect[box_i].T, 'o-', color='gray', alpha=.75, label='Original Box']
box_i = reshape_cv[cv2.boxPoints[rect_scale]]
ax[0].plot[*connect[box_i].T, 'o-', color='green', alpha=.75, label='Scaled Box']
ax[0].plot[*points.T, 'o', label='Points']
ax[1].imshow[img_return]
box_i = transform_cv2np[cv2.boxPoints[rect], t_matrix]
ax[1].plot[*connect[box_i].T, 'o-', color='gray', alpha=.75, label='Original Box']
point_t = transform_np[points, t_matrix]
ax[1].plot[*point_t.T, 'o', label='Points']
ax[0].set_title['Original']
ax[1].set_title['Translated']
for axi in ax:
axi.legend[loc=1]
plt.tight_layout[]