python opencv实现图片旋转矩形分割

时间:2022-08-23 17:29:42

有时候需要对有角度的矩形框内图像从原图片中分割出来。这里的程序思想是,先将图片进行矩形角度的旋转,使有角度的矩形处于水平状态后,根据原来坐标分割图片。
参考:python opencv实现旋转矩形框裁减功能

修改原来的程序:

1.旋转函数的输入仅为矩形的四点坐标
2.角度由公式计算出来
3.矩形四点pt1,pt2,pt3,pt4由txt文件读入
4.在旋转程序中还处理了顺时针和逆时针及出现矩形框翻转的问题。

代码:

python" id="highlighter_894866">
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# -*- coding:utf-8 -*-
import cv2
from math import *
import numpy as np
import time,math
import os
import re
 
'''旋转图像并剪裁'''
def rotate(
    img, # 图片
    pt1, pt2, pt3, pt4
):
  print pt1,pt2,pt3,pt4
  withrect = math.sqrt((pt4[0] - pt1[0]) ** 2 + (pt4[1] - pt1[1]) ** 2) # 矩形框的宽度
  heightrect = math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) **2)
  print withrect,heightrect
  angle = acos((pt4[0] - pt1[0]) / withrect) * (180 / math.pi) # 矩形框旋转角度
  print angle
 
  if pt4[1]>pt1[1]:
    print "顺时针旋转"
  else:
    print "逆时针旋转"
    angle=-angle
 
  height = img.shape[0] # 原始图像高度
  width = img.shape[1# 原始图像宽度
  rotatemat = cv2.getrotationmatrix2d((width / 2, height / 2), angle, 1) # 按angle角度旋转图像
  heightnew = int(width * fabs(sin(radians(angle))) + height * fabs(cos(radians(angle))))
  widthnew = int(height * fabs(sin(radians(angle))) + width * fabs(cos(radians(angle))))
 
  rotatemat[0, 2] += (widthnew - width) / 2
  rotatemat[1, 2] += (heightnew - height) / 2
  imgrotation = cv2.warpaffine(img, rotatemat, (widthnew, heightnew), bordervalue=(255, 255, 255))
  cv2.imshow('rotateimg2', imgrotation)
  cv2.waitkey(0)
 
  # 旋转后图像的四点坐标
  [[pt1[0]], [pt1[1]]] = np.dot(rotatemat, np.array([[pt1[0]], [pt1[1]], [1]]))
  [[pt3[0]], [pt3[1]]] = np.dot(rotatemat, np.array([[pt3[0]], [pt3[1]], [1]]))
  [[pt2[0]], [pt2[1]]] = np.dot(rotatemat, np.array([[pt2[0]], [pt2[1]], [1]]))
  [[pt4[0]], [pt4[1]]] = np.dot(rotatemat, np.array([[pt4[0]], [pt4[1]], [1]]))
 
  # 处理反转的情况
  if pt2[1]>pt4[1]:
    pt2[1],pt4[1]=pt4[1],pt2[1]
  if pt1[0]>pt3[0]:
    pt1[0],pt3[0]=pt3[0],pt1[0]
 
  imgout = imgrotation[int(pt2[1]):int(pt4[1]), int(pt1[0]):int(pt3[0])]
  cv2.imshow("imgout", imgout) # 裁减得到的旋转矩形框
  cv2.waitkey(0)
  return imgrotation # rotated image
 
 
# 根据四点画原矩形
def drawrect(img,pt1,pt2,pt3,pt4,color,linewidth):
  cv2.line(img, pt1, pt2, color, linewidth)
  cv2.line(img, pt2, pt3, color, linewidth)
  cv2.line(img, pt3, pt4, color, linewidth)
  cv2.line(img, pt1, pt4, color, linewidth)
 
# 读出文件中的坐标值
def readtxt(directory,imagename,last):
  filetxt=directory+"//rawlabel//"+imagename[:7]+last # txt文件名
  gettxt=open(filetxt, 'r') # 打开txt文件
  lines = gettxt.readlines()
  length=len(lines)
  for i in range(0,length,4):
    pt2=list(map(float,lines[i].split(' ')[:2]))
    pt1=list(map(float,lines[i+1].split(' ')[:2]))
    pt4=list(map(float,lines[i+2].split(' ')[:2]))
    pt3=list(map(float,re.split('\n| ',lines[i+3])[:2]))
    # float转int
 
    pt2=list(map(int,pt2))
    pt1=list(map(int,pt1))
    pt4=list(map(int,pt4))
    pt3=list(map(int,pt3))
 
    imgsrc = cv2.imread(imagename)
    drawrect(imgsrc, tuple(pt1),tuple(pt2),tuple(pt3),tuple(pt4), (0, 0, 255), 2)
    cv2.imshow("img", imgsrc)
    cv2.waitkey(0)
    rotate(imgsrc,pt1,pt2,pt3,pt4)
 
 
if __name__=="__main__":
  directory = "g://grasp//grapcode//trainimage//jpg//4"
  last = 'cneg.txt'
  imagename="pcd0247r.png"
  readtxt(directory,imagename,last)

原带角度的矩形框:

python opencv实现图片旋转矩形分割

旋转矩形框:

python opencv实现图片旋转矩形分割

分割:

python opencv实现图片旋转矩形分割

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/u013948010/article/details/78605043