opencv图像旋转矩阵

在Python opencv中图像旋转矩阵可以用来旋转源图片到目标图片、旋转源坐标点到目标坐标点。根据图像旋转矩阵还可以逆向根据目标坐标点得到原始点的位置。

将常用的旋转函数汇总一下

1. 根据中心坐标点旋转图片

# 输入为三通道图片以及需要顺时针旋转的角度
def rotate_image(image, angle):
    (h, w) = image.shape[:2]
    (cX, cY) = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D((cX, cY), angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))
    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)),M

下面是另一个类似的

def func1(image,degree):
    height, width = image.shape[:2]
    heightNew = int(width * fabs(sin(radians(degree))) + height * fabs(cos(radians(degree))))
    widthNew = int(height * fabs(sin(radians(degree))) + width * fabs(cos(radians(degree))))
    matRotation = cv2.getRotationMatrix2D((width / 2, height / 2), -degree, 1)
    matRotation[0, 2] += (widthNew - width) / 2
    matRotation[1, 2] += (heightNew - height) / 2
    imgRotation = cv2.warpAffine(image, matRotation, (widthNew, heightNew), borderValue=(255, 255, 255))
    return imgRotation, matRotation

2. 坐标点进行旋转操作

def rotate_boxes(boxes,angle,h,w):
    (cX, cY) = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D((cX, cY), angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))
    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY
    points = np.array(boxes).reshape((4,2))
    ones = np.ones(shape=(4, 1))
    points_ones = np.concatenate((points, ones), axis=1)

    transformed_pts = M.dot(points_ones.T).T
    return transformed_pts 

3. 根据目标坐标点得到源坐标点

小角度可以采用这样的方式,但是这个代码存在一个问题,这是根据矩阵的乘法逆推到的,当h1=0或者 (h2 * h4 - h1 * h5)=0的时候,结果会有问题。

def transformPTs_inverse(pts, H):
    H_inverse = np.linalg.pinv(H)
    pts = np.array(pts)
    num = pts.shape[0]
    newpts = []
    h1, h2, h3, h4, h5, h6 = H[0][0], H[0][1], H[0][2], H[1][0], H[1][1], H[1][2]
    for i in range(num):
        x1, y1 = pts[i]
        y0 = (x1 * h4 - y1 * h1 - h3 * h4 + h1 * h6) / (h2 * h4 - h1 * h5)
        x0 = (x1 - h3 - h2*y0)/h1
        newpts.append([int(x0), int(y0)])
    repts = np.array([newpts[3], newpts[0], newpts[1], newpts[2]])
    return rept

第二种方法:


def transformPTs_inverse_homography(pts, H):
    H_inverse = np.linalg.pinv(H)
    pts = np.array(pts)
    num = pts.shape[0]
    newpts = []
    for i in range(num):
        newpt = np.dot(H_inverse, pts[i].tolist() + [1])
        newpt = newpt/newpt[-1] # Homogeneous
        newpts.append(newpt[:-1])
    newpts = np.array(newpts)
    return newpts

对于大角度比如90,180,270度角,可以采用一种比较笨的方法

# 这里的输入pts是长度为8的数组,分别为左上角、右上角、左下角、右下角的顺序。
def stupid_inverse(pts, angle, H):
    pts = np.array(pts).reshape((4, 2))
    num = pts.shape[0]
    h1, h2, h3, h4, h5, h6 = H[0][0], H[0][1], H[0][2], H[1][0], H[1][1], H[1][2]
    newpts = []
    if angle == 90:
        for i in range(num):
            x1, y1 = pts[i]
            x0 = h6 - y1
            y0 = x1 - h3
            newpts.append([int(x0), int(y0)])
        repts = np.array([newpts[2], newpts[0], newpts[3], newpts[1]])
    elif angle == 180:
        for i in range(num):
            x1, y1 = pts[i]
            x0 = h3 - x1
            y0 = h6 - y1
            newpts.append([int(x0), int(y0)])
        repts = np.array([newpts[3], newpts[2], newpts[1], newpts[0]])
    elif angle == 270:
        for i in range(num):
            x1, y1 = pts[i]
            x0 = y1
            y0 = h3 - x1
            newpts.append([int(x0), int(y0)])
        repts = np.array([newpts[1], newpts[3], newpts[0], newpts[2]])

    else:
        repts = pts
    repts = repts.reshape(-1)
    return repts

自己常用的函数,怕忘了,所以记录一下。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容