--.--
--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

04.16
Mon
お久しぶりです。

とうとう大学生になっちゃったmoratoriです。

大学生といったら、自由な時間がたくさんあって好きなことしまくれるのかなー

なんて思ってたら入学そうそうたくさんのタスクが山積みでちょっと挫けそうですw←

でもまぁー友達とかみんなが親切にしてくれるので総じて楽しい日々を送っています。

と、このへんにしといて、今日は画像を回転させる方法について書きます。

しかしこの方法はあっているのかも分からないし、とにかく効率が悪いです。

数学の内容は高校生ぐらいです。

でもまぁいちおう雑記的なあれで書いてみます。

まず、座標の移動について。

こんな図を用意してみました。

rotate_pos.png



はい。わかりずらいですねww

ちなみに1とか2とか3とかの数値は全く気にしないで下さい。関係ないので。

Rは半径で、θとβはそれぞれ図示された角度を表してます。

紫の線は直角三角形を作るための補助的な線です。

んでまず何をしたいかと言いますと、

(x,y)座標を反時計まわりにβだけ回転させた(x',y')が知りたい

ということで試行錯誤してみます。

まずx ,yをsinとかcosで表してみると

x = Rcos(θ)
y = Rsin(θ)

となります。①

で同様にx' , y'はそれぞれ

x' = Rcos(θ+β)
y' = Rsin(θ+β)

これを加法定理でばらすと、

x' = Rcos(θ)cos(β) - Rsin(θ)sin(β)
y' = Rsin(θ)cos(β) + Rcos(θ)sin(β)

となりますが、①より

x' = xcos(β) - ysin(β)
y' = ycos(β) + xsin(β)

となります。

これで任意の(x,y)の点からβ度回転したときの座標(x',y')が求まりました。

因みにこの形は行列で表せるので、表してみると

rotatemat.png

となります。


じゃあ実際に使ってみます。

ということで以前書いた拙作行列演算モジュールを折角なので用いて

画像をぐるっとまわしてみます。

例のMatrixモジュールは以下です

#!/usr/bin/env python
#coding:utf-8

import math

