f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 2022
-
19 juin 2007 à 13:31
amirrazi506
Messages postés18Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention22 novembre 2007
-
28 août 2007 à 16:43
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
amirrazi506
Messages postés18Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention22 novembre 2007 28 août 2007 à 16:43
Salut Kenavo
MERCI pour touts
moi amirrazi506
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 20123 24 juin 2007 à 10:58
Kenavo,
Tout roule pour le mode I420 ou presque ;P. Si tu décoches tout il faut quand même sortir le plumeau à cause des poussières. Il manque un "if poussieres.Checked then" à la ligne 247. Bref, rien de bien grave.
P.S. Merci d'avoir passé du temps à coder le mode I420.
Cordialement.
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 24 juin 2007 à 01:41
Nostalgie ? Un peu ! Faut quand même être un peu nostalgique pour pratiquer encore le Pascal !
N'empêche que les mariés de cet après midi, pour lesquels j'avais écrit ce code, ont trouvé ces images "transmutées" des plus "jolies"
Va comprendre ces jeunes qui trouvent le vieux rassurant !.....
Et j'espère que WhiteHippo et ses webcam ont trouvé leur bonheur dans la dernière version
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 23 juin 2007 à 23:19
Petite période de nostalgie des années Lumière ? A quand l'impression sur de bonnes vieilles pellicules argentiques ? mdr
Je n'ai rien compris à vos histoires de I420, IYUV et YUY2 et autres sigles mais ce n'est pas grave.
En tous cas, félicitations à Kenavo qui nous sort quelque chose de très original et bien ficelé.
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 20123 21 juin 2007 à 19:35
Pour information, et pour ceux qui ne connaissent pas le mode I420 (=IYUV) et/ou les autres formats de pixels, un très bon site (en anglais) fait référence : www.fourcc.org
Cordialement.
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 21 juin 2007 à 15:34
WhiteHippo,
Il me reste donc à adapter les effets d'images pour le mode I420 (dont je dispose et que je connais un peu).
Je pensais - naïvement, j'en conviens - que le mode RGB était standard.
Pour le sépia ça ne pose pas de problème particulier, puisqu'il doit suffire de modifier les tables U et V en conservant Y
Pour les rayures et les taches pas de problèmes non plus : les modifications portent je pense seulement sur la table Y
Les sauts et glissements peuvent peut-être être réalisés juste sur la table Y puisque les tables U et V devraient être constantes.
J'y jetterais un coup d'oeil dès que j'aurais un moment.
A+
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 20123 21 juin 2007 à 13:30
Kenavo,
"Si tu active la ligne (Capture1.SelectFormat dans OnActivate) tu as accès aux paramètres de format de la vidéo.
",:
C'est ce que j'ai fait :)
N.B. Capture1.SelectDisplay provoque également une exception 'Microsoft WDM Image Capture (Win32):Pas de dialogue "Display" pour ce périphérique!'
"Ça m'étonne que tes webcams ne disposent pas du mode RVB !" :
Celle qui dispose du plus de mode est ma vieille Logitech VCAM-U1 (RGB24,RGB32,YUY2,RGB555 16 bits,I420,YVU9,UYVY). Avec ma Philips SPC900NC/00 juste les modes I420, IYUV (le même quoi ;) et YUY2. Ceci explique peut être les taux qu'elle arrive à atteindre de 60fps, voire 90fps sous certaines conditions. Avec l'autre pas de modes RGB non plus. Mais j'ai des doutes sur celle là quand au driver. Je referais un essai en le réinstallant.
Cordialement.
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 21 juin 2007 à 08:47
Salut WhiteHippo
Ça m'étonne que tes webcams ne disposent pas du mode RVB !
Si tu active la ligne (Capture1.SelectFormat dans OnActivate) tu as accès aux paramètres de format de la vidéo.
Ma webcam n'est pas très vielle (Logitech Quickcam Pro 5000)
Pour les vidéos en 640x480, il y a des bugs. Il faut tout d'abord que le bitmap du cadre soit du même format que la vidéo
J'ai ensuite quelques problème d'indices que j'ai corrigé
Il me reste à voir pourquoi en mode enregistrement, en 640 x 480) l'image n'est plus raffraichie à l'écran !
Mise à jour à venir ....
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 20123 20 juin 2007 à 21:59
Hello Kenavo
Testé avec 3 webcams dfférentes, une seule concluante, la plus vieille en 320x240... (Les 2 autres ne disposant pas d'un mode RVB 24 ;) Programme et effet plutôt réussi.
P.S. J'ai pas le temps de déboggué le programme, mais j'ai un problème lorsque je configure le TCapture et la webcam en 640x480. J'ai bien une image qui apparait, signe que normallement ok, mais j'obtiens une exception EInvalidGraphicOperation 'Indice ligne hors limites' sur l'affectation de P2 dans Capture1Frame (Affectation du Scanline).
Cordialement.
Francky23012301
Messages postés400Date d'inscriptionsamedi 6 août 2005StatutMembreDernière intervention11 février 20161 19 juin 2007 à 17:06
Salut,
Ayant une webcam j'ai pu essayer et ca marche nickel : super code Kénavo ^^.
@+
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 19 juin 2007 à 16:33
Merci à Renfield pour le lien, je vais pouvoir modifier la vitesse de lecture du film.
Un peu de boulot pour adapter les structures, mais ça doit être jouable.
@Cirec : Scanline une fois par image ! C'est pas trop, non ? Et j'utilise bien le PByte
(Le PByte est le type d'origine dans la structure retournée par la fonction callback OnFrame ou OnVideoStream, j'ai donc fait avec).
Mais je vais relire avec attention tes commentaires sur la source de l'ami Mauricio.
Ken@vo
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 19 juin 2007 à 15:00
Il faudrait aussi des saccades dans le .avi pour simuler le fait que la manivelle ne tourne pas à vitesse constante !
Pour la ligne Pointeur^[iia + 2] := Pointeur^[iia + 2], elle est certes inutile mais ne ralentit pas le calcul car elle n'est pas compilée (pas de point bleu devant). Ceci prouve que delphi fait bien son boulot !
Pour les avi, désolé mais je n'en sais rien.
++
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 19 juin 2007 à 14:28
@F0XI : C'est vrai que le pré-calcul d'indice, sachant qu'il faut agir sur 3 pixels consécutifs, est intéressant. Je suis plus réservé sur l'emploi des shl et shr, qui rendent, à mon avis le source moins clair, surtout que dans ce cas, div 2 ou * 2, le compilateur traduit ces instruction par les rotations !
@FLORENTH : FreeAndNil ! Bon sang mais c'est bien sûr ! Traces résiduelle d'une utilisation massive de Delphi 4 !
Autre remarque :
dans la transformation des couleur en Sépia, j'anticipe la question : "A quoi sert la première ligne ?" (Ici avec l'optimisation de F0XI)
begin
Pointeur^[iia + 2] := Pointeur^[iia + 2];
Pointeur^[iia + 1] := Pointeur^[iia + 2];
Pointeur^[iia + 0] := TabSepia[Pointeur^[iia + 2]];
end;
La réponse est : elle ne sert à rien !
Mais, cela permet d'essayer la transformation des couleurs en utilisant comme référence de luminosité une des couleurs fondamentales. Ici (iia + 2) utilise le rouge comme référence, mais on peut remplacer à chaque ligne par (iia + 1) ce qui fera du vert la référence ou (iia + 0) qui utilisera le bleu.
Si on veut faire une transformation plus complète à partie de la luminance réelle, il faut calculer celle ci avec la formule bien connue (?!) Y = 0.299R + 0.587G + 0.114B, ce qui évidemment plomberait les calculs.
Autre question : Connaissez vous un moyen simple de modifier la vitesse de lecture d'un AVI ? Cela permettrait de donner le petit air vieillot des films tournés à la manivelle au environ de 18 à 20 images/seconde et qui sont projetés à 25 images/seconde.
Moi non plus je n'ai pas de webcam pour vérifier mais j'ai transposé l'effet avec getdibits (par ailleurs, est-ce vraiment plus rapide que scanline ?).
Et bien verdict: very good job !! On voit bien que les webcam t'inspirent !
Le meilleur dans tout ça: les rayures ! On dirait vraiment que tu as une vielle webcam des années 30 (y'avait des ordis à cette époque ? ^^).
Petite optimisation de l'optimisation de f0xi:
Position := Position + Random( (Stabilite shl 1) + 1) - Stabilite;
if (position < 0) or (position >= a) then
Duree := 1;
Dec(Duree);
if Duree = 0 then
begin
Rayure[i].Free;
Rayure[i] := nil;
end;
devient
Inc(Position, Random( (Stabilite shl 1) + 1) - Stabilite);
if (Duree = 1) or (Position < 0) or (Position >= a) then
FreeAndNil(Rayure[i])
else
Dec(Duree);
A + et continue de nous épater !
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202237 19 juin 2007 à 13:31
ça a l'air pas mal, mais n'ayant pas de webcam pour verifier .... :)
petite optim :
procedure TForm1.Capture1Frame(Sender: TObject; HndPreview: Cardinal; lpVHdr: PVIDEOHDR);
var
Pointeur, P2: PTabByte;
iia,iib, i, j, a, b, c: integer;
begin
Pointeur := Pointer(lpVHdr^.lpData);
P2 := Bitmap.ScanLine[239];
a := Capture1.Width;
b := Capture1.Height;
if sepia.Checked then
for i := 0 to a - 1 do
for j := 0 to b - 1 do
begin
iia := (j * a + i) * 3;
Pointeur^[iia + 2] := Pointeur^[iia + 2];
Pointeur^[iia + 1] := Pointeur^[iia + 2];
Pointeur^[iia + 0] := TabSepia[Pointeur^[iia + 2]];
end;
if rayures.Checked then
for i := 0 to tbRayures.Position do
if Rayure[i] <> nil then
with Rayure[i] do
begin
for j := 0 to Capture1.Height - 1 do
begin
iia := (j * a + Position) * 3;
Pointeur^[iia] := Pointeur^[iia] shr 1;
Pointeur^[iia + 1] := Pointeur^[iia] shr 1;
Pointeur^[iia + 2] := Pointeur^[iia] shr 1;
end;
Position := Position + Random( (Stabilite shl 1) + 1) - Stabilite;
if (position < 0) or (position >= a) then
Duree := 1;
dec(Duree);
if Duree = 0 then
begin
Rayure[i].Free;
Rayure[i] := nil;
end;
end;
if poussieres.Checked then
for i := 0 to tbPoussiere.Position do
begin
c := Random(a * b);
iia := c * 3;
Pointeur^[iia] := 255;
Pointeur^[iia + 1] := 255;
Pointeur^[iia + 2] := 255;
end;
if Cadre.Checked then
for i := 0 to a - 1 do
for j := 0 to b - 1 do
begin
c := P2^[(j * a + i) * 3];
iia := (j * a + i) * 3;
Pointeur^[iia] := min(Pointeur^[iia] + c, 255);
Pointeur^[iia + 1] := min(Pointeur^[iia + 1] + c, 255);
Pointeur^[iia + 2] := min(Pointeur^[iia + 2] + c, 255);
end;
if sauts.Checked and (saut > 0) then
begin
for i := 0 to a-1 do
for j := b-1 downto saut do
begin
iia := (j * a + i) * 3;
iib := ((j-saut) * a + i) * 3;
Pointeur^[iia] := Pointeur^[iib];
Pointeur^[iia + 1] := Pointeur^[iib + 1];
Pointeur^[iia + 2] := Pointeur^[iib + 2];
end;
Saut := 0;
end;
end;
28 août 2007 à 16:43
MERCI pour touts
moi amirrazi506
24 juin 2007 à 10:58
Tout roule pour le mode I420 ou presque ;P. Si tu décoches tout il faut quand même sortir le plumeau à cause des poussières. Il manque un "if poussieres.Checked then" à la ligne 247. Bref, rien de bien grave.
P.S. Merci d'avoir passé du temps à coder le mode I420.
Cordialement.
24 juin 2007 à 01:41
N'empêche que les mariés de cet après midi, pour lesquels j'avais écrit ce code, ont trouvé ces images "transmutées" des plus "jolies"
Va comprendre ces jeunes qui trouvent le vieux rassurant !.....
Et j'espère que WhiteHippo et ses webcam ont trouvé leur bonheur dans la dernière version
23 juin 2007 à 23:19
Je n'ai rien compris à vos histoires de I420, IYUV et YUY2 et autres sigles mais ce n'est pas grave.
En tous cas, félicitations à Kenavo qui nous sort quelque chose de très original et bien ficelé.
21 juin 2007 à 19:35
Cordialement.
21 juin 2007 à 15:34
Il me reste donc à adapter les effets d'images pour le mode I420 (dont je dispose et que je connais un peu).
Je pensais - naïvement, j'en conviens - que le mode RGB était standard.
Pour le sépia ça ne pose pas de problème particulier, puisqu'il doit suffire de modifier les tables U et V en conservant Y
Pour les rayures et les taches pas de problèmes non plus : les modifications portent je pense seulement sur la table Y
Les sauts et glissements peuvent peut-être être réalisés juste sur la table Y puisque les tables U et V devraient être constantes.
J'y jetterais un coup d'oeil dès que j'aurais un moment.
A+
21 juin 2007 à 13:30
"Si tu active la ligne (Capture1.SelectFormat dans OnActivate) tu as accès aux paramètres de format de la vidéo.
",:
C'est ce que j'ai fait :)
N.B. Capture1.SelectDisplay provoque également une exception 'Microsoft WDM Image Capture (Win32):Pas de dialogue "Display" pour ce périphérique!'
"Ça m'étonne que tes webcams ne disposent pas du mode RVB !" :
Celle qui dispose du plus de mode est ma vieille Logitech VCAM-U1 (RGB24,RGB32,YUY2,RGB555 16 bits,I420,YVU9,UYVY). Avec ma Philips SPC900NC/00 juste les modes I420, IYUV (le même quoi ;) et YUY2. Ceci explique peut être les taux qu'elle arrive à atteindre de 60fps, voire 90fps sous certaines conditions. Avec l'autre pas de modes RGB non plus. Mais j'ai des doutes sur celle là quand au driver. Je referais un essai en le réinstallant.
Cordialement.
21 juin 2007 à 08:47
Ça m'étonne que tes webcams ne disposent pas du mode RVB !
Si tu active la ligne (Capture1.SelectFormat dans OnActivate) tu as accès aux paramètres de format de la vidéo.
Ma webcam n'est pas très vielle (Logitech Quickcam Pro 5000)
Pour les vidéos en 640x480, il y a des bugs. Il faut tout d'abord que le bitmap du cadre soit du même format que la vidéo
J'ai ensuite quelques problème d'indices que j'ai corrigé
Il me reste à voir pourquoi en mode enregistrement, en 640 x 480) l'image n'est plus raffraichie à l'écran !
Mise à jour à venir ....
20 juin 2007 à 21:59
Testé avec 3 webcams dfférentes, une seule concluante, la plus vieille en 320x240... (Les 2 autres ne disposant pas d'un mode RVB 24 ;) Programme et effet plutôt réussi.
P.S. J'ai pas le temps de déboggué le programme, mais j'ai un problème lorsque je configure le TCapture et la webcam en 640x480. J'ai bien une image qui apparait, signe que normallement ok, mais j'obtiens une exception EInvalidGraphicOperation 'Indice ligne hors limites' sur l'affectation de P2 dans Capture1Frame (Affectation du Scanline).
Cordialement.
19 juin 2007 à 17:06
Ayant une webcam j'ai pu essayer et ca marche nickel : super code Kénavo ^^.
@+
19 juin 2007 à 16:33
Un peu de boulot pour adapter les structures, mais ça doit être jouable.
@Cirec : Scanline une fois par image ! C'est pas trop, non ? Et j'utilise bien le PByte
(Le PByte est le type d'origine dans la structure retournée par la fonction callback OnFrame ou OnVideoStream, j'ai donc fait avec).
Mais je vais relire avec attention tes commentaires sur la source de l'ami Mauricio.
Ken@vo
19 juin 2007 à 15:00
http://groups.google.fr/group/microsoft.public.win32.programmer.directx.video/browse_thread/thread/804d12a82f91845b/1235096fe6b63e9c?lnk=st&q=change+avi+frame+rate&rnum=1&hl=fr#1235096fe6b63e9c
19 juin 2007 à 14:39
Pour la ligne Pointeur^[iia + 2] := Pointeur^[iia + 2], elle est certes inutile mais ne ralentit pas le calcul car elle n'est pas compilée (pas de point bleu devant). Ceci prouve que delphi fait bien son boulot !
Pour les avi, désolé mais je n'en sais rien.
++
19 juin 2007 à 14:28
@FLORENTH : FreeAndNil ! Bon sang mais c'est bien sûr ! Traces résiduelle d'une utilisation massive de Delphi 4 !
Autre remarque :
dans la transformation des couleur en Sépia, j'anticipe la question : "A quoi sert la première ligne ?" (Ici avec l'optimisation de F0XI)
begin
Pointeur^[iia + 2] := Pointeur^[iia + 2];
Pointeur^[iia + 1] := Pointeur^[iia + 2];
Pointeur^[iia + 0] := TabSepia[Pointeur^[iia + 2]];
end;
La réponse est : elle ne sert à rien !
Mais, cela permet d'essayer la transformation des couleurs en utilisant comme référence de luminosité une des couleurs fondamentales. Ici (iia + 2) utilise le rouge comme référence, mais on peut remplacer à chaque ligne par (iia + 1) ce qui fera du vert la référence ou (iia + 0) qui utilisera le bleu.
Si on veut faire une transformation plus complète à partie de la luminance réelle, il faut calculer celle ci avec la formule bien connue (?!) Y = 0.299R + 0.587G + 0.114B, ce qui évidemment plomberait les calculs.
Autre question : Connaissez vous un moyen simple de modifier la vitesse de lecture d'un AVI ? Cela permettrait de donner le petit air vieillot des films tournés à la manivelle au environ de 18 à 20 images/seconde et qui sont projetés à 25 images/seconde.
19 juin 2007 à 13:42
Et bien verdict: very good job !! On voit bien que les webcam t'inspirent !
Le meilleur dans tout ça: les rayures ! On dirait vraiment que tu as une vielle webcam des années 30 (y'avait des ordis à cette époque ? ^^).
Petite optimisation de l'optimisation de f0xi:
Position := Position + Random( (Stabilite shl 1) + 1) - Stabilite;
if (position < 0) or (position >= a) then
Duree := 1;
Dec(Duree);
if Duree = 0 then
begin
Rayure[i].Free;
Rayure[i] := nil;
end;
devient
Inc(Position, Random( (Stabilite shl 1) + 1) - Stabilite);
if (Duree = 1) or (Position < 0) or (Position >= a) then
FreeAndNil(Rayure[i])
else
Dec(Duree);
A + et continue de nous épater !
19 juin 2007 à 13:31
petite optim :
procedure TForm1.Capture1Frame(Sender: TObject; HndPreview: Cardinal; lpVHdr: PVIDEOHDR);
var
Pointeur, P2: PTabByte;
iia,iib, i, j, a, b, c: integer;
begin
Pointeur := Pointer(lpVHdr^.lpData);
P2 := Bitmap.ScanLine[239];
a := Capture1.Width;
b := Capture1.Height;
if sepia.Checked then
for i := 0 to a - 1 do
for j := 0 to b - 1 do
begin
iia := (j * a + i) * 3;
Pointeur^[iia + 2] := Pointeur^[iia + 2];
Pointeur^[iia + 1] := Pointeur^[iia + 2];
Pointeur^[iia + 0] := TabSepia[Pointeur^[iia + 2]];
end;
if rayures.Checked then
for i := 0 to tbRayures.Position do
if Rayure[i] <> nil then
with Rayure[i] do
begin
for j := 0 to Capture1.Height - 1 do
begin
iia := (j * a + Position) * 3;
Pointeur^[iia] := Pointeur^[iia] shr 1;
Pointeur^[iia + 1] := Pointeur^[iia] shr 1;
Pointeur^[iia + 2] := Pointeur^[iia] shr 1;
end;
Position := Position + Random( (Stabilite shl 1) + 1) - Stabilite;
if (position < 0) or (position >= a) then
Duree := 1;
dec(Duree);
if Duree = 0 then
begin
Rayure[i].Free;
Rayure[i] := nil;
end;
end;
if poussieres.Checked then
for i := 0 to tbPoussiere.Position do
begin
c := Random(a * b);
iia := c * 3;
Pointeur^[iia] := 255;
Pointeur^[iia + 1] := 255;
Pointeur^[iia + 2] := 255;
end;
if Cadre.Checked then
for i := 0 to a - 1 do
for j := 0 to b - 1 do
begin
c := P2^[(j * a + i) * 3];
iia := (j * a + i) * 3;
Pointeur^[iia] := min(Pointeur^[iia] + c, 255);
Pointeur^[iia + 1] := min(Pointeur^[iia + 1] + c, 255);
Pointeur^[iia + 2] := min(Pointeur^[iia + 2] + c, 255);
end;
if sauts.Checked and (saut > 0) then
begin
for i := 0 to a-1 do
for j := b-1 downto saut do
begin
iia := (j * a + i) * 3;
iib := ((j-saut) * a + i) * 3;
Pointeur^[iia] := Pointeur^[iib];
Pointeur^[iia + 1] := Pointeur^[iib + 1];
Pointeur^[iia + 2] := Pointeur^[iib + 2];
end;
Saut := 0;
end;
end;