目标检测数据增强之旋转

在做目标检测时需要做旋转变换,传统方法是,图像旋转之后,包围盒也旋转同样角度,然后取旋转后包围盒的最大外接矩形做新的包围盒,做的时候发现旋转角度变大时包围盒的误差很明显,受这篇文章:目标检测中的旋转增强 - 知乎的启发,写了新的旋转增强代码

文中取的是旋转后的椭圆的最大外接矩形,这里工程上做近似,采样椭圆上的12个点,找这12个点旋转后的外接矩形,python代码如下:

import math
import random
import numpy as np
import cv2

#由椭圆的x求y
def _ellipseX2Y(a,b,x,xc,yc):
    m = math.sqrt(b**2 - (x-xc)**2 * b**2 / a**2)
    return yc - m, yc + m

#由椭圆的y求x 其实形式上跟上面的函数是一样的 但怕用的时候弄混 还是写了一个函数
def _ellipseY2X(a,b,y,xc,yc):
    m = math.sqrt(a**2 - (y-yc)**2 * a**2 / b**2)
    return xc - m, xc + m
    
#得到矩形框内接椭圆的采样点
def _getEllipsePt(x1,y1,x2,y2):
    pts = []
    xc = (x1 + x2) / 2
    yc = (y1 + y2) / 2
    a = (x2 - x1) / 2
    b = (y2 - y1) / 2
    #十字架上的点
    pts.append((x1,yc))
    pts.append((xc,y1))
    pts.append((x2,yc))
    pts.append((xc,y2))
    #由x求y
    xtmp = x1 + a / 2
    ytmp1, ytmp2 = _ellipseX2Y(a,b,xtmp,xc,yc)
    pts.append((xtmp,ytmp1))
    pts.append((xtmp,ytmp2))
    xtmp = x1 + a / 2 * 3
    ytmp1, ytmp2 = _ellipseX2Y(a,b,xtmp,xc,yc)
    pts.append((xtmp,ytmp1))
    pts.append((xtmp,ytmp2))
    #由y求x
    ytmp = y1 + b / 2
    xtmp1, xtmp2 = _ellipseY2X(a,b,ytmp,xc,yc)
    pts.append((xtmp1,ytmp))
    pts.append((xtmp2,ytmp))
    ytmp = y1 + b / 2 * 3
    xtmp1, xtmp2 = _ellipseY2X(a,b,ytmp,xc,yc)
    pts.append((xtmp1,ytmp))
    pts.append((xtmp2,ytmp))    
    
    return pts

def _getRotateXY(x,y,matRotate):
    xnew = matRotate[0][0] * x + matRotate[0][1] * y + matRotate[0][2]
    ynew = matRotate[1][0] * x + matRotate[1][1] * y + matRotate[1][2]
    return xnew, ynew


#随机旋转的代码
imgFile = r'test.jpg'
box = [10,10,50,60]
img = cv2.imdecode(np.fromfile(imgFile, dtype=np.uint8), cv2.IMREAD_UNCHANGED)

imgW = img.shape[1]
imgH = img.shape[0]
rotateDeg = random.randint(-20,20)
rotateScale = random.uniform(0.8,1.2)
#旋转矩阵
matRotate = cv2.getRotationMatrix2D((imgW*0.5, imgH*0.5), rotateDeg, rotateScale)
#图像根据旋转矩阵旋转
img = cv2.warpAffine(img, matRotate, (imgW, imgH))
#box取内接椭圆的点
samplePts = _getEllipsePt(box[0],box[1],box[2],box[3])
#采样点做旋转
rotXs = []
rotYs = []
for samplePt in samplePts:
    rotX, rotY = _getRotateXY(samplePt[0],samplePt[1],matRotate)
    rotXs.append(rotX)
    rotYs.append(rotY)
#得到采样点的最大外接矩形
x1 = min(rotXs)
y1 = min(rotYs)
x2 = max(rotXs)
y2 = max(rotYs)
newBox = [x1,y1,x2,y2]

如果想做得更精确,可以加密采样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值