CNN Data Augmentation(数据增强)-旋转

来源:互联网 发布:陀螺稳定原理 知乎 编辑:程序博客网 时间:2024/05/18 22:15

1、原始状态

最初的图像是这个样子的
这里写图片描述
.xml文件张下面这个样子

<annotation>    <object>        <name>face</name>        <difficult>0</difficult>        <bndbox>            <xmin>315.307918</xmin>            <ymin>240.234604</ymin>            <xmax>693.677419</xmax>            <ymax>699.683284</ymax>        </bndbox>    </object></annotation>

2、旋转图像并修改对应的xml文件

import cv2import mathimport numpy as npimport os# pdb仅仅用于调试,不用管它import pdb#旋转图像的函数def rotate_image(src, angle, scale=1.):    w = src.shape[1]    h = src.shape[0]    # 角度变弧度    rangle = np.deg2rad(angle)  # angle in radians    # now calculate new image width and height    nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale    nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale    # ask OpenCV for the rotation matrix    rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)    # calculate the move from the old center to the new center combined    # with the rotation    rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))    # the move only affects the translation, so update the translation    # part of the transform    rot_mat[0,2] += rot_move[0]    rot_mat[1,2] += rot_move[1]    # 仿射变换    return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)//对应修改xml文件def rotate_xml(src, xmin, ymin, xmax, ymax, angle, scale=1.):    w = src.shape[1]    h = src.shape[0]    rangle = np.deg2rad(angle)  # angle in radians    # now calculate new image width and height    # 获取旋转后图像的长和宽    nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale    nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale    # ask OpenCV for the rotation matrix    rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)    # calculate the move from the old center to the new center combined    # with the rotation    rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))    # the move only affects the translation, so update the translation    # part of the transform    rot_mat[0,2] += rot_move[0]    rot_mat[1,2] += rot_move[1]    # rot_mat是最终的旋转矩阵    # 获取原始矩形的四个中点,然后将这四个点转换到旋转后的坐标系下    point1 = np.dot(rot_mat, np.array([(xmin+xmax)/2, ymin, 1]))    point2 = np.dot(rot_mat, np.array([xmax, (ymin+ymax)/2, 1]))    point3 = np.dot(rot_mat, np.array([(xmin+xmax)/2, ymax, 1]))    point4 = np.dot(rot_mat, np.array([xmin, (ymin+ymax)/2, 1]))    # 合并np.array    concat = np.vstack((point1, point2, point3, point4))    # 改变array类型    concat = concat.astype(np.int32)    print concat    rx, ry, rw, rh = cv2.boundingRect(concat)    return rx, ry, rw, rh# 使图像旋转60,90,120,150,210,240,300度for angle in (60, 90, 120, 150, 210, 240, 300):    # 指向图片所在的文件夹    for i in os.listdir("/home/username/image"):        # 分离文件名与后缀        a, b = os.path.splitext(i)        # 如果后缀名是“.jpg”就旋转图像        if b == ".jpg":            img_path = os.path.join("/home/username/image", i)            img = cv2.imread(img_path)            rotated_img = rotate_image(img, angle)            # 写入图像            cv2.imwrite("/home/yourname/rotate/" + a + "_" + str(angle) +"d.jpg", rotated_img)            print "log: [%sd] %s is processed." % (angle, i)        else:            xml_path = os.path.join("/home/username/xml", i)            img_path = "/home/guoyana/varied_pose/" + a + ".jpg"            src = cv2.imread(img_path)            tree = ET.parse(xml_path)            root = tree.getroot()            for box in root.iter('bndbox'):                xmin = float(box.find('xmin').text)                ymin = float(box.find('ymin').text)                xmax = float(box.find('xmax').text)                ymax = float(box.find('ymax').text)                x, y, w, h = rotate_xml(src, xmin, ymin, xmax, ymax, angle)                # 改变xml中的人脸坐标值                box.find('xmin').text = str(x)                box.find('ymin').text = str(y)                box.find('ymax').text = str(x+w)                box.find('ymax').text = str(y+h)                box.set('updated', 'yes')            # 写入新的xml            tree.write("/home/username/xml/" + a + "_" + str(angle) +".xml")            print "[%s] %s is processed." % (angle, i)

3、结果

我们来看下旋转后的图像和修改后的.xml文件
太多了,这里只放两张~
这里写图片描述 这里写图片描述
修改后的xml文件如下

<annotation>    <object>        <name>face</name>        <difficult>0</difficult>        <bndbox updated="yes">            <xmin>460</xmin>            <ymin>521</ymin>            <xmax>693.677419</xmax>            <ymax>849</ymax>        </bndbox>    </object></annotation>

效果怎么样呢?我们来写个小程序看一下

import cv2import osimport xml.etree.ElementTree as ETimport pdbfor img in os.listdir("/home/mi/rotate/"):    a, b = os.path.splitext(img)    if b == ".jpg":        img = cv2.imread("/home/yourname/rotate/" + img)        tree = ET.parse("/home/yourname/xml/" + a + ".xml")        root = tree.getroot()        for box in root.iter('bndbox'):            x1 = float(box.find('xmin').text)            y1 = float(box.find('ymin').text)            x2 = float(box.find('xmax').text)            y2 = float(box.find('ymax').text)            x1 = int(x1)            y1 = int(y1)            x2 = int(x2)            y2 = int(y2)            cv2.rectangle(img, (x1, y1), (x2, y2), [0,255,0], 2)            cv2.imshow("test", img)        if 1 == cv2.waitKey(0):            pass

这里写图片描述 这里写图片描述


(end)

0 0
原创粉丝点击