2014-01-30 35 views
1

我正在試驗OpenCV和Python的綁定。此代碼旨在用命令行參數值旋轉圖像。但是,它將保存爲輸入圖像的精確副本,並且不會進行任何旋轉。Python OpenCV - 文件旋轉,但顏色值被覆蓋

此代碼是adapted from this answer

import cv2 as cv 

def rotateImage(self, image, angle): 
    print "Rotating image to angle: %s" % (angle) 

    print type(image) #image is numpy.ndarray 
    print type(angle) #angle is float 

    center = tuple(np.array(image.shape[0:2])/2) 
    matrix = cv.getRotationMatrix2D(center, angle, 1.0) 
    rotate = cv.warpAffine(image, matrix, image.shape[0:2], flags=cv.INTER_LINEAR) 

    fileList = self.filename.split(".") 
    newFile = fileList[0] + "_rotate_%s." % (int(angle)) + fileList[1] 

    print "Saving to %s" % (newFile) 
    cv.imwrite(newFile, rotate) 

我的問題是旋轉後保存的圖像不是輸入一個是。

輸入圖像:enter image description here

輸出:enter image description here

鑑於這些輸入和輸出,如何可以改變圖像的尺寸,以允許30和45度旋轉?

回答

3

問題在於,旋轉之後,圖像超出了原始形狀的邊緣。解決方案是擴展原始圖像,然後旋轉。這樣,重要的部分不切斷:

import cv2 as cv 
import numpy as np 

def extend(image): 
    nrow, ncol, ncolor = image.shape 
    n = int((nrow**2 + ncol**2)**.5//2 + 1) 
    new = np.zeros((2*n, 2*n, ncolor)) 
    a = nrow//2 
    b = ncol//2 
    new[n-a:n-a+nrow, n-b:n-b+ncol, :] = image 
    return new 

def rotateImage(fname, angle): 
    print "Rotating image to angle: %s" % (angle) 

    image = cv.imread(fname, -1) 
    print type(image) #image is numpy.ndarray 
    print type(angle) #angle is float 
    image = extend(image) 

    center = tuple(np.array(image.shape[0:2])/2) 
    matrix = cv.getRotationMatrix2D(center, angle, 1.0) 
    rotate = cv.warpAffine(image, matrix, image.shape[0:2], flags=cv.INTER_LINEAR) 

    fileList = fname.split(".") 
    newFile = fileList[0] + "_rotate_%s." % (int(angle)) + fileList[1] 

    print "Saving to %s" % (newFile) 
    cv.imwrite(newFile, rotate) 

的延伸函數創建了一個較大的陣列(基於對角線上的原始圖像的尺寸),並把原始圖像中的中心。我使用np.zeros創建了較大的圖像,這意味着延伸返回的圖像具有較大的黑色邊框。該擴展需要在圖像旋轉之前完成。

您的圖像,經過45度旋轉,看起來像:

enter image description here