[C++]Rotacja obrazka o dowolny kąt

0

Napisałem sobie rotację wczytanego obrazka, użyłem do tego celu mnozenia macierzy punktu i macierzy rotacji. Obrazek rzeczywiscie "obraca sie" o zadany kat, ale sa na nim czarne kropki (tlo pod obrazkiem mam czarne) - wyglada to tak, jakby te byly "dziury" w obrazku, po prostu tak, jakby jakieś punkty się nie zrotowały XD. Nie mogę zapodac kodu, ale może ktoś ma jakiś pomysł, co robię źle? Operuję na tablicach typu double, jednak przy intach problem jest taki sam.

0

Spora część u mnie opiera się na tym skrawku kodu:

[code]for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
x1 = x0 cos(theta) - y0 sin(theta);
y1 = x0 sin(theta) + y0 cos(theta);
// check boundaries, use different width and height if you want
if (x1 >= 0 && x1 < width && y1 >= 0 && y1 < height) {
// if you are using a linear array then linear_idx = y1 * width + x1
output[x][y] = input[x1][y1]; // or maybe output[x][y] = bilinear_interpolation(input, x1, y1);
}
else {
output[x][y] = 0; // or output[x][y] = boundary_constant;
}
}
}

Oczywiście ja nie obliczam x1,y1, tylko mam macierz, gdzie macierz[0][0] = x1, a macierz[0][1] = y1
Macierze mam dobrze wymnozone, z tym nie mialem problemu - to na pewno nie jest zle

0
heh napisał(a)

Obrazek rzeczywiscie "obraca sie" o zadany kat, ale sa na nim czarne kropki

Liczysz w złą stronę. Zamiast jechać po wszystkich pikselach obrazka źródłowego i obliczać docelową pozycję piksela, rób odwrotnie: jedź po pikselach obrazka docelowego i obliczaj jaką pozycję miał ten piksel przed rotacją (czyli musisz obracać o kąt w drugą stronę).

0

Hm, zmienilem, i tak jest tak, jak bylo poprzednio. Teraz glowna czesc mojego kodu, to cos takiego:

We - obrazek wejsciowy, Wy - obrazek wyjsciowy, po rotacji

for(int y=0; y<we.height(); y++)
    {
     for(int x=0; x<we.width(); x++)
     {
      //Wypelniamy macierz punktu p wspolrzednymi aktualnych punktow obrazka x,y
      //Mnozymy macierz punktu p przez macierz rotacji - zwykle mnozenie macierzy
      //Dostajemy macierz punktu p' gdzie nowe obliczone wspolrzedne to x',y'
      //Warunek - aby nie rysowac pikseli "poza" obszarem
      if(x1 >= 0 && x1 < we.width() && y1 >= 0 && y1 < we.height())
         wy.setPixel(QPoint(x1,y1),we.pixel(QPoint(x,y)));
     }
    }
0
for(int y=0; y<we.height(); y++)
{
for(int x=0; x<we.width(); x++)

Jeżeli we


 oznacza obrazek wejściowy, to nie zmieniłeś. Te fory mają być po <u>wyjściu</u>.
0

Faktycznie, masz rację :) Teraz mam takie coś - i obraca obrazek - inna sprawa, ze jest on troche kanciasty, ale to chyba z tym nic juz nie zrobię:

for(int y=0; y<wy.height(); y++)
     {
      for(int x=0; x<wy.width(); x++)
      {
       //Wypelniamy macierz punktu p wspolrzednymi aktualnych punktow obrazka x,y
      //Mnozymy macierz punktu p przez macierz rotacji - zwykle mnozenie macierzy
      //Dostajemy macierz punktu p' gdzie nowe obliczone wspolrzedne to x',y'
      //Warunek - aby nie rysowac pikseli "poza" obszarem
       if(x1 >= 0 && x1 < we.width() && y1 >= 0 && y1 < we.height())
          wy.setPixel(QPoint(x,y),we.pixel(QPoint(x1,y1)));
      }
     }

a mógłbyś mi jeszcze trochę wyjaśnic, dlaczego mój sposób był błędny? Ja jeszcze sobie przeanalizuję, ale mile widziane byłby jakieś dodatowe objaśnienia ;) Pozdro

0

Prawdopodobnie jest to kwestia zaokrągleń - sam widzisz, że obrócony rysunek jest "kanciasty", czyli odwzorowanie nie jest 1:1. Jeżeli liczysz "do przodu" to możliwa jest sytuacja, że po przeliczeniu pixel 123 trafia na 320, ale 124 na 322 - pewne punkty zostaną więc pominięte (stąd czarne kropki). Licząc "od tyłu" masz pewność, że każdy punkt został przeliczony nawet, jeżeli odwzorowanie wyszło 320<-123, 321<-123, 322<-124 (chodzi oczywiście o ideę)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0