python cv2 获取矩形,居中,旋转

下面的代码可以让一个图片中的任意位置,角度的矩形,旋转到正确的位置,并且居中显示。
import cv2
import numpy as np
import matplotlib.pyplot as plt
from pynput import keyboard,mouse

def plt_show(image):
plt.imshow(image)
plt.axis('off')
plt.show()

def show(image):
cv2.imshow("raw", image)
cv2.waitKey(0)

def move_right():
print("moving right")

def move_left():
print("moving left")

def move_up():
print("moving up")

def move_down():
print("moving down")

def save_picture(angel,image):
cv2.imwrite("%s/%s.jpg" % ('image', angel),image.shape[0],image.shape[1])

def handlToGray(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, TRE = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY) # 图像二值化
return TRE
#图像转动一定角度
def rotate_bound(image, angle):
# grab the dimensions of the image and then determine the
# center
(h, w) = image.shape[:2]
(cX, cY) = (w // 2, h // 2)

# grab the rotation matrix (applying the negative of the
# angle to rotate clockwise), then grab the sine and cosine
# (i.e., the rotation components of the matrix)
M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])

# compute the new bounding dimensions of the image
nW = int((h * sin) + (w * cos))
nH = int((h * cos) + (w * sin))

# adjust the rotation matrix to take into account translation
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY

# perform the actual rotation and return the image
return cv2.warpAffine(image, M, (nW, nH))
#图像按照给定的x,y 值进行平移
def moving_bound(image,x,y):
(h, w) = image.shape[:2]
M = np.float32([[1,0,-x],[0,1,-y]])
return cv2.warpAffine(image, M, (w, h))
#找到矩形的旋转角度
def find_rect(image):
gray = handlToGray(image)
contours, hierarchy = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(contours[0])
return rect


#获取矩形的偏移坐标
def getoffset(image):
(h, w) = image.shape[:2]
cx = int(w / 2)
cy = int(h / 2)
x_left = 0;
x_right = 0;
y_up = 0;
y_down = 0;

x_total = 0;
y_total = 0;

# 获取左边边框
for i in range(cx, 0, -1):
mx = image[cy][i] # 先取高度,再取宽度
if (mx == 0):
x_left = i
break
# 获取右边边框
for i in range(cx, w, 1):
mx = image[cy][i]
if (mx == 0):
x_right = i
break
x_total = x_right - x_left

# 获取上边框
for i in range(cy, 0, -1):
my = image[i][cx]
if (my == 0):
y_up = i
break
# 获取下边框
for i in range(cy, h, 1):
mx = image[i][cx]
if (mx == 0):
y_down = i
break
y_total = y_down - y_up

x_offset = (x_left + x_total / 2) - cx
y_offset = (y_up + y_total / 2) - cy

return x_offset, y_offset, x_total, y_total



def on_press(key):
pass

def on_release(key):
if key == keyboard.Key.esc: # Stop listener
return False
elif key == keyboard.Key.right:
move_right()
elif key == keyboard.Key.left:
move_left()
elif key == keyboard.Key.up:
move_up()
elif key == keyboard.Key.down:
move_down()



def on_move(x, y):
pass

def on_click(x, y, button, pressed):
pass

def on_scroll(x, y, dx, dy):
pass

def main():

image = cv2.imread("image/raw2.jpg")
rect = find_rect(image)
angle = rect[2] #角度
im = rotate_bound(image, -angle)
rect = find_rect(im)
print(rect)
x,y = rect[0]
width, height = rect[1]
box = cv2.boxPoints(rect)
(h, w) = im.shape[:2]
cx = int(w / 2)
cy = int(h / 2)
im = moving_bound(im,x-cx,y-cy)
if width < height:
im = rotate_bound(im, 90)
TRE = handlToGray(im)
plt_show(TRE)

main()

# Collect events until released
keyboard_listener = keyboard.Listener(on_press=on_press, on_release=on_release)
mouse_listener = mouse.Listener(on_click=on_click, on_move=on_move, on_scroll=on_scroll)
lst = [keyboard_listener, mouse_listener]

for t in lst: t.start()
for t in lst: t.join()




发表评论