2009-03-29 35 views
7

Ayrıca bakınız: Why is my image rotation algorithm not working?Bir resmi nasıl döndürürüm?

Bu soru dile özgü değildir ve bir matematik problemidir. Ancak, matematikte fazla sıcak olmadığım için ihtiyacım olan şeyi açıklamak için bazı C++ kodları kullanacağım. İşte

görüntü oluşur açıklanmıştır: Burada

ImageMatrix image; 
image[0][0][0] = 1; 
image[0][1][0] = 2; 
image[0][2][0] = 1; 
image[1][0][0] = 0; 
image[1][1][0] = 0; 
image[1][2][0] = 0; 
image[2][0][0] = -1; 
image[2][1][0] = -2; 
image[2][2][0] = -1; 

Ben oluşturmaya çalışıyorum işlev için prototip: Sadece ilk iki endeks döndürmek istediğiniz

ImageMatrix rotateImage(ImageMatrix image, double angle); 

(satır ve sütunlar) değil, kanal.

+0

döndür? isteğe bağlı bir açı veya 90 derece birden fazla? – shoosh

+0

Shoosh: Prototipin önerdiği gibi (çift açılı) bu herhangi bir değerin çifte türünü kullanıyor olmalıdır. –

cevap

26

Bunu çözmenin genel yolu, geriye doğru yapmaktır. Giriş görüntüsündeki her pikselin çıktı görüntüsünde nerede bittiğini hesaplamak yerine, çıktı görüntüsündeki her pikselin giriş görüntüsünde nerede olduğunu hesaplarsınız (değerini diğer yönde olarak döndürerek). çıktı görüntüdeki tüm pikseller bir değere sahip olacaktır emin olun.

output = new Image(input.size()) 

for each pixel in input: 
{ 
    p2 = rotate(pixel, -angle); 
    value = interpolate(input, p2) 
    output(pixel) = value 
} 

interpolasyon yapmak için farklı yollar vardır. bence dönme formülüne için, https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions

kontrol etmelidir Ama sadece burada, güzel olmak (nokta (x, y) açı derece/radyanların dönüşü):

newX = cos(angle)*x - sin(angle)*y 
newY = sin(angle)*x + cos(angle)*y 
+0

Teşekkürler kigurai. Bunu uygulamaya çalıştım ama çok şansım olmadı, belki bir göz atabilirsin? http://stackoverflow.com/questions/697520/why-is-my-image-rotation-algorithm-not-working –

2

Döndürme matrislerinden ayrı olarak, görüntü bilgilerini takma yoluyla kaybetmeyen başka bir çözüm var. 2B görüntü rotasyonunu, görüntü kalitesini koruyan skews and scalings'a ayırabilirsiniz. Bu Sağladığınız örneği gibi görünüyor

Here's a simpler explanation

+0

İlginç, ancak "Nyquist frekansı" veya "spektrumu" gibi matematik terimlerinin çoğunu anlamıyorum. görüntü". Arka plan bilgisi için okuyacağım materyallere işaret edebilir misiniz? Kendi başıma keşfedebileceğim bir şey mi yoksa gerçek bir matematik eğitimine mi ihtiyacım var? (Geçen sene matematik lisesi öğrenciyim.) –

+0

@Iraimbilanja: Sinyal işleme teorisi ikinci veya üçüncü sene EE maddesidir. İntegral kalkülüsün nasıl yapıldığını bilmek ilk önce yardımcı olur. –

+0

Her zaman wikipedia vardır: http://en.wikipedia.org/wiki/Nyquist_frequency Bir görüntünün spektrogramı olarak frekansı düşünün: bir ses oyuncunun grafik analizcisinin çıktısına eşdeğerdir, sadece 2B'de. Görüntüde en çok hangi frekansın görünür olduğunu ve hangi yönde olduğunu gösterir. – heeen

0

bazı kenar saptama çekirdektir. Yani eğer istediğiniz şey farklı açıların kenarlarını tespit ederseniz, bazı sürekli fonksiyonu (sizin durumunuzda x1 ile x1 ile çarpılan bir parametreli gaussian olabilir) seçip kigurai tarafından sağlanan formüllere göre döndürün. Sonuç olarak, diskrete çekirdeğini daha verimli ve taklit olmadan üretebileceksiniz.

2

bir görüntüyü döndürmek için, 3 puan oluşturun:

A----B 
| 
| 
C 

ve A. etrafında Bunu yeni döndürülmüş bir görüntü elde etmek için bu döndürmek:

  • 2D A etrafında ABC döndürmek, Yani bu, A'dan B'ye döndürülen bir durumda, tek bir euler rotasyonu
  • traversidir. Her piksel için, orijinal görüntüdeki yatay çizgi üzerinde soldan sağa doğru da geçiş yaparsınız. Bu yüzden, görüntü 100 genişliğinde, 50 yüksekliğinde bir görüntüyse 100 adımda A'dan B'ye ve 50 adımda A'dan C'ye geçecek, ABC tarafından döndürülen alanda 50 piksellik 100 piksel çizeceksiniz. .

Bu karmaşık görünebilir, ancak değil. rotoZoomer by me

çizim, bir kauçuk benzeri bir etki elde etmek için kaynak işaretçiler biraz değiştirmek, ama o devre dışı bırakırsanız, kod görüntüyü döndürür görürsünüz: Bir süre önce yazdığı bu C# kodu bakınız sorunsuz. Tabii ki, bazı açılarda biraz bozuk görünen bir görüntü elde edersiniz. Kaynak kodu neler olup bittiğine dair yorumlar içerir, böylece arkasındaki matematik/mantığı kolayca yakalayabilmeniz gerekir.

daha iyi, ben de bir zamanlar, 14 yıl kadar önce bir java versiyonunu yaptık Eğer Java gibi

;) - ne kadar tarafından> http://www.xs4all.nl/~perseus/zoom/zoom.java

İlgili konular