HectorDuino

Placez ici vos trucs et astuces, étalez sans retenue votre savoir-faire et votre science qui va nous permettre de redonner une apparence neuve et fonctionnelle à nos bouzes.

Modérateurs : Papy.G, fneck, Carl

__sam__
Messages : 7961
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ »

Moi aussi j'ai avast. Bon.. on va pas insister, voici un premier gif rapide:
Image
(j'en mettrais d'autres au fur et à mesure de leur arrivée)
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

Super Merci !

J'ai donc transféré ça sur Hector. C'est encore plus beau en Haute résolution...mais il faut encore que je gagne encore un peu de débit.. (32Ko/sec n'est pas suffisant).J'ai des axes pour ça !
Demain je mettrais une vidéo pour présenter le résultat.

Merci pour la patience.
JJ
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

J'ai profité de 5min pour installer CYGWIN sur mon PC seven du boulot.
Là ça se passe mieux. le seul pb c'est qu'a priori le script ne trouve pas ffmpeg. (j'ai tracé $cpt reste à 1...)
J'ai déplacé le répertoire de ffmpeg dans /home/user/ffmpeg/ (dans lequel on trouve /bin/ffmpeg.exe)

et j'ai modifié le script pour trouver ffmpeg :
open(OUT,"| ./ffmpeg/bin/ffmpeg -i - -v 0 -r $fps -s ${w}x${h} -an tmp/img%05d.bmp");

sans plus de résultat. :oops:
__sam__
Messages : 7961
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ »

Oui il faut mettre ffmpeg.exe "stand-alone" à coté du script (cette version de ffmpeg.exe peut se trouver dans les tout premiers ZIP de video à 120ko/sec). Déplacer les dossiers cygwin n'est pas une super option. Au mieux tu peux faire un lien depuis le dossier du script:

Code : Tout sélectionner

cd <dossier du script perl>
ln -s /usr/bin/ffmpeg.exe ./ffmpeg.exe
Ce soir je vais poster un gros ZIP avec ffmpeg et pleins de GIFS que mon PC va mouliner aujourd'hui et une nouvelle version du script qui donne peut-être de meilleures couleurs (il y a une légère inertie aux changements à présent, ce qui réduit les clignotements).
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

Donc la vidéo en HAUTE RESOLUTION sur Hector (réel, je le rappelle).
L'optimisation ici utilisée consiste à envoyer des trames de 4 octets :
* Offset , octet1,octet2,octet3,octet4
* 0, Adr poids fort, Adr poids faible, octet

Ceci me permettra d'avoir à chaque fois des trames de 4 octets. A terme je ferais une synchro par trame et ensuite les autres octets par timer (comme Daniel) ou encore avec un octet tournant de synchro grâce à l'octet entre Hector => HectorDuino. Mais ça c'est pour un peu plus tard !

(ok, certains auront compté 5 octets pour le 1er type, mais je me suis gouré. J'en ai profité de garder cette configuration pour accentuer la différence avec Offset , octet1 , octet2. mais c'est bel et bien prévu de repasser en 4 octets :wink: )



PS : En fin de vidéo vous avez les comptes pour calculer le débit d'octets.
yves
Messages : 467
Inscription : 12 sept. 2007 21:32

Re: HectorDuino

Message par yves »

vraiment impressionnant la capacité du hector et l'amélioration du programme depuis ton premier post !
Yves
Daniel
Messages : 17397
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: HectorDuino

Message par Daniel »

C'est excellent cette compétition Micronique / Thomson :D
Aujourd'hui Micronique marque un point, mais __sam__ va bientôt relever le défi sur TO8 :wink:

Encore une idée pour le son : s'il y a 6 bits libres en sortie sur un port parallèle, il est possible de faire une extension musique externe pour Hector, comme celle des TO7 et MO5. Il suffit d'un MC14050 et d'une douzaine de résistances.
MC14050.png
MC14050.png (54.79 Kio) Consulté 4525 fois
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

Bha, sam est transfuge et travaille pour les 2 camps...
Merci à lui pour sa contribution.
D'ailleurs, j'ai une remarque : Actuellement je cherche les 4 couleurs dans l'image et je fais un algo qui permet de trouver la palette en 2 temps pour chaque couleur :
* Soit la couleur existait précédemment => je la garde
* Soit il s'agit d'une nouvelle couleur => je remplace celle qui disparaît ( l'une des jusque 4) la plus proche au niveau des composantes RVB.

Ceci pose un problème que l'on voit dans la vidéo ci dessus : les grands aplats blanc qui passent en noir ne sont pas repris sur la même couleur et donc je suis obligé de re-dessiner ensemble de cet aplats.
Serait-il possible de dessiner 1 ligne de plus (en dernier ou premier) avec les 4 première pixels les 4 couleurs à utiliser. Cette palette étant calculée avec le moindre modif possible :
exemple (c'est mieux avec un exemple) :

Soit une image blanche avec un pixel noir au centre.
l'image d'après est une image noir avec un pixel blanc au centre.
la palette passerait de Noir, blanc ,x, y à Blanc, Noir, x,y => rien à dessiner.

Je pense que cet algo doit être assez difficile à créer (désolé :oops: ). Je mettrais peut être ça dans mon encodeur plus tard, plutôt...
[EDIT] Ton idée est plaisante, Daniel. Mais je crains que je préfère travailler sur un Hector non modifié :wink:
__sam__
Messages : 7961
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ »

Oui j'ai constaté la même chose que toi concernant les à-plats blancs sur la vidéo.

Une idée peut-être plus simple: pour les couleurs tu ne te casses pas la tête, tu fais un tri par occurence: la 0 est la couleur la plus fréquente, la 3 la moins fréquente. Ainsi lors du passage d'un écran majoritairement noir à un écran majoritairement blanc, ne se fait que par un jeu de palette avec peu de changements d'octets.

[EDIT]chose promise, donc chose due: http://dl.free.fr/iI9lmYr0e

Mais quelques remarques:
  • une version de ffmpeg.exe sans dépendance est présente dans l'archive
  • A mon avis les démos amiga (En particulier Arte de Sanity) passeront très bien car elles sont très compressibles
  • l'aspect-ratio des videos n'est pas respecté
  • j'ai modifié le script en cours de route (algo et respect du pixel-ratio), donc les videos varient en qualités.
  • Un gros bug fait que les écrans 100% noirs apparaissent 100% verts :-/
  • Je vais refaire les vidéos...
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

Dans un premier temps, il faut que je boost encore le débit entre Hectorduino et Hector... Te tracasse pas trop, là j'ai matière, il y a assez de gif !!!

J'ai testé rapidement et même avec ce ffmpeg, le script (ffmpeg) ne génère pas du tout d'image dans le répertoire tmp...
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

Alors pour obtenir quelque chose, j'ai modifié dans les 1ere ligne l'ouverture de OUT en y indiquant le nom du fichier directement en remplacement du "-" après l'option -i ... comme ceci :

open(OUT,"| ./ffmpeg.exe -i - -v 0 -r $fps -s ${w}x${h} -an tmp/img%05d.bmp");

devient :
open(OUT,"| ./ffmpeg -i bad2.mp4 -v 0 -r $fps -s ${w}x${h} -an tmp/img%05d.bmp");

Là les images sont créées bien créées, puis détruites au fur est à mesure de l'avance du calcul de ffmpeg dans le répertoire tmp, par contre j'ai pas le gif de créé (et j'ai le fichier toto.png qui reste bien sur la dernière image crée !)

-> je n'ai pas vu comment dans ton script tu remplace le "-" par $file, c'est pour ça que j'ai fait cette modification...
peut être :

open(OUT,"| ./ffmpeg -i $file -v 0 -r $fps -s ${w}x${h} -an tmp/img%05d.bmp");

???
(j'ai essayé, ça marche) reste la création du gif!
ça avance :wink:

[EDIT] Avec la même modif le 1er script créé bien le gif ! Là faut que je parte, mais ça sent bon :D
__sam__
Messages : 7961
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ »

J'utilise le principe du "pipe": J'indique à FFMPEG de lire son entrée standard (le fichier "-"), auquel le script envoie régulièrement les données du fichier source. Ceci permet d'avoir un faible nombre de fichiers dans le dossier "tmp" (normalement 1 seul à la fois). Si je ne faisait pas ca, il y aurait des Go de fichiers dans un dossier, et windows n'aime pas trop ca (chez moi ca ralenti tout), en puls de manger inutilement de la place disk.

A la fin du script il faut attendre un peu (beaucoup): la création d'un gif de plusieurs Mo prend beaucoup de temps (compression).
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

ok, mais je lance bien le script avec "perl scrpit.pl bad.mp4" il devrait donc reprendre le "bad.mp4" ?
__sam__
Messages : 7961
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ »

oui. Pour le gif: ca met du temps et consomme un coeur complet. Pendant ce temps tu dois voir que sur disk, le fichier gif est de taille 0.

Au fait: je suis en train d'introduire une mesure "psycho-visuelle" pour mieux trouver la palette et éviter que des couleurs qui certes numériquement plus fréquentes mais visuellement moins logiques soient choisies. Sur le petit gif de la biche ca donne exactement ce que je veux :)
Image
(avant la biche passait au jaune complet au milieu de la séquence)

Les demos passent aussi mieux je trouve
ImageImage
ImageImage

Code : Tout sélectionner

#/bin/perl
# Conversion video en gif 4 couls
#
# Samuel DEVULDER, Sept-Oct 2015.
#

# parametres
($W, $H) = (204, 153); # HR
$fps     = 10;
$dither  = "vac8";
($RED,$GRN,$BLU) = (2,4,1);

# fichier entree
$file    = $ARGV[0];

$out = $file;
$out =~ s/\.[^\.]*$/.gif/;
exit if -e $out;

($x,$y, $aspect_ratio) = (160,100,"16:9");
open(IN, "./ffmpeg -i \"$file\" 2>&1 |");
while(<IN>) {
	if(/, (\d+)x(\d+)/) {
		($x,$y) = ($1, $2);
		# 4:3
		if(abs($x - 4/3*$y) < abs($x - 16/9*$y)) {
			($w,$h,$aspect_ratio) = (133,100,"4:3");
		}
	}
}
close(IN);
$h = int(($w=$W)*$y/$x);
$w = int(($h=$H)*$x/$y) if $h>$H;
print $file," : ${x}x${y} ($aspect_ratio) -> ${w}x${h}\n";

# dossier temporaire
mkdir "tmp";
open(OUT,"| ./ffmpeg -i - -v 0 -r $fps -s ${w}x${h} -an tmp/img%05d.bmp");
open(IN, "<$file");

&init_magick;
$gif = Image::Magick->new(size=>"${w}x${h}");
	
$cpt = 1; my @c = (0)x8;
binmode(IN);
binmode(OUT);
while(1) {
	$name = sprintf("tmp/img%05d.bmp", $cpt);
	
	$expected_size = $h*(($w*3 + 3)&~3) + 54 if !$expected_size;
	if($expected_size != -s $name) {
		# image pas complete: on continue de nourrir ffmpeg
		my $buf;
		my $read = read(IN,$buf,4096);
		last unless $read;
		syswrite OUT, $buf, $read;
	} else  {
		# image complete!
		print STDERR int($cpt++/$fps),"s\r";
		sleep(5) if ($cpt%1200)==0; # on fait une pause régulière pour ne pas surchauffer le processeur
		
		# lecture de l'image
		my $img = Image::Magick->new();
		$img->Read($name);
		unlink $name;
		
		# on force la saturation (140%) pour avoir des couleurs plus franches
		$img->Modulate(saturation=>140);
		$img->Evaluate(operator=>'Multiply', value=>255/245);
		
		my $tmp = Image::Magick->new(size=>"${W}x${H}");
		$tmp->Read("xc:black");
		$tmp->Composite(image=>$img, Operator=>"Over", x=>($W-$w)>>1, y=>($H-$h)>>1);
		undef $img; $img = $tmp;
		my $orig = $img->Clone();

		# trammage
		$img->Set(colorspace=>$LINEAR_SPACE);
		$img->OrderedDither($dither);
		
		if(0) {
			# version R,G,B
			$img=$img->Fx(expression=>"(i+j)%3==0?r:0", channel=>"Red");
			$img=$img->Fx(expression=>"(i+j)%3==1?g:0", channel=>"Green");	
			$img=$img->Fx(expression=>"(i+j)%3==2?b:0", channel=>"Blue");	
		} else {
			# détermination des 4 couleurs les plus fréquentes (histograme + passe-bas)
			my $z = $orig;
			
			if(!defined $gauss) {
				$gauss = Image::Magick->new(size=>"${W}x${H}");
				$gauss->Read("xc:black");
				$gauss=$gauss->Fx(expression=>"exp(-8*(((i-$W/2)/$W)^2 + ((j-$H/2)/$H)^2))", channel=>"All");
				$gauss->Write("gauss.png");
			}
			$z->Composite(image=>$gauss, Compose=>"Multiply", channel=>"All");
			$z->Blur(sigma=>2);
			$z->Set(colorspace=>$LINEAR_SPACE);
			$z->OrderedDither($dither);
			$z->Write("gauss.png");
			
			my @h = $z->Histogram();
			my @H = (0)x8;
			for(my $i=$#h+1; ($i-=5)>=0;) {
				$H[($h[$i]&$RED)|($h[$i+1]&$GRN)|($h[$i+2]&$BLU)] = 
				$h[$i+4];
			}
			my @sf;
			for my $i (0..7) {
				my $t = int($c[$i] = ($c[$i]*0 + 32*$H[$i])/32);
				my $x = $t;	$x |= $x>>1; $x |= $x>>2; $x |= $x>>4; $x |= $x>>8; $x |= $x>>16; ++$x;
				my $y = $x>>4; $x -= $y?$y:1; $t &= $x;
				$sf[$i]=$t*16 + ($i==0?8:$i);
			}
			@h = sort {$sf[$b]<=>$sf[$a]} (0..7);
			# print "\n";
			# for my $i (@h) {
				# print $i, "=>", $sf[$i]>>4, " ",int($c[$i]), " (",$H[$i],")\n";
			# }
			
			
			# construction d'une palette avec ces 4 couleurs
			my $k = join(',', @h[0..3]);
			my $m = $pal{$k};
			if(!defined $m) {
				my(@px);
				for my $c (@h[0..3]) {
					push(@px, ($c&$RED)?255:0, ($c&$GRN)?255:0, ($c&$BLU)?255:0);
				}
				my $tmp = $ENV{'HOME'}."/.toto.pnm";
				open(ZZ,">$tmp");
				print ZZ "P6\n4 1\n255\n", pack('C*',@px),"\n";
				close(ZZ);
				$m = Image::Magick->new();
				$m->Read($tmp);
				unlink($tmp);
				$pal{$k} = $m;
			}
			
			# remping de l'image tramée sur ces 4 couleurs
			$img->Remap(image=>$m, 'dither-method'=>'none');
		}
		$img->Write("toto.png");
		
		# ajout de l'image au gif animé
		$img->Set(dispose=>"None");
		$img->Set(delay=>int(100/$fps));
		push(@$gif, $img);
		
		# pas plus de 3600 imgs (6mins)
		last if $cpt==4200;
	}
}
close(OUT);
unlink(<$ENV{'HOME'}/img*.bmp>);

# ecriture du fichier gif
$gif->Set(dispose=>"None");
$gif->Set(Layers=>"optimize-trans");
$gif->Set(delay=>int(100/$fps));
$gif->Write($out);

sub init_magick {
	# chargement image-magick la 1ere fois
	my($home) = "tmp";
	$ENV{'HOME'} = $home;
	mkdir($home);
	mkdir("$home/.magick");
	open(THR, ">$home/.magick/thresholds.xml");
		
	print THR <<EOF;
		<thresholds>
			<threshold map="2x2">
				<description>2x2 dither matrix</description>
				<levels width="2" height="2" divisor="5">
				1 2
				3 4
				</levels>
			</threshold>
			<threshold map="3x3">
				<description>3x3 dither matrix</description>
				<levels width="3" height="3" divisor="10">
				7 8 2
				6 9 4
				3 5 1
				</levels>
			</threshold>
			<threshold map="5x3">
				<description>5x3 dither matrix</description>
				<levels width="3" height="5" divisor="16">
				 3  9  4
				 8 14 10	
				13 15 11
				 7 12  5
				 2  6  1
				</levels>
			</threshold>			
			<threshold map="vac8">
				<description>void and cluster 65 niveaux</description>
				<levels width="8" height="8" divisor="65">
				35 57 19 55  7 51  4 21
				29  6 41 27 37 17 59 45
				61 15 53 12 62 25 33  9
				23 39 31 49  2 47 13 43
				 3 52  8 22 36 58 20 56
				38 18 60 46 30  5 42 28
				63 26 34 11 64 16 54 10
				14 48  1 44 24 40 32 50
				</levels>
			</threshold>
		</thresholds>
EOF
	close(THR);
		
	eval 'use Image::Magick;';
	
	# determination de l'espace RGB lineaire
	my $img = Image::Magick->new(size=>"256x1", depth=>16);
	$img->Read('gradient:black-white');
	$img->Set(colorspace=>'RGB');
	#$img->Set(colorspace=>"Gray") unless $coul;
	my @px1 = $img->GetPixel(x=>128, y=>0);
	$img->Read('gradient:black-white');
	$img->Set(colorspace=>'sRGB');
	#$img->Set(colorspace=>"Gray") unless $coul;
	my @px2 = $img->GetPixel(x=>128, y=>0);
	my $d1 = $px1[0]-0.5; $d1=-$d1 if $d1<0;
	my $d2 = $px2[0]-0.5; $d2=-$d2 if $d2<0;
	$LINEAR_SPACE = $d1>=$d2 ? "RGB" : "sRGB";
	#print $px1[0], "   ",$px2[0],"    $LINEAR_SPACE\n";
}
ImageImage
ImageImage
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
yo_fr
Messages : 1337
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr »

Alors,
J'ai recopié le répertoire cygwin de mon pc de boulot sur mon pc et maintenant .... c'est fonctionnel sur mon pc !

J'ai malgrès tout les mêmes soucis (ffmpeg => $file et non "-" ainsi que le gif qui ne se crée pas après le traitement, même en laissant du temps (j'avais remarqué qu'il fallait attendre un temps que le gif se constitue avec le script de la 6eme page de ce fil))

Par contre je pense que la HR c'est encore un gros travail d'optimisation pour passer n'importe quoi. J'ai essayé quelques vidéo est c'est pas terrible (les gros changement = gros lag :cry: ). Bref j'ai encore du boulot.


Sinon une vidéo qui passe super bien c'est la biche !
Allez je te la présente :D :D :

Répondre