class Matrix:

    #if flag is True , make elementary matrix in the [instance].e
    def __init__ ( self , matrixFactor , flag = True ):
        if ( isinstance( matrixFactor , str ) ): matrixFactor = self.transForm( matrixFactor )
        self.gyou = len( matrixFactor )
        self.retu = len( matrixFactor[ 0 ] )
        self.e = None
        for eachLine in matrixFactor:
            if ( self.retu != len( eachLine ) ): raise IOError
        self.matrix = matrixFactor
        if (( self.retu == self.gyou ) and ( flag == True )) :
            elementary_factor = []
            each_factor = []
            counter = 0
            for dummy in xrange( self.gyou ):
                for dummy2 in xrange( self.retu ):
                    if ( dummy2 == counter ) :
                        each_factor.append( 1 )
                    else:
                        each_factor.append( 0 )
                counter += 1
                elementary_factor.append( each_factor )
                each_factor = []
            self.e = Matrix( elementary_factor , False )


    def transForm( self , strdata ):
        result = []
        proc = []
        for eachRow in strdata.split( ";" ):
            for eachFactor in eachRow.split( "," ):
                proc.append( float( eachFactor ) )
            result.append( proc )
            proc = []
        return result

    #show format
    def printFormat( self ):
        print "%s Row %s Column  matrix" %( self.gyou , self.retu )


    #show matrix gui
    def printMatrix( self ):
        for each in self.matrix:
            for number in each:
                print str( number ) + "\t",
            print ""



    def getFactor( self , gyou , retu ):
        return self.matrix[ gyou - 1 ][ retu - 1 ]



    def getRow( self , row ):
        return self.matrix[ row - 1 ]


    def getColumn( self , column ):
        result = []
        for each in self.matrix : result.append( each[ column - 1 ] )
        return result


    def powMatrix( self , number):
        ins = Matrix( self.matrix )
        result = ins
        for dummy in xrange( number - 1 ):
            result = result.mult( ins )
        return result


    def timesMatrix( self , number ):
        result = []
        proc = []
        for each in self.matrix:
            for n in each:
                proc.append( n * number )
            result.append( proc )
            proc = []
        return Matrix(result)


    def multMatrix( self , matrix ):
        if ( self.retu != matrix.gyou ): raise IOError
        result =[]
        proc = []
        tmp = 0
        for each in self.matrix:
            for counter2 in xrange( matrix.retu ):
                r = matrix.getColumn( counter2 + 1 )
                for counter in xrange( self.retu ):
                    tmp += each[ counter ] * r[ counter ]
                proc.append( tmp )
                tmp = 0
            result.append( proc )
            proc = []
        return Matrix( result )

    #addMatrix
    def addMatrix( self , matrix  , flag = True):
        if ( ( self.gyou != matrix.gyou ) or ( self.retu != matrix.retu ) ): raise IOError
        new_matrix = []
        counter = 0
        for each in self.matrix:
            new_matrix.append( self.addList( each , matrix.matrix[ counter ] , flag ) )
            counter += 1
        return Matrix( new_matrix )


    #SubstractionMatrix
    def subsMatrix( self , matrix ):
        return self.addMatrix( matrix , flag = False )


    def compare( self , matrix ):
        if ( ( self.gyou != matrix.gyou ) or ( self.retu != matrix.retu ) ): return False
        counter = 0
        for each in self.matrix:
            target = matrix.matrix[ counter ]
            counter2 = 0
            for each2 in each:
                if ( each2 != target[ counter2 ] ) : return False
                counter2 += 1
            counter += 1
        return True

    def getInverseMatrix2( self ):
        if ( ( self.gyou != 2) or ( self.retu != 2 ) ): raise IOError
        d = self.getFactor(1,1) * self.getFactor(2,2) - self.getFactor(1,2) * self.getFactor(2,1)
        if ( d == 0): raise IOError
        inv = [ [self.getFactor(2,2) , -self.getFactor(1,2)] , [ -self.getFactor(2,1), self.getFactor(1,1)] ]
        return Matrix(inv).timesMatrix( 1.0/d )

    def getRotatedPosition(self , angle):
        if ((self.gyou != 2) or (self.retu != 1)) : raise IOError
        rotatemat = Matrix([[math.cos(angle) , -math.sin(angle)] , [math.sin(angle) , math.cos(angle)]])
        return rotatemat.multMatrix(self)
		
		
    #this method is private. DON'T CALL WITH INSTANCE
    def addList( self , list1 , list2 , flag):
        result = []
        counter = 0
        for each in list1:
            if ( flag ):
                result.append( each + list2[ counter ] )
            else:
                result.append( each - list2[ counter ] )
            counter += 1
        return result

		
if (__name__ == "__main__"): print "this is a matrix module."




因みにこの回転行列を使うために

getRotatedPosition()というメソッドを追加しました。

んで、上記のモジュールを使った簡単なサンプルが以下。

以下のソースコードは相当適当に書かれてるので注意!ww

多分大きい画像でやらなけりゃ大丈夫なはず

#!/usr/bin/env python
#coding:utf-8


import pygame
import math
import os
import Matrix as mat

			
filename = os.path.join( os.getcwd() , "src.jpg")

surface = pygame.image.load(filename)
size_x , size_y = surface.get_size()

picinfo = {}

newsur = pygame.Surface((700 , 700))

for x in xrange(size_x):
	for y in xrange(size_y):
		rm = mat.Matrix([[x],[y]]).getRotatedPosition(math.radians(95))
		newsur.set_at((int(rm.getRow(1)[0])+500 , int(rm.getRow(2)[0])+200) , surface.get_at((x,y)))
		
pygame.image.save(newsur , "dst.jpg")






なお、画像処理を行うためにpygameを使っているので動かすにはpygameをインストールしなきゃいけないですw(ぇ

では。
スポンサーサイト

comment 0 trackback 0
トラックバックURL
http://telracsmoratori.blog.fc2.com/tb.php/109-b66bf67a
トラックバック
コメント
管理者にだけ表示を許可する
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。