-
1. Data: 2010-04-19 12:25:31
Temat: Resize obrazka w roznych skalach
Od: Maciej Pilichowski <P...@g...com>
Hej,
Pytanie lamerskie, ale mam zacmienie i nie moge ruszyc z miejsca.
UPRASZCZAJAC:
Mam tablice 2d (obrazek) i mam ja przeskalowac do drugiej tablicy 2d
o innych wymariach. Zeby nie macic, skala zmiany w obu wspolrzednych
jest ta sama.
Jesli testuje procedure, to np. robie skalowanie x2 a nastepnie x0.5
i powinienem dostac optycznie mniej wiecej to samo.
A sama procedura jest prosta -- dla X i Y obliczam wspolczynnik
"skali" -- tj. wielkosc ostatniej wsp. X (lub Y) dla tablicy
wyjsciowej w stosunku do ostatniej wsp. z tablicy oryginalnej.
Pozniej iteruje po wszystkich punktach z tablicy wyjsciowej, licze
jakie sa odpowiedniki wsp. w tablicy oryginalnej i przepisuje wartosci
(+wygladzanie). Mniejsza o artefakty.
Ok, jak do tej pory dziala.
Ale teraz chcialbym nie miec skali tylko liniowej, ale potegowa (no
i odwrotnosc -- logarytmiczna). W ogolnosci skalowanie jest jakas tam
funkcja.
Obliczenie skali i wsp. oryginalnych (dla X) wyglada tak:
// input, prefix i -- wejscie
// output, prefix o -- wyjscie
var ratiox = ((double)input.Width() - 1) / func(output.Width() - 1);
var ix = func(ox) * ratiox;
Jesli chce skale potegowa, to np. wrzucam jako func
i => Math.Pow(2, i) - 1 // 2^i-1
a jesli logarytmiczna
i => Math.Log(i+1,2) // log2 (i+1)
Dziala, kompiluje sie, obrazki sie generuja.
PROBLEM: procedura skalowania logarytmicznego nie jest "odwrotnoscia"
skalowania potegowego (i vice versa). Nie chodzi mi tu o detale takie
jak artefakty 1 pixela. Znieksztalcenia dotycza obrazu jako calosci.
Np. obecnie jesli dam skalowanie potegowe, a pozniej logarytmiczne, to
musze wrzucic jeszcze raz skalowanie potegowe, aby dostac zrodlowy
obrazek.
Jesli zaczne od skalowania logarytmicznego, to musze kilkanascie razy
aplikowac skalowanie potegowe, aby dostac zrodlo.
Rzecz jasna cos musialem przeoczyc, tylko co? :-) Z gory dzieki za
naprowadzenie.
milego dnia, hej
-
2. Data: 2010-04-20 20:58:35
Temat: Re: Resize obrazka w roznych skalach
Od: Michoo <m...@v...pl>
Maciej Pilichowski pisze:
> Ale teraz chcialbym nie miec skali tylko liniowej, ale potegowa (no
> i odwrotnosc -- logarytmiczna). W ogolnosci skalowanie jest jakas tam
> funkcja.
>
> Obliczenie skali i wsp. oryginalnych (dla X) wyglada tak:
>
> // input, prefix i -- wejscie
> // output, prefix o -- wyjscie
>
> var ratiox = ((double)input.Width() - 1) / func(output.Width() - 1);
>
> var ix = func(ox) * ratiox;
Przetłumacz ten kod na ludzki, ok? - bo raczej nie obliczasz WEJściowej
wartości współrzędnej x w oparciu o wartość WYJściową?
$cat /dev/glassorb
Zamieszałeś kompletnie:
Jeżeli policzysz logarytm z wymiaru docelowego wymiaru obrazu a potem
przeskalujesz (PRZEMNOŻYSZ/PODZIELISZ) w oparciu o niego to będziesz
skalował w oparciu o STAŁĄ skalę i żeby wrócić do początkowego wymiaru
musisz wykonać operację odwrotną do tej użytej wcześniej, czyli
PODZIELIĆ/POMNOŻYĆ przez tą samą wartość.
Skala logarytmiczna oznacza, że SKALA się zmienia wraz z odległością od
przyjętego początku układu współrzędnych.
Np. w skali logarytmicznej:
mamy 2 odcinki: (10,100) i (10,1000)
po przeskalowaniu mamy odcinki (log(10),log(100)) i (log(10),log(1000)),
czyli (1,2) i (1,3)
aby wrócić do oryginalnych stosujemy funkcję odwrotną:
(10^1,10^2) i (10^1,10^3) -> (10,100) i (10,1000)
$
--
Pozdrawiam
Michoo
-
3. Data: 2010-04-21 05:52:14
Temat: Re: Resize obrazka w roznych skalach
Od: Maciej Pilichowski <P...@g...com>
On Tue, 20 Apr 2010 22:58:35 +0200, Michoo <m...@v...pl> wrote:
Dzieki za odpowiedz.
>> var ratiox = ((double)input.Width() - 1) / func(output.Width() - 1);
>>
>> var ix = func(ox) * ratiox;
>Przetłumacz ten kod na ludzki, ok? - bo raczej nie obliczasz WEJściowej
>wartości współrzędnej x w oparciu o wartość WYJściową?
Wlasnie tak robie. Dlatego, ze iteruje po pixelach w tablicy
wyjsciowej i na podstawie tychze wyliczam obszar jaki musze odczytac z
tablicy wejsciowej.
>Jeżeli policzysz logarytm z wymiaru docelowego wymiaru obrazu a potem
>przeskalujesz (PRZEMNOŻYSZ/PODZIELISZ) w oparciu o niego to będziesz
>skalował w oparciu o STAŁĄ skalę i żeby wrócić do początkowego wymiaru
>musisz wykonać operację odwrotną do tej użytej wcześniej, czyli
>PODZIELIĆ/POMNOŻYĆ przez tą samą wartość.
Nie chcialem tego robic do tej pory, bo bledy numeryczne beda
powodowaly degradacje obrazka.
Myslalem jesli juz o jakims sprytnym sposobie, ktory w jednym kroku
bedzie operowal na zlozeniu tych funkcji (tj. przeskalowywaniu
liniowym, jak wyzej opisujesz, i skalowaniu wg funkcji wybranej przez
usera).
milego dnia, hej