<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TextureMind &#187; Tutorials</title>
	<atom:link href="http://www.texturemind.com/postcategory/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.texturemind.com</link>
	<description>...the home page of Gianpaolo Ingegneri</description>
	<lastBuildDate>Sat, 17 Jul 2010 08:51:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to create photorealistic textures (Ita)</title>
		<link>http://www.texturemind.com/post35/</link>
		<comments>http://www.texturemind.com/post35/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 14:07:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.texturemind.com/?p=35</guid>
		<description><![CDATA[Le texture fotorealistiche vengono usate per migliorare l&#8217;impatto visivo di molte simulazioni tridimensionali nei motori grafici moderni. Le texture non sono altro che immagini digitali con la caratteristica peculiare di fornire all&#8217;osservatore un&#8217;impressione di continuità se accostate ripetutamente l&#8217;una accanto all&#8217;altra in orizzontale e in verticale.

Lo scopo di questo tutorial è quello di capire come è possibile creare immagini del genere, [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">Le texture fotorealistiche vengono usate per migliorare l&#8217;impatto visivo di molte simulazioni tridimensionali nei motori grafici moderni. Le texture non sono altro che immagini digitali con la caratteristica peculiare di fornire all&#8217;osservatore un&#8217;impressione di continuità se accostate ripetutamente l&#8217;una accanto all&#8217;altra in orizzontale e in verticale.</p>
<p style="text-align: center"><img src="/images/posts/cgtexturescreen.jpg" border="0" alt="" width="400" height="273" /></p>
<p align="justify">Lo scopo di questo tutorial è quello di capire come è possibile creare immagini del genere, usando come base di partenza dei temi fotografati nella vita reale (muri, pavimenti, roccie, etc&#8230;) ed effettuare le trasformazioni necessarie con pochi strumenti e senza ricorrere a particolari software per la generazione procedurale (che in questo caso non servono proprio a niente).   (screenshot preso dal sito <a href="http://cgtextures.com/">http://cgtextures.com/</a>)</p>
<p><span id="more-35"></span></p>
<p align="justify">Come esempio pratico partiremo da una foto priva di loop presa dal sito <a href="http://cgtextures.com/">http://cgtextures.com/</a>, dentro il quale potrete trovare molte immagini di questo tipo. L&#8217;immagine si presenta inizialmente in questo modo:</p>
<p style="text-align: center"><img src="/images/posts/rock01.jpg" border="0" alt="" width="256" height="256" /></p>
<p align="justify">Costruiamo una seconda immagine di dimensioni doppie in altezza e larghezza, ed accostiamo la texture in modo da evidenziare la totale mancanza di loop:</p>
<p style="text-align: center"><img src="/images/posts/rock02.jpg" border="0" alt="" width="512" height="512" /></p>
<p align="justify">Adesso l&#8217;unica cosa da fare è ritagliare all&#8217;interno di questa immagine un rettangolo di dimensioni pari quelle della texture di partenza, in modo da ottenere una seconda texture sulla quale sarà necessario lavorare da questo momento in poi:</p>
<p style="text-align: center"><img src="/images/posts/rock03.jpg" border="0" alt="" width="512" height="512" /></p>
<p align="justify">E&#8217; meglio se non fate copia e incolla del rettangolo, ma continuate a lavorare all&#8217;interno della parte evidenziata in viola, perchè potrebbe essere necessario dover ritagliare alcuni pezzi che giacciono proprio sul bordo evidenziato. Per eliminare quella percezione di tassellamento è necessario fornire una continuità naturale all&#8217;immagine lavorando sul bordo di discontinuità (non quello viola!) con le diverse tecniche messe a disposizione dal programma di grafica che usate ed individuando, se è il caso, degli elementi naturali all&#8217;interno dell&#8217;immagine (come un mattone, una pietra, un teschio, etc&#8230;) da ritagliare e incollare sul bordo, per poi fonderlo in un secondo momento con altri effetti grafici. Il primo passo è formare un&#8217;immagine con discontinuità sempre meno evidenti operando una sorta di collage, come suggerito dalla seguente figura:</p>
<p style="text-align: center"><img src="/images/posts/rock04.jpg" border="0" alt="" width="512" height="512" /></p>
<p align="justify">Una volta che avrete reso i bordi meno discontinui, potete passare alla fase di ritocco durante la quale potete fondere gli elementi per eliminare le imperfezioni di questo collage di ritagli. Se state usando il paint shop pro vi consiglio un effetto di smudge, da applicare a mano nei punti critici come nel seguente esempio:</p>
<p style="text-align: center"><img src="/images/posts/rock05.jpg" border="0" alt="" width="530" height="230" /></p>
<p align="justify">Alla fine del lavoro, se avete proceduto correttamente, dovreste ottenere il risultato mostrato qui di seguito:</p>
<p style="text-align: center"><img src="/images/posts/rock06.jpg" border="0" alt="" width="256" height="256" /></p>
<p align="left">che mantiene un perfetto loop orizzontale e verticale:</p>
<p style="text-align: center"><img src="/images/posts/rock07.jpg" border="0" alt="" width="512" height="512" /></p>
<h2>Conclusioni</h2>
<p align="justify">Come abbiamo visto la creazione di texture fotorealistiche è veramente semplice, non richiede software di fotoritocco particolarmente complessi ne eccessive tribolazioni da parte di chi le realizza. L&#8217;importante è cercare di ottenere una certa continuità nell&#8217;immagine finale evitando di usare sempre lo stesso sistema o produrre delle immagini visivamente antiestetiche, come l&#8217;orrendo effetto di mirror ai bordi usato spesso nei videogiochi oppure la perdità della ruvidità usata dai grafici inesperti per diminuire la definizione del taglio. Per la verità esistono in rete dei programmi per la creazione automatica di questo tipo di texture, ma li sconsiglio caldamente perchè un risultato esteticamente perfetto lo si può ottenere solo con l&#8217;esperienza manuale di un essere umano: l&#8217;immagine oggetto di questo tutorial è perfetta ed è stata realizzata dal sottoscritto in meno di 5 minuti, quindi non esiste la reale necessità di usare un software dedicato. Ho usato un&#8217;immagine già presente in un sito, ma avrei potuto fotografare un muro vicino casa oppure la facciata di un palazzo, questa tecnica non presenta limiti e può essere usata per comporre qualsiasi tipo di ambientazione fotorealistica.</p>
<p align="justify">©2008 Gianpaolo Ingegneri</p>
]]></content:encoded>
			<wfw:commentRss>http://www.texturemind.com/post35/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get Ascii code from keyboard on windows/c++ (Ita)</title>
		<link>http://www.texturemind.com/post34/</link>
		<comments>http://www.texturemind.com/post34/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 20:32:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.texturemind.com/?p=34</guid>
		<description><![CDATA[Gli eventi windows per la gestione dell&#8217;input della tastiera non restituiscono direttamente un codice ascii ma uno molto più intrippato chiamato Virtual Key, studiato per consentire anche la gestione di quei tasti che non fanno parte del testo (come i cursori, il tasto stampa, etc&#8230;) o la conversione diretta in formati più avanzati, come l&#8217;unicode.
Se è mia intenzione [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">Gli eventi windows per la gestione dell&#8217;input della tastiera non restituiscono direttamente un codice ascii ma uno molto più intrippato chiamato Virtual Key, studiato per consentire anche la gestione di quei tasti che non fanno parte del testo (come i cursori, il tasto stampa, etc&#8230;) o la conversione diretta in formati più avanzati, come l&#8217;unicode.</p>
<p align="justify"><span id="more-34"></span>Se è mia intenzione fare un editor di testo, devo necessariamente ottenere il codice ascii per ogni rispettivo tasto premuto nella tastiera, dato che il virtual key non può essere gestito direttamente. Ho notato che in rete non circola granchè al riguardo e che la guida msdn è così confusa e superficiale da far venire i brividi, per questo motivo ho deciso di pubblicare questo piccolo listato in c++ che risolve alla perfezione il problema:</p>
<p align="justify">LRESULT WINDOWPROC(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)<br />
{<br />
BYTE keyStateArr[256];<br />
WORD value;<br />
CHAR asciicode;</p>
<p align="justify">switch( message )<br />
{<br />
case WM_KEYDOWN:</p>
<p>//preleva lo stato della tastiera<br />
GetKeyboardState(keyStateArr);</p>
<p>//converte la virtual key wParam in codice ascii<br />
if (ToAscii(wParam, (T_DWORD)lParam, keyStateArr, &amp;value, 0)  != 0)<br />
{<br />
asciicode = (T_CHAR) value;</p>
<p align="justify">//restituisce le maiuscole se è premuto il tasto shift<br />
if ((GetKeyState(VK_SHIFT) &amp; 0&#215;8000) &amp;&amp; wParam &gt;= &#8216;a&#8217; &amp;&amp; wParam &lt;= &#8216;z&#8217;)<br />
asciicode += &#8216;A&#8217;-'a&#8217;;<br />
}<br />
else<br />
{<br />
//restiruisce 0 se non è premuto alcun tasto con codice ascii<br />
asciicode = 0;<br />
}</p>
<p align="justify">Scrivi_il_testo(asciicode);</p>
<p>break;<br />
}</p>
<p>return DefWindowProc(hWnd, message, wParam, lParam);<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.texturemind.com/post34/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Graphics effects using chunky-to-planar on amiga/c (Ita)</title>
		<link>http://www.texturemind.com/post30/</link>
		<comments>http://www.texturemind.com/post30/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 23:41:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Download]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.texturemind.com/?p=30</guid>
		<description><![CDATA[Il cosiddetto modo planar è sempre stato un impedimento per quei programmatori che avevano intenzione di creare effetti grafici tridimensionali sull&#8217;Amiga, cosa che invece riusciva facilissima sui pc perchè supportavano nativamente il modo chunky. Esiste infatti una famosa disputa tra chi difendeva le peculiarità del planar (utile per i giochi 2d) e chi invece ne esaltava i [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">Il cosiddetto modo planar è sempre stato un impedimento per quei programmatori che avevano intenzione di creare effetti grafici tridimensionali sull&#8217;Amiga, cosa che invece riusciva facilissima sui pc perchè supportavano nativamente il modo chunky. Esiste infatti una famosa disputa tra chi difendeva le peculiarità del planar (utile per i giochi 2d) e chi invece ne esaltava i difetti (inutile per i giochi 3d), resta comunque una verità indiscutibile: senza chunky non è possibile lavorare direttamente con i pixel, e questa è una gravissima limitazione per chi vuole realizzare effetti grafici di qualsiasi tipo, cioè non ancorati a certe particolari caratteristiche dell&#8217;hardware, come rotazioni di immagini, motori in texture mapping, bump mapping, etc.</p>
<p style="text-align: center"><img src="/images/posts/amigaeffects.jpg" border="0" alt="" width="400" height="300" /></p>
<p align="justify">Fortunatamente esistono delle tecniche di conversione che permettono di minimizzare queste differenze e rendere la vita più facile ai programmatori che tutt&#8217;ora, per scopi puramente hobbystici, hanno intenzione di sviluppare qualche piccolo lavoro grafico su questa macchina del passato. Anch&#8217;io mi ci sono cimentato con esiti positivi e dato che in rete il materiale scarseggia ho deciso di pubblicare in questo articolo un piccolo progetto che incorpora le tecniche di conversione c2p e p2c più veloci (programmate in assembler) con un esempio di utilizzo all&#8217;interno di un listato in c per la visualizzazione degli effetti grafici in tempo reale.</p>
<p style="text-align: right"><a href="/files/amigagfx.zip"><img src="/images/d_amiga3.png" border="0" alt="" width="131" height="48" /></a></p>
<p><span id="more-30"></span><br />
Per chi non dovesse conoscere le terminologie:</p>
<p align="justify">- Il planar era una tecnica di visualizzazione delle bitmap con la quale i bit dei pixel da visualizzare sullo schermo dovevano essere memorizzati sotto forma di più array booleani detti appunto bitplane. Un&#8217;immagine da 8-bit, ad esempio, era composta da otto bit-plane, cioè da ben otto array booleani in memoria distinti e separati. E&#8217; facile capire che se in questo modo avessi avuto la necessità di accedere ad un pixel in memoria, dato che possono essere letti da un array soltanto 8 bit (1 byte)  alla volta, avrei dovuto leggere 8 array diversi per ciascun pixel dell&#8217;immagine, il che è così dispendioso da rendere inutilizzabile questa tecnica per effetti real time.</p>
<p align="justify">- Il chunky invece è il modo nativo con cui le schede grafiche del pc (ma oggi giorno direi tutte) permettono di visualizzare sullo schermo un&#8217;immagine memorizzata come una successione di byte stipati all&#8217;interno di un unico array. Uno o più byte, letti in modo sequenziale all&#8217;interno dell&#8217;array, rappresentano il pixel che verrà visualizzato sullo schermo. Quindi per un&#8217;immagine a 8 bit è necessario un unico array, e per accedere ad un pixel serve un solo accesso al relativo byte. Se l&#8217;immagine è a 16 bit devo leggere i 2 byte disposti in memoria l&#8217;uno dopo l&#8217;altro per ciascun pixel, e così via. E&#8217; questo il modo corretto di rappresentare, lavorare e visualizzare le immagini digitali.</p>
<p align="justify">- Una ChunkyToPlanar è un algoritmo super ottimizzato in assembler (non esistono c2p in c)  che ha lo scopo di convertire in una sola botta l&#8217;intera immagine chunky in un&#8217;altra di tipo planar, per poter essere visualizzata da un hardware che supporta solo il planar.</p>
<p align="justify">- Una PlanarToChunky è lo stesso tipo di algoritmo solo che converte le immagini da planare a chunky. Esso non è usato quasi mai nell&#8217;Amiga per effetti in tempo reale, ma probabilmente per catturare degli schermi elaborati via hardware dai chip custom per poi poterli memorizzare in un&#8217;immagine digitale da elaborare oppure salvare su file secondo i formati attualmente esistenti.</p>
<p align="justify">Nel listato che ho incluso c&#8217;è un esempio utile su come aprire uno schermo nuovo con la intuition, per poi creare un semplice algoritmo di disegno (una texture mapping dei pavimenti con filtraggio bilineare) e visualizzare il risultato sullo schermo. Vediamo soltanto di commentare le parti di codice più salienti:</p>
<p align="left">struct Screen *scr;</p>
<p>if(scr=OpenScreenTags(NULL, SA_Title,&#8221;New chunky to planar&#8221;, SA_DisplayID, 0&#215;00000000, SA_Depth, 8, SA_FullPalette, TRUE, SA_Exclusive, TRUE, TAG_DONE))<br />
{//codice}</p>
<p>Questo serve ad aprire uno schermo con le funzioni del sistema operativo. Ciò che viene visualizzato del sistema è una bitmap di tipo planar a 8 bit con palette. Per settare una semplice palette di tipo grayscale:</p>
<p align="justify">for (y = 0; y &lt; 256; y++)<br />
SetRGB32( &amp;scr-&gt;ViewPort, y, (y &lt;&lt; 24), (y &lt;&lt; 24), (y &lt;&lt; 24));</p>
<p align="justify">I canali rgb della palette sono a 8bit ciascuno, tuttavia devono essere shiftati in quel modo, forse per motivi di allineamento in memoria (infatti amiga usa il big-endian). Passiamo al pezzo forte, e cioè alla creazione della struttura per poter in seguito utilizzare la chunky to planar:</p>
<p align="justify">// creo un&#8217;immagine a 8bit di 320&#215;256</p>
<p align="justify">unsigned char *image;<br />
image = new unsigned char[320*256];</p>
<p align="justify">// costruisco le informazioni per la ChunkyToPlanar</p>
<p align="justify">struct c2pStruct c2p;<br />
c2p.bmap = scr-&gt;RastPort.BitMap; //indirizzo bitmap dello schermo amiga<br />
c2p.startX = 0; //posizione x<br />
c2p.startY = 0; //posizione y<br />
c2p.width = 320; //larghezza<br />
c2p.height = 240; //altezza<br />
c2p.ChunkyBuffer = image; //immagine chunky da visualizzare</p>
<p align="justify">Questo significa che convertiremo direttamente il contenuto di image nella bitmap di visualizzazione, cioè chiamando la chunkytoplanar visualizzaremo sullo schermo il contenuto di image nel seguente modo:</p>
<p align="justify">ChunkyToPlanarAsm(&amp;c2p);</p>
<p align="justify">Prima di chiudere il programma non dobbiamo scordarci di rilasciare l&#8217;immagine e di chiudere lo schermo amiga:</p>
<p align="justify">//rilascio la memoria usata per l&#8217;immagine<br />
delete [] image;</p>
<p align="justify">//chiudo lo schermo amiga<br />
CloseScreen(scr);</p>
<p align="justify">E&#8217; ovvio che questi listati possono essere messi insieme in un progetto compilabile solo da persone che hanno una certa esperienza, per questo motivo ho incluso anche l&#8217;eseguibile in formato Amiga, come dimostrativo per quegli utenti che vogliono vedere subito il risultato senza avere il tempo di compilare. Ricordate che l&#8217;effetto potrebbe sembrarvi lento non perchè la chunky to planar è lenta ma perchè l&#8217;algoritmo di disegno implementa un filtraggio di tipo bilineare. Per l&#8217;esecuzione sul pc consiglio l&#8217;ultima versione di winuae con harddisk e workbench installati, minimo 1mb di memoria e il coprocessore matematico casomai doveste usare  il processore 68030. Per una velocità di esecuzione decente settate il modo JIT (Just In Time).</p>
<p>©2008 Gianpaolo Ingegneri</p>
]]></content:encoded>
			<wfw:commentRss>http://www.texturemind.com/post30/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image scaling with subsampling technique (Ita)</title>
		<link>http://www.texturemind.com/post29/</link>
		<comments>http://www.texturemind.com/post29/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 00:39:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Download]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.texturemind.com/?p=29</guid>
		<description><![CDATA[Il sottocampionamento, noto anche come subsampling, è un algoritmo che permette di ridurre il numero di campioni di un segnale digitale oppure di un&#8217;immagine senza andare incontro, durante l&#8217;inevitabile perdita di informazione, al famoso difetto di aliasing. E&#8217; importante ridurre il più possibile questo difetto, perchè l&#8217;aliasing potrebbe provocare nei suoni un fastidioso brusio oppure [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">Il sottocampionamento, noto anche come subsampling, è un algoritmo che permette di ridurre il numero di campioni di un segnale digitale oppure di un&#8217;immagine senza andare incontro, durante l&#8217;inevitabile perdita di informazione, al famoso difetto di aliasing. E&#8217; importante ridurre il più possibile questo difetto, perchè l&#8217;aliasing potrebbe provocare nei suoni un fastidioso brusio oppure nelle immagini una percezione di forme imprecise o addirittura totalmente alterate.</p>
<p style="text-align: right"><a href="/files/sotto-campionamento.pdf"><img src="/images/download.png" border="0" alt="" width="121" height="34" /></a></p>
<p><span id="more-29"></span></p>
<p align="justify">Il sottocampionamento dei segnali digitali</p>
<p align="justify">Per capire meglio di cosa stiamo parlando, riprendiamo velocemente qualche cenno di segnali digitali. Un segnale digitale è una raccolta di n campioni, tipicamente campionati da un segnale analogico in base a un tempo di campionamento (durata temporale del campione), quindi si ha una frequenza di campionamento che corrisponde al numero massimo di campioni riprodotti al secondo (es: 44000). Il teorema del campionamento dice che la massima frequenza di campionamento (e quindi il numero di campioni) è scelta come circa il doppio della frequenza di taglio del segnale analogico da campionare, per esempio un suono con massimo 20000 Hz di banda passante (udibile umano) può essere campionato usando 48000 campioni al secondo per ottenere una qualità perfetta durante la fase di ascolto (ossia durante la conversione digitale-analogico). Tuttavia se riduciamo il numero di campioni da 48000 a 12800 al secondo otteniamo un&#8217;irrimediabile perdita di informazione ed un conseguente effetto di aliasing, che all&#8217;orecchio ci suonerà come un fastidioso brusio o altri tipi di rumore.</p>
<p align="justify">Vediamo in pseudocodice come viene operata questa riduzione dei campioni:</p>
<p>prima = 48000; dopo = 12800;<br />
step = prima / dopo; p = 0;</p>
<p>For n = 0  to dopo-1<br />
segnale_nuovo[n] = segnale_vecchio[int(p)];<br />
p += step;<br />
Next</p>
<p align="justify">Con questo algoritmo, noto anche come stretching, abbiamo costruito un nuovo segnale digitale sulla base di quello vecchio, che era da ridurre. Il nuovo segnale digitale ha preso un campione da quello vecchio, poi ne ha incrementato la posizione di lettura di 3.75 per poi prenderne un altro, questo significa che almeno 2 o 3 campioni sono stati scartati per ogni ciclo. Vediamo numericamente come si comporta la posizione di lettura p (che è un numero in virgola) e la posizione effettiva del campione da leggere (che è un numero intero).</p>
<p>n = 0;    p = 0;         int(p) = 0;<br />
n = 1;    p = 3.75;     int(p) = 3;     &#8217;scartati 1, 2<br />
n = 2;    p = 7.5;       int(p) = 7;     &#8217;scartati 4, 5, 6<br />
n = 3;    p = 11.25;   int(p) = 11;   &#8217;scartati 8, 9, 10<br />
n = 4;    p = 15;        int(p) = 15;   &#8217;scartati 12, 13, 14<br />
n = 5;    p = 18.75;   int(p) = 18;   &#8217;scartati 16, 17</p>
<p align="justify">Il sottocampionamento di un segnale consiste proprio nell’evitare di scartare questi campioni ed attribuire il loro peso informativo al nuovo campione sotto forma di media pesata per evitare l’effetto di aliasing. Il peso da associare ad ogni campione viene stabilito in base alla sua dimensione (misurata da 0 e 1) e prevedendo quanti campioni verrebbero scartati dopo un incremento della posizione di lettura. Vediamo come dovrebbe essere calcolato il nuovo campione, nel caso di n = 1:</p>
<p align="justify"><img src="http://www.texturemind.com/images/posts/sotto%20campionamento2.jpg" border="0" alt="" width="256" height="128" align="right" /></p>
<p>p1 = 3.75; int(p1) = 3; peso1 = 4 – 3.75 = 0.25;<br />
p2 = 4;      int(p2) = 4; peso2 = 5 &#8211; 4 = 1;<br />
p3 = 5;      int(p3) = 5; peso3 = 6 &#8211; 5 = 1;<br />
p4 = 6;      int(p4) = 6; peso4 = 7 &#8211; 6 = 1;<br />
p5 = 7.5;   int(p5) = 7; peso5 = 7.5 &#8211; 7 = 0.5;</p>
<p align="justify">
<p align="justify">Il campione nella posizione 3 ha un peso informativo di 4-3.75 = 0.25. Poi in ordine viene letto il campione successivo della posizione 4 con un peso di 1, e così via, fino ad arrivare alla posizione 7 con un peso di 0.5. Possiamo dunque renderci conto che il nuovo campione dovrà essere uguale alla media pesata di ben 5 campioni (la somma del campione di partenza, i 3 che sarebbero stati scartati e l’ultimo di arrivo). Indichiamo con s[n] il vecchio segnale e calcoliamo il nuovo campione nel seguente modo: nuovo_campione[1] = (s[3]*0.25 + s[4]*1 + s[5]*1 + s[6]*1 + s[7]*0.5) / 3.75; Osservando questa formula possiamo notare che gli unici campioni da moltiplicare per i pesi sono quello di partenza e quello di arrivo, mentre gli altri andrebbero moltiplicati per 1, cioè andrebbero sommati per come si presentano. Inoltre la somma dei pesi è pari alla lunghezza massima del campione, che in questo caso è pari allo step: possiamo creare dunque un algoritmo ottimizzato, abbastanza leggero dal punto di vista computazionale. Generalizzando il caso appena preso in esame, possiamo costruire in pseudo-codice l’algoritmo definitivo per il sottocampionamento di un segnale digitale:</p>
<p>prima = 48000; dopo = 12800;<br />
step = prima / dopo; p = 0;For n = 0  to dopo-1<br />
nuovo_campione = segnale_vecchio[int(p)] * (1 &#8211; (p-int(p)));<br />
For j = int(p)+1  to int(p+step)-1<br />
nuovo_campione += segnale_vecchio[j];<br />
Next</p>
<p>nuovo_campione += segnale_vecchio[int(p+step)] * ((p+step)-int(p+step));<br />
nuovo_segnale[n] = nuovo_campione / step;<br />
p += step;<br />
Next</p>
<p align="justify">Il sottocampionamento delle immagini digitali</p>
<p align="justify">Le immagini digitali possono essere trattate come il caso particolare di un segnale a due dimensioni: possiamo così estendere al caso bidimensionale l&#8217;algoritmo usato in precedenza per i segnali digitali. ll nuovo<img src="http://www.texturemind.com/images/posts/sotto%20campionamento1.jpg" border="0" alt="" width="209" height="209" align="right" /> campione deve essere calcolato non più in base alla media pesata di un solo vettore di campioni, ma di un&#8217;intera matrice di campioni, come è possibile vedere dalla figura qui accanto. Dobbiamo eseguire il calcolo del nuovo campione con media pesata esattamente come avevamo fatto in precedenza per un vettore di campioni, ripetendo l’operazione per ogni riga della matrice e tenendo conto che, nel bordo superiore ed in quello inferiore, i pesi di ciascun campione dovranno essere moltiplicati per un peso che è pari rispettivamente a [int(ty+1) – ty] e [(ty+sy) – int(ty+sy)]. Alla fine, la somma totale dei pesi che abbiamo attribuito a ciascun campione dovrà essere esattamente uguale a sx*sy, cioè l’area del rettangolo preso in considerazione (i pesi infatti sono proprio le aree di ogni singolo campione). Sviluppando l&#8217;algoritmo del sottocampionamento di un&#8217;immagine digitale otteniamo il seguente pseudo-codice:</p>
<p>Dim old_width, old_height<br />
Dim new_width, new_height<br />
sx = old_width / new_width;<br />
sy = old_height / new_height;</p>
<p>For py = 0  to new_height-1<br />
tx = 0;</p>
<p>For px = 0  to new_width-1</p>
<p>&#8216;riga superiore<br />
j = int(ty);<br />
new_sample = old_image[int(tx), j] * (1 &#8211; (tx-int(tx)));<br />
For i = int(tx)+1  to int(tx+sx)-1<br />
new_sample += old_image[i, j];<br />
Next<br />
new_sample += old_image[int(tx+sx), j] * ((tx+sx)-int(tx+sx));<br />
new_sample = new_sample * (1 &#8211; (ty-int(ty)));</p>
<p>&#8216;righe intermedie<br />
For j = int(ty)+1  to int(ty+sy)-1<br />
new_sample = old_image[int(tx), j] * (1 &#8211; (tx-int(tx)));<br />
For i = int(tx)+1  to int(tx+sx)-1<br />
new_sample += old_image[i, j];<br />
Next<br />
new_sample += old_image[int(tx+sx), j] * ((tx+sx)-int(tx+sx));<br />
Next</p>
<p>&#8216;riga inferiore<br />
j = int(ty+sy);<br />
new_sample2 = old_image[int(tx), j] * (1 &#8211; (tx-int(tx)));<br />
For i = int(tx)+1  to int(tx+sx)-1<br />
new_sample2 += old_image[i, j];<br />
Next<br />
new_sample2 += old_image[int(tx+sx), j] * ((tx+sx)-int(tx+sx));<br />
new_sample = new_sample2 * ((ty+sy)-int(ty+sy));</p>
<p>&#8217;scrivo il nuovo campione calcolato<br />
new_image[px, py] = new_sample / (sx * sy);<br />
tx += sx;<br />
Next<br />
ty += sy;<br />
Next</p>
<p style="text-align: center"><img src="http://www.texturemind.com/images/posts/sotto%20campionamento3.jpg" border="0" alt="" width="530" height="200" /></p>
<p align="justify">Com’è possibile vedere da questo esempio, l’immagine ridotta con lo stretch dei campioni presenta dei difetti di aliasing che non sono presenti nell’immagine ridotta con il sottocampionamento. Il subsampling è quasi sempre usato quando si devono ridurre delle immagini troppo grandi in immagini più piccole, come gli screenshot di un videogioco da inserire nell’articolo di una rivista, senza perdere qualità, anzi, nella maggior parte dei casi le immagini ridimensionate con questa tecnica risultano visivamente più gradevoli rispetto a quelle mostrate nelle loro dimensioni originali. Per questo motivo il sottocampionamento viene implementato in una sua variante, chiamata supercampionamento (supersampling) come tecnica di antialiasing per migliorare la qualità delle immagini generate da alcuni motori grafici, programmi di raytracing, generatori procedurali di texture e campionatori di forme geometriche anche complesse (come le clipart).</p>
<p>©2008 Gianpaolo Ingegneri</p>
]]></content:encoded>
			<wfw:commentRss>http://www.texturemind.com/post29/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fast Fourier Transform with Digital Images (Ita)</title>
		<link>http://www.texturemind.com/post27/</link>
		<comments>http://www.texturemind.com/post27/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 23:32:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Download]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.texturemind.com/?p=27</guid>
		<description><![CDATA[All&#8217;interno dello zip potete trovare un articolo che tratta il filtraggio delle immagini digitali mediante trasformata FFT 2D (Fast Fourier Transform &#8211; Trasformata di Fourier Veloce). Viene fatta un&#8217;ampia introduzione sulla teoria che sta alla base di questa tecnica ed analizzate nel dettaglio le diverse strategie implementative dal punto di vista della programmazione in c.

Nel pacchetto sono inclusi [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">All&#8217;interno dello zip potete trovare un articolo che tratta il filtraggio delle immagini digitali mediante trasformata FFT 2D (Fast Fourier Transform &#8211; Trasformata di Fourier Veloce). Viene fatta un&#8217;ampia introduzione sulla teoria che sta alla base di questa tecnica ed analizzate nel dettaglio le diverse strategie implementative dal punto di vista della programmazione in c.</p>
<p style="text-align: center"><img src="/images/posts/articolofft.jpg" border="0" alt="" width="400" height="274" /></p>
<p align="justify">Nel pacchetto sono inclusi i sorgenti completi in c, alcune immagini in formato pgm per fare delle prove e l&#8217;eseguibile nel caso abbiate subito voglia di vedere qualcosa di pratico. Oltre alla realizzazione della trasformata di fourier veloce, per poter lavorare in modo completo sullo spettro delle frequenze, sono stati presi in esame tre tipi di filtri diversi: ideale, butterworth e gaussiano. Viene affrontato anche il tema dell&#8217;uso dei filtri passabanda come soluzione per correggere eventuali disturbi periodici all&#8217;interno di un&#8217;immagine.</p>
<p style="text-align: right"><a href="/files/Filtri_FFT.zip"><img src="/images/download.png" border="0" alt="" width="121" height="34" /></a></p>
<p>©2008 Gianpaolo Ingegneri</p>
]]></content:encoded>
			<wfw:commentRss>http://www.texturemind.com/post27/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
