View Full Version : Simulare un convertitore D/A
dite sia possibile?
io penso di si; lo si può fare ad esempio effettuando una scansione di una immagine pixel/pixel e ricavandone il valore di luminosità e colore, quindi, rappresentare tali valori su di un grafico
dite che sto dicendo una enorme fesseria?
Originariamente inviato da misterx
[B]dite sia possibile?
io penso di si; lo si può fare ad esempio effettuando una scansione di una immagine pixel/pixel e ricavandone il valore di luminosità e colore, quindi, rappresentare tali valori su di un grafico
dite che sto dicendo una enorme fesseria?
Aspetta simulare un covertitore Digitale/Analogico è impossibile perchè i dati che rilevi saranno in ogni caso quantizzati...
L'unica cosa che poi fare è simulare i valori di tensione in uscita dal covertitore...
Ad esempio...io gli passo un numero a 8 bit...e lui mi tira fuori un valore compreso fra la tensione di base e la tensione massima quantizzato su 255 valori...
Un quanto sarà (VMax - VMin)/255....
Quindi VOut(num) sarà :
VOut(num) = VMin + ((VMax - VMin)/255)*num
Originariamente inviato da cionci
[B]
Aspetta simulare un covertitore Digitale/Analogico è impossibile perchè i dati che rilevi saranno in ogni caso quantizzati...
L'unica cosa che poi fare è simulare i valori di tensione in uscita dal covertitore...
Ad esempio...io gli passo un numero a 8 bit...e lui mi tira fuori un valore compreso fra la tensione di base e la tensione massima quantizzato su 255 valori...
Un quanto sarà (VMax - VMin)/255....
Quindi VOut(num) sarà :
VOut(num) = VMin + ((VMax - VMin)/255)*num
quello che intendevo dire è che se ritengo un singolo campione "quanto", una determinata tensione che varia nel tempo, come dici tu, riottengo il segnale "originale" di partenza; salvo alcune informazioni che risulteranno irrimediabilmente perse per sempre dovuto al procedimento di quantizzazione
però, se io riporto i singoli valori su di un grafico, dovrei riottenere il medesimo o la medesima forma d'onda di partenza
in sostanza: avendo un'immagine e volendo da essa ricostruire la forma d'onda del segnale PAL, non dovrebbe essere sufficiente rappresentare graficamente tali valori?
io penso di si
Devi fare il grafico di VOut ;)
c'è però un piccolo problema: usando le funzioni grafiche del C++ tipo:
GetPixel(x,y)
la velocità di scansione dell righe è alquanto bassa, dell'ordine di 4 secondi per immagine
per velocizzare il tutto, si deve leggere lo stato o valore degli indirizzi della memoria grafica?
Originariamente inviato da misterx
[B]c'è però un piccolo problema: usando le funzioni grafiche del C++ tipo:
GetPixel(x,y)
la velocità di scansione dell righe è alquanto bassa, dell'ordine di 4 secondi per immagine
per velocizzare il tutto, si deve leggere lo stato o valore degli indirizzi della memoria grafica?
No...non ti conviene...inoltre Windows non te lo permetterebbe...
Devi usare strumenti appositi per il disegno...o strumenti appositi per il disegno di grafici...
Prova un po' qui : http://www.codeproject.net/miscctrl/#Charting%20Controls
Mi sembra che ci siano molte cose interessanti ;)
Originariamente inviato da cionci
[B]
No...non ti conviene...inoltre Windows non te lo permetterebbe...
Devi usare strumenti appositi per il disegno...o strumenti appositi per il disegno di grafici...
già, forse si devono usare le directx: giusto?
però, BCB per le immagini mette a disposizione un Handle che se non sbaglio, dovrebbe essere l'indirizzo iniziale di un'area grafica
nel mio caso:
int *MioPuntatore = Image1->Picture->Canvas->Handle;
almeno, penso sia così
Originariamente inviato da misterx
[B]già, forse si devono usare le directx: giusto?
però, BCB per le immagini mette a disposizione un Handle che se non sbaglio, dovrebbe essere l'indirizzo iniziale di un'area grafica
nel mio caso:
int *MioPuntatore = Image1->Picture->Canvas->Handle;
almeno, penso sia così
Usi BCB ? Perchè quella roba che ti ho passato è per VC++...li c'è roba che fa per te (ad esempio una specie di oscilloscopio con un aggiornamento molto veloce)...
ho sempre usato BCB e penso che lo si possa fare anche con questo compilatore;)
cmq, la simulazione "realistica" di un convertitore D/A la si può fare; lo dimostra anche la tua formuletta:)
Originariamente inviato da misterx
[B]ho sempre usato BCB e penso che lo si possa fare anche con questo compilatore;)
cmq, la simulazione "realistica" di un convertitore D/A la si può fare; lo dimostra anche la tua formuletta:)
Sotto quest'ottica sì...avevo capito tutt'altra cosa ;)
Riguardo a BCB purtroppo non sono in grado di aiutarti perchè non conosco siti che mettono a disposizione controlli free...
Comunque è ovvio che si possa fare...
In BCB 6 ho visto che nella toolbar samples c'è un componente chiamato performance graph...quello ti potrebbe andare bene...
Originariamente inviato da cionci
[B]In BCB 6 ho visto che nella toolbar samples c'è un componente chiamato performance graph...quello ti potrebbe andare bene...
forse non ci siamo capiti
io piazzo su una form un'immagine e con con loop, la scandisco pixel/pixel per ottenere il valore RGB del pixel stesso
il problema è che usando le funzioni grafiche di C++, la velocità è alquanto bassa
per questo ho detto che si dovrebbe forse fare una scansione degli indirizzi della scheda grafica dove è mappata la mia immagine
per fare un esempio:
non penso che un player disponga i pixel sul video attraverso coordinate (x,y e colore)
in questo caso si avrebbe un frame rate abbastanza banale; dell'ordine di 1 frame ogni 4 secondi;)
Ah credevo che la lentezza ci fosse nel generare il grafico...
Scusa, ma il bitmap lo carichi da disco ? Oppure puoi ottenere il vettore dei dati visualizzati tramite qualche puntatore al bitmap ? Ti dovrebbe bastare scandire quel vettore...
Questo ti potrebbe andare bene :
Byte *rowPtr;
TBitmap *pBitmap = Image1->Picture->Bitmap;
for (int y = 0; y < pBitmap->Height; y++)
{
rowPtr = (Byte *)pBitmap->ScanLine[y];
for (int x = 0; x < pBitmap->Width; x++)
switch(pBitmap->PixelFormat)
{
//le costanti dei vari formati sono : pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom
//ad seconda del formato dovrai comportati in maniera diversa per leggere la riga
}
}
interessante il codice che ho sperimentato scandendo il puntatore (*rowPtr)
sto andando a fondo alla questione e vorrei riuscire ad ottenere 25 scansioi al secondo:)
se ti capitasse di trovare una porzione di codice abbastanza breve che permette di ruotare in tempo reale una Bitmap su di un'altra bitmap ti ringrazio: in pratica, l'una farebbe da sfondo fisso, l'altra, di dimensioni minori, ruota su essa
P.S.
ho trovato in rete alcuni esempi ma a mio parere si possono ottenere i medesimi effetti con molto meno codice
Originariamente inviato da misterx
[B]se ti capitasse di trovare una porzione di codice abbastanza breve che permette di ruotare in tempo reale una Bitmap su di un'altra bitmap ti ringrazio: in pratica, l'una farebbe da sfondo fisso, l'altra, di dimensioni minori, ruota su essa
Dovrebbe essere solamente una questione matematic...ora ci penso un po'...
Originariamente inviato da cionci
[B]Ah credevo che la lentezza ci fosse nel generare il grafico...
Scusa, ma il bitmap lo carichi da disco ? Oppure puoi ottenere il vettore dei dati visualizzati tramite qualche puntatore al bitmap ? Ti dovrebbe bastare scandire quel vettore...
Questo ti potrebbe andare bene :
Byte *rowPtr;
TBitmap *pBitmap = Image1->Picture->Bitmap;
for (int y = 0; y < pBitmap->Height; y++)
{
rowPtr = (Byte *)pBitmap->ScanLine[y];
for (int x = 0; x < pBitmap->Width; x++)
switch(pBitmap->PixelFormat)
{
//le costanti dei vari formati sono : pfDevice, pf1bit,
pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom
//ad seconda del formato dovrai comportati in maniera diversa per leggere la riga
}
}
però, se (*rowPtr) dichiarato come Byte, punta a soli 8 bit di informazione per ogni punto di ogni riga, come ottengo le restanti informazioni che perdo, in quanto so che ad ogni pixel sono associati 24 bit
Ti ho appunto messo le varie costanti dentro lo switch ;)
switch(pBitmap->PixelFormat)
{
pf1bit:
int i = x >> 3; //divido per 8
int p = x & 0x07; //resto della divisione per 8
//col = 1 pixel bianco - 0 pixel nero
unsigned char col = ((*rowPtr[i]) & (1<<p)) >> p ;
...
...
//scrivo col nel pixel
*rowPtr[i] = (((*rowPtr[i]) & (1<<p)) > 0) ?
((*rowPtr[i]) & (col<<p)) :
((*rowPtr[i]) | (col<<p));
break;
pf4bit:
int i = x >> 1; //divido per 2
int p = x & 0x01; //resto della divisione per 2
//col = codifica del colore a 4 bit
unsigned char col = p ?
((*rowPtr[i]) >> 4) :
((*rowPtr[i]) & 0xF0);
...
...
//scrivo col nel pixel
*rowPtr[i] = p ?
((*rowPtr[i]) & 0x0F + (col<<4)) :
((*rowPtr[i]) & 0xF0 + col & 0x0F);
break;
pf8bit:
int i = x;
unsigned char col = *rowPtr[i]; //col = codifica del colore a 8 bit
...
...
*rowPtr[i] = col; //scrivo col nel pixel
break;
pf15bit:
int i = x*2;
//col = codifica del colore a 16 bit
unsigned short col = (*rowPtr[i]) + (((*rowPtr[i+1]) & 0x7F) << 8);
...
...
//scrivo nella parte meno significativa del pixel
*rowPtr[i] = (Byte)(col & 0x00FF);
//scrivo nella parte più significativa del pixel
*rowPtr[i+1] = (Byte)((col & 0x7F00) >> 8);
break;
pf16bit:
int i = x*2;
//col = codifica del colore a 16 bit
unsigned short col = (*rowPtr[i]) + ((*rowPtr[i+1]) << 8);
...
...
//scrivo nella parte meno significativa del pixel
*rowPtr[i] = (Byte)(col & 0x00FF);
//scrivo nella parte più significativa del pixel
*rowPtr[i+1] = (Byte)((col & 0xFF00) >> 8);
break;
pf24bit:
int i = x*3;
//col = codifica del colore a 24 bit
unsigned int col = (*rowPtr[i]) + ((*rowPtr[i+1]) << 8) + ((*rowPtr[i+2]) << 16);
...
...
//scrivo nella parte meno significativa del pixel
*rowPtr[i] = (Byte)(col & 0x000000FF);
*rowPtr[i+1] = (Byte)((col & 0x0000FF00) >> 8);
//scrivo nella parte più significativa del pixel
*rowPtr[i+2] = (Byte)((col & 0x00FF0000) >> 16);
break;
pf32bit:
int i = x*4;
//col = codifica del colore a 32 bit
unsigned int col = (*rowPtr[i]) + ((*rowPtr[i+1]) << 8) + ((*rowPtr[i+2]) << 16) + ((*rowPtr[i+3]) << 24);
...
...
//scrivo nella parte meno significativa del pixel
*rowPtr[i] = (Byte)(col & 0x000000FF);
*rowPtr[i+1] = (Byte)((col & 0x0000FF00) >> 8);
*rowPtr[i+2] = (Byte)((col & 0x00FF0000) >> 16);
//scrivo nella parte più significativa del pixel
*rowPtr[i+3] = (Byte)((col & 0xFF000000) >> 16);
break;
default:
}
Ho supposto che i byte fossero allineati a sinistra...
Cioè...che il pixel non utilizzato dei 15 bit fosse l'ultimo...e che la codifica RGB venga memorizzata proprio nell'ordine RGB con R nel byte meno significativo...
Per vedere se va bene ti devi far un po' di debug...ad esempio assegnando a col 255 (nella codifica a 24 bit) e scrivendolo in tutti i pixel, se ti diventa tutto rosso allora ho fatto bene...se ti diventa tutto blu allora li ho invertiti (e devi invertire l'ordine di lettura e scrittura dei 15, 16, 24 e 32 bit)...
sono ordinati nell'ordine RGB, quindi il tuo ragionamento è corretto
Nei 4 bit c'è in errore...nella lettura la maschera per fare l'AND è 0x0F e non 0xF0...
anzi, mi correggo:
pf24bit:
int i = x*3;
//col = codifica del colore a 24 bit
unsigned int col = ((*rowPtr[i]) << 16) + ((*rowPtr[i+1]) << 8) + (*rowPtr[i+2]);
è in formato BGR
ora devo solo velocizzare la scansione delle righe ed ottenere il livello di luminosità
:)
Cionci:
ottimo lavoro;)
Originariamente inviato da misterx
[B]ottimo lavoro;)
Thanks :)
Quando hai finito fammi vedere il risultato ;)
sto approfondendo la conversione D/A; eppure mi sembrava semplicemente una tensione che variasse nel tempo
per quando riguarda la rotazione delle Bitmap, ho provato le funzioni tradizionali ma non sono sufficientemente performanti; molti esempi trovati in rete, si basano sull'uso della "ScanLine" poi con un pò di trigonometria ruotano pixel per pixel
ho visto che la soluzione più perfrmante è: o l'uso dell'assemble oppure usare componenti freeware:D che utilizzano le librerie OpenGL
a quanto pare, ai giorni nostri c'è ben poco da inventare:(
fa niente, usiamo tutto ciò che c'è a disposizione:)
una mia riflessione:
sei anche tu convinto che oggi la programmazione si divenuta l'arte di mettere insieme tutta quella nutrita serie di funzioni, componenti compresi, già scritte da altri?
Dipende a che livello si programma...quando devi fare in un'applicazione commerciale di alto livello riutilizzare componenti già fatti sta un po' male :)
Nelle piccole applicazioni commerciali o in quelle freeware recuperare codice già fatto è un bene...sia per il fatto che si impara qualcosa...sia perchè si fa prima ;)
Ah...lo sai come si fa per velocizzare le funzioni che usano la trigonometria ? Si fanno il seno e coseno cablati (anche se probabilmente lo fanno già i compilatori, ma magari con un grado di precisione più alto)...
Ad esempio puoi fare un vettore di 360 elementi...uno per ogni grado con all'interno il valore del seno e del coseno per ogni grado...
E' molto più veloce...
sapevo del calcolo matriciale per velocizzare il tutto
ho trovato un componente per le OpenGL qui: **** (http://www.ciemmesoft.com/componenti/categorieing.asp?ID=4&PAG=1 )
ma non riesco a trovare la documentazione
se ne sapete qualcosa
grazie 2000 volte:)
ho trovato la documentazione, come non detto:)
Originariamente inviato da cionci
[B]Dipende a che livello si programma...quando devi fare in un'applicazione commerciale di alto livello riutilizzare componenti già fatti sta un po' male :)
Nelle piccole applicazioni commerciali o in quelle freeware recuperare codice già fatto è un bene...sia per il fatto che si impara qualcosa...sia perchè si fa prima ;)
Ah...lo sai come si fa per velocizzare le funzioni che usano la trigonometria ? Si fanno il seno e coseno cablati (anche se probabilmente lo fanno già i compilatori, ma magari con un grado di precisione più alto)...
Ad esempio puoi fare un vettore di 360 elementi...uno per ogni grado con all'interno il valore del seno e del coseno per ogni grado...
E' molto più veloce...
ho trovato un metodo, alla larga dalle Opengl, non male
si tratta di avere due matrici (x/y) atte a contenere un'immagine
si fa una scansione in direzione Y e si assegnano i puntatori alla seconda matrice per i quali solo per la X ti calcoli la nuova posizione
in definitiva, per un sistema di coordinate X/Y, la Y ti viene già ritornata dal loop di scansione delle Y, quindi, solo per la X, devi calcolarti la nuova posizione di dove dovrà essere disegnato il pixel
non so se sono riuscito a farmi capire:)
All'incirca sì...comunque se mi mandi l'algoritmo mi farebbe piacere guardarlo un po'...
cmq, penso che la tecnica si chiami rotazione di puntatori?
a te la sentenza:)
do ancora una pelatina al codice e ti mostro il risultato:)
int xOrig , yOrig;
double Angolo, cosAngolo, sinAngolo;
RGBTRIPLE *RigaOriginale, *RigaRuotata;
Graphics::TBitmap *MiaBitmap = new Graphics::TBitmap;
MiaBitmap->Width = Image1->Width;
MiaBitmap->Height = Image1->Height;
MiaBitmap->PixelFormat = pf24bit;
for(int Gradi = 0; Gradi <= 360; Gradi++)
{
Angolo = -Gradi * M_PI/180;
sinAngolo = sin(Angolo);
cosAngolo = cos(Angolo);
for ( int y = MiaBitmap->Height-1; y >= 0 ; y--)
{
RigaOriginale = (RGBTRIPLE*)Image1->Picture->Bitmap->ScanLine[y];
RigaRuotata = (RGBTRIPLE*)MiaBitmap->ScanLine[y];
for ( int x = BitmapRotated->Width-1; x >= 0; x--)
{
xOrig = int(x * cosAngolo - y * sinAngolo);
yOrig = int(x * sinAngolo + y * cosAngolo);
if ( (xOrig >= 0) && (xOrig <= Image1->Width-1) &&
(yOrig >= 0) && (yOrig <= Image1->Height-1) )
{
RigaRuotata[x] = RigaOriginale[xOrig];
}
else
{
RigaRuotata[x].rgbtBlue = 0;
RigaRuotata[x].rgbtGreen = 0;
RigaRuotata[x].rgbtRed = 0;
}
}
}
Image2->Picture->Bitmap = MiaBitmap;
Quanti FPS riesci a fare in quel modo ?
dipende dallo step dei gradi; cmq, non molti
cmq, io che ho un 1700, la rotazione avviene in modo fluido: peccato che il tutto è legato alla potenza di calcolo della CPU
ecco perchè mi ero orientato verso le OpenGL
ci vorrebbe un metodo che ruotasse un'intera riga senza scandire i singoli puntatori
chissà se esiste, ma temo di no
cmq, qui (http://digilander.libero.it/daffol/ruota.zip) c'è la versione compilata e zippata (279Kb circa); vedi come gira a te:)
pardon, mancava qualche libreria: ho corretto:)
Originariamente inviato da misterx
[B]pardon, mancava qualche libreria: ho corretto:)
Infatti...ho provato ieri sera e mancava la libreria per i jpg...
Va bene (Tb @1200)...dopo tutto l'immagine è anche molto grande...
Quanti gradi di rotazione gli fai fare per ogni frame ?
Ci credoc he va lento :)
Prova a fargli fare una rotazione in 25 frames...
Così com'è ci emtte circa 3,5 secondi...ma fa 365 frames...
Quindi dovrebbe fare circa 100 frame al secondo...
Fagli fare una rotazione di 365/25 gradi...te la dovrebbe fare molto velocemente...
Ed a quel punto puoi mettere una temporizzazione per rendere la velocità indipendente dalla CPU...
Non è detto... Hai provato a farla girare di 2 gradi alla volta ? Scatta ?
ora dovrebbe viaggiare a 25 fps
qui (http://digilander.libero.it/daffol/ruota.zip)
vedi anche l'esempio banale di conversione D/A; ci sto rimettendo mano usando la ScanLine che è molto + efficace
lo start/stop come puoi vedere non sono molto efficaci: dammi tempo
anche la rappresentazione grafica lascia a desiderare in quanto sto approfondendo il segnale PAL
per quanto riguarda l'esempio per la scrittura di file AVI, postato qualche tempo fa, se ti capita un esempio meno dispersivo o magari un funzione già bella e pronta alla quale spedire una BitMap ti ringrazio:)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.