2012-02-08 17 views
7

मैं कुछ कोड प्राप्त करने की कोशिश कर रहा हूं जो एक छवि पर एक परिप्रेक्ष्य परिवर्तन (इस मामले में एक 3 डी रोटेशन) करेगा।छवि पर 3 डी रोटेशन

import os.path 
import numpy as np 
import cv 

def rotation(angle, axis): 
    return np.eye(3) + np.sin(angle) * skew(axis) \ 
       + (1 - np.cos(angle)) * skew(axis).dot(skew(axis)) 

def skew(vec): 
    return np.array([[0, -vec[2], vec[1]], 
        [vec[2], 0, -vec[0]], 
        [-vec[1], vec[0], 0]]) 

def rotate_image(imgname_in, angle, axis, imgname_out=None): 
    if imgname_out is None: 
     base, ext = os.path.splitext(imgname_in) 
     imgname_out = base + '-out' + ext 
    img_in = cv.LoadImage(imgname_in) 
    img_size = cv.GetSize(img_in) 
    img_out = cv.CreateImage(img_size, img_in.depth, img_in.nChannels) 
    transform = rotation(angle, axis) 
    cv.WarpPerspective(img_in, img_out, cv.fromarray(transform)) 
    cv.SaveImage(imgname_out, img_out) 

जब मैं z- अक्ष के बारे में बारी बारी से, सब कुछ उम्मीद के रूप में काम करता है, लेकिन चारों ओर एक्स या y अक्ष घूर्णन पूरी तरह से बंद है। इससे पहले कि मुझे उचित परिणाम दिखाई देने से पहले मुझे पीआई/200 के रूप में छोटे कोणों से घूमने की ज़रूरत है। कोई अंदाजा क्या गलत हो सकता है?

उत्तर

21

सबसे पहले, रोटेशन मैट्रिक्स का निर्माण प्रपत्र

[cos(theta) -sin(theta) 0] 
R = [sin(theta) cos(theta) 0] 
    [0   0   1] 

इस समन्वय को बदलने को लागू करने की आप मूल के चारों ओर एक रोटेशन देता है।

यदि, इसके बजाय, आप छवि केंद्र के चारों ओर घूमना चाहते हैं, तो आपको सबसे पहले छवि केंद्र को मूल में स्थानांतरित करना होगा, फिर रोटेशन लागू करें, और उसके बाद सब कुछ वापस ले जाएं। आप एक अनुवाद मैट्रिक्स का उपयोग कर ऐसा कर सकते हैं:

[1 0 -image_width/2] 
T = [0 1 -image_height/2] 
    [0 0 1] 

अनुवाद, रोटेशन के लिए परिवर्तन मैट्रिक्स, और उलटा अनुवाद तो हो जाता है:

H = inv(T) * R * T 

मैं कैसे संबद्ध करने के बारे में थोड़ा सोचने के लिए होगा 3 डी परिवर्तन के लिए skew मैट्रिक्स। मुझे उम्मीद है कि सबसे आसान मार्ग 4 डी रूपांतरण मैट्रिक्स स्थापित करना है, और उसके बाद 2 डी समरूप समन्वय को प्रोजेक्ट करना है। लेकिन अब के लिए, तिरछा मैट्रिक्स के सामान्य रूप:

[x_scale 0  0] 
S = [0  y_scale 0] 
    [x_skew y_skew 1] 

x_skew और y_skew मूल्यों आम तौर पर छोटे (1e-3 या उससे कम) कर रहे हैं।

from skimage import data, transform 
import numpy as np 
import matplotlib.pyplot as plt 

img = data.camera() 

theta = np.deg2rad(10) 
tx = 0 
ty = 0 

S, C = np.sin(theta), np.cos(theta) 

# Rotation matrix, angle theta, translation tx, ty 
H = np.array([[C, -S, tx], 
       [S, C, ty], 
       [0, 0, 1]]) 

# Translation matrix to shift the image center to the origin 
r, c = img.shape 
T = np.array([[1, 0, -c/2.], 
       [0, 1, -r/2.], 
       [0, 0, 1]]) 

# Skew, for perspective 
S = np.array([[1, 0, 0], 
       [0, 1.3, 0], 
       [0, 1e-3, 1]]) 

img_rot = transform.homography(img, H) 
img_rot_center_skew = transform.homography(img, S.dot(np.linalg.inv(T).dot(H).dot(T))) 

f, (ax0, ax1, ax2) = plt.subplots(1, 3) 
ax0.imshow(img, cmap=plt.cm.gray, interpolation='nearest') 
ax1.imshow(img_rot, cmap=plt.cm.gray, interpolation='nearest') 
ax2.imshow(img_rot_center_skew, cmap=plt.cm.gray, interpolation='nearest') 
plt.show() 

और उत्पादन:

Rotations of cameraman around origin and center+skew

कोड यह

0

मुझे आपके रोटेशन मैट्रिक्स को बनाने का तरीका नहीं मिलता है। यह मेरे लिए बल्कि जटिल लगता है। आमतौर पर, यह शून्य मैट्रिक्स का निर्माण करके बनाया जाएगा, 1 अनइडेड अक्षों पर, और सामान्य sin, cos, -cos, sin दो उपयोग किए गए आयामों में डाला जाएगा। फिर इन सभी को एक साथ गुणा करें।

आपको np.eye(3) + np.sin(angle) * skew(axis) + (1 - np.cos(angle)) * skew(axis).dot(skew(axis)) कहां से मिला?

बुनियादी बिल्डिंग ब्लॉक से प्रोजेक्शन मैट्रिक्स बनाने का प्रयास करें। एक रोटेशन मैट्रिक्स का निर्माण काफी आसान है, और "rotationmatrix dot skewmatrix" काम करना चाहिए।

हालांकि आपको रोटेशन सेंटर पर ध्यान देना पड़ सकता है। आपकी छवि शायद ज़ेड अक्ष पर 1 की वर्चुअल स्थिति पर रखी गई है, इसलिए एक्स या वाई पर घूर्णन करके, यह थोड़ा सा चलता है। तो आपको एक अनुवाद का उपयोग करने की आवश्यकता होगी ताकि ज़ेड 0 हो जाए, फिर घुमाएं, फिर वापस अनुवाद करें। (Affine निर्देशांक में अनुवाद matrixes बहुत सरल भी हैं विकिपीडिया देखें:। https://en.wikipedia.org/wiki/Transformation_matrix)

संबंधित मुद्दे