Accueil > Forum > > > > Comparaison de bytes d images
Comparaison de bytes d images
vendredi 14 mars 2008 à 13:22:04 |
Comparaison de bytes d images

danyclassique
|
Bonjour a tous. J aurai voulu savoir si quelqu un connait une methode pour comparer 2 tableaux de bytes contenant chacun les paquets de bytes d une image exemple: byte[]b //contient une image; byte[]b2 //contient une autre image; puis en extraire la difference qui ensuite sera affichee dans une picturebox Je pense que vous avez compris son sens; Merci d avance;
|
|
vendredi 14 mars 2008 à 17:46:40 |
Re : Comparaison de bytes d images

ShareVB
|
salut,
ca dépend du format de l'image....si tu peux recréer un Bitmap à partir de ton tableau, il y a une solution sinon, il te faut le bon décodeur et ensuite, comparer le résultat "bitmap"...
ShareVB
|
|
samedi 15 mars 2008 à 18:50:19 |
Re : Comparaison de bytes d images

danyclassique
|
En fait j utilise un webservices pour le transport d images entre 2 ordi distants Ces images sont la capture du bureau d un des ordi .
Jusqu a la tout fonctionne mais il y a une repetition de chaque images envoyees y compris ce qu il y avait dans la picturebox de l ordi no2 ce qui est logique puisque le thread de l ordi no1 prend sans arret des captures d images sur lui meme
Le but est qu a l arrivee il y est une comparaison entre l image qui est deja dans la picture box et la nouvelle qui arrive et c est cette differnce que l on afficherai en suivant et si il n y a pas de difference majeure on afficherai rien
A chaque envoies d images j utilise une fonction de convertion d images qui renvoie un tableau de bytes pour chaque transport
private byte [] Convert( Image i, ImageFormat f) { MemoryStream ms = new MemoryStream (); i.Save(ms, f); byte [] bytes = ms.ToArray(); return bytes; } et pour chaque reception d images j utilise une fonction qui reconstitue le flux de bytes en bitmap et c est ce bitmap que j affiche dans le picturebox
private Image Convert( byte [] b) { MemoryStream ms = new MemoryStream (b); Bitmap bm = new Bitmap (ms); return bm; }
Apres reflexion je pense qu il serai mieux pour le programme et plus rapide pour celui ci que le travail de comparaison ce passe a l envoie et non a la recption .
J adapterai cela par la suite.
Desole pour les explications un peut farfelus mais ce bug est difficile a expliquer
Je pense de toute facon que tu as deja compris le problemme.
Merci pour ton aide.
|
|
samedi 15 mars 2008 à 21:16:36 |
Re : Comparaison de bytes d images

ShareVB
|
salut,
donc ce que tu cherches à faire est une sorte de VNC....donc ce ne serait pas qu'une simple comparaison mais plutot un delta dans le genre de ce que font les codecs mpeg4...l'idée est de n'envoyer que les parties de l'image qui changent...
Côté serveur : Tu gardes deux images la précédente et celle en cours Tu fais une comparaison et tu récupéres les zones de différences (sous la forme [(x,y début) (données) (x,y fin)]) Ensuite, tu envois toutes ces zones Côté client : Enfin, dans ton image de destination, tu recopies toutes tes zones...
donc maintenant comment faire tout cela et de préférence rapidement : par le code unsafe...sinon tu as GetPixel mais alors là ca va prendre un moment...
quelque chose comme : BitmapData bmpA = x.LockBits(new Rectangle(Point.Empty, x.Size), ImageLockMode.ReadOnly, x.PixelFormat); BitmapData bmpB = y.LockBits(new Rectangle(Point.Empty, y.Size), ImageLockMode.ReadOnly, y.PixelFormat);
bool ret = true; unsafe { UnmanagedMemoryStream umsA = new UnmanagedMemoryStream((byte*)bmpA.Scan0, (long)bmpA.Stride * bmpA.Height); UnmanagedMemoryStream umsB = new UnmanagedMemoryStream((byte*)bmpB.Scan0, (long)bmpB.Stride * bmpB.Height);
for (int i = 0; i < bmpA.Height;i++) { int s = ((bmpA.Width*3 + 7) / 8); for (int j = 0; j < s; j++) { int bA = umsA.ReadByte() >> 2 + umsA.ReadByte() >> 1 + umsA.ReadByte(); int bB = umsB.ReadByte() >> 2 + umsB.ReadByte() >> 1 + umsB.ReadByte(); //récuérer les zones de différences } } } x.UnlockBits(bmpA); y.UnlockBits(bmpB);
ShareVB
|
|
samedi 15 mars 2008 à 21:47:21 |
Re : Comparaison de bytes d images

danyclassique
|
Exactement . Merci d avoir repondu si vite je vais essayer de mettre ca en route et je te recontact des que je ne recoit que ce qu il faut et pas une repetition d image
A bientot ou peut etre a tout a l heure.
|
|
samedi 15 mars 2008 à 22:20:57 |
Re : Comparaison de bytes d images

danyclassique
|
Je t avoue que je comprend a moitie ton code mais je pense que je n est pas le niveau encore de l adapter sur le mien tu na pas l air d un petit joueur bien au contraire
Bravo pour ces competences
Mais pour en revenir a mon petit niveau je vais t envoyer mon code et peut etre tu pourras me diriger su la direction que j ai deja prise
cote serveur
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.Diagnostics ; namespace CAPTURE{ using dany; using System.Threading; using System.Drawing.Imaging; public partial class Form1 : Form { public Form1(){ InitializeComponent(); } #region Declarationsdany. Service s = new CAPTURE.dany. Service (); ImageFormat imageformat = ImageFormat .Png; Thread t; //Thread t2; IntPtr handle2 = new IntPtr (); IntPtr handle = new IntPtr (); #endregion Declarations #region Dll and Constantes[ DllImport ( "user32.dll" )] private static extern IntPtr GetDesktopWindow();[ DllImport ( "gdi32.dll" )] private static extern bool BitBlt( IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop); private const int SRCCOPY = 0xCC0020; #endregion Dll and Constantes public void CaptureTotale(){ while ( true ){ handle = GetDesktopWindow(); Graphics gScreen = Graphics .FromHwnd(handle); Rectangle r = Screen .PrimaryScreen.Bounds; Bitmap bmpScreen = new Bitmap (r.Width, r.Height); Graphics gBmp = Graphics .FromImage(bmpScreen); IntPtr hDCScreen = gScreen.GetHdc(); IntPtr hDCBmp = gBmp.GetHdc();BitBlt(hDCBmp, 0, 0, r.Width, r.Height, hDCScreen, 0, 0, SRCCOPY); gScreen.ReleaseHdc(hDCScreen); gBmp.ReleaseHdc(hDCBmp); byte [] b = Convert(bmpScreen, imageformat);s.setimage(b); Thread .Sleep(100);} } private byte [] Convert( Image i, ImageFormat f){ MemoryStream ms = new MemoryStream ();i.Save(ms, f); byte [] bytes = ms.ToArray(); return bytes;} private void button1Capture_Click( object sender, EventArgs e){ ThreadStart ts = new ThreadStart (CaptureTotale);t = new Thread (ts);t.Start(); } private void Form1_FormClosed( object sender, FormClosedEventArgs e){ //t2.Abort();//no run if project clientreceive îåøä work just test. t.Abort(); } } }
cote web service
[ WebMethod ] public void setimage( byte [] b){ Application[ "b" ] = b;} [ WebMethod ] public byte [] getimage(){ byte [] b = ( byte [])Application[ "b" ]; return b;}
cote client
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.Collections; using System.Threading; using System.Drawing.Imaging; namespace clientreceive{ public partial class Form1 : Form { public Form1(){ InitializeComponent(); } #region Declarationsdanyrecoit. Service se = new clientreceive.danyrecoit. Service (); Thread t2; #endregion Declarations private void button1receive_Click( object sender, EventArgs e){ ThreadStart ts2 = new ThreadStart (Display);t2 = new Thread (ts2);t2.Start(); } void Display(){ while ( true ){ try { byte [] b = se.getimage(); Image bmp = Convert(b);pictureBox1.Image = bmp; } catch ( Exception ex){ string text = string .Format( "Eception Type:{0}\n\n" + "Message: {1}\n\n" + "Stack Trace: {2}" ,ex.GetType(), ex.Message, ex.StackTrace); //MessageBox.Show(text);--->no run this one bug } } } private Image Convert( byte [] b){ MemoryStream ms = new MemoryStream (b); Bitmap bm = new Bitmap (ms); return bm;} private void Form1_FormClosed( object sender, FormClosedEventArgs e){ t2.Abort(); //no run ->this new instance just test. } } }
Desole pour tout ca mais je suis coince a une repetion de la meme image avec la nouvelle
et notre prof veut que nous employons la technique du bitblt
En tout cas merci et chapeau pour cet algorithme extra
|
|
samedi 15 mars 2008 à 22:43:10 |
Re : Comparaison de bytes d images

ShareVB
|
salut,
euh, il y a plusieurs choses qui me surprennent relativement : -> pourquoi un webservice ? dans ce cas, un service WCF ou plus simplement un socket... -> (plus de l'ordre du détail) le serveur pourrait être une appli console ou un service (bon pour tester c'est un peu moins facile)
pour le reste tu peux intégrer mon code avec le bitmap que tu crées depuis bitblt...
ShareVB
|
|
samedi 15 mars 2008 à 22:48:31 |
Re : Comparaison de bytes d images

danyclassique
|
Je comprend bien ce que tu dis moi j avais suggere au prof par tcp ip comme un chat que nous avions deja mis au point mais il etait pas daccord alors bon!!! ok donc je vais essayer de my mettre merci encore
|
|
samedi 15 mars 2008 à 23:40:43 |
Re : Comparaison de bytes d images

danyclassique
|
Ou la la
Je t avoue que je suis en plein cassement de tete je n arrive pas tres bien a adapter ton code au mien pour mieux dire je n est jamais utilise la technique dangereuse qui elle meme utilise les pointeurs
Je suis completement coince mais le pire c est qu il n y a pas beaucoup de monde qui arrivent a me repondre a par toi pour l instant
pourrai tu peut etre me dirriger dans l insertion de ton code ce qui pourrai m aider pour mieux le comprendre quand je le ferai tourner pas a pas
|
|
dimanche 16 mars 2008 à 15:17:06 |
Re : Comparaison de bytes d images

taupe4
|
Je ne te conseille pas les images PNG. Dans ton cas, et avec la méthode que tu désires utiliser (la méthode des différences), utiliser des PNG ralentira le processus (bah oui coder une image en PNG c'est forcément plus long qu'en BMP.
Pour une performance optimale, j'irais même à te recommander les BMP 32 bit, si tu utilises la méthode des différences. Car, dans ce cas, tout peut se faire très rapidement et efficacement.
Et le code donné par ShareVB ne fonctionnera pas. En premier lieu, l'utilisation de SHR (>>) au lieu de SHL (<<), qui créera un truc incohérenct. En second lieu, le non-respect de l'endianness.
Le code suivant contient des commentaires pour t'aider à comprendre comment faire l'opération relativement efficacement. Car les logiciels de type VNC utilisent une méthode encore plus efficace: ils créent un pilote de carte vidéo virtuel (qui sous-traite la production au vrai pilote) et peuvent donc obtenir tout changement en temps réel, et ce sans avoir à obtenir une image complète continuellement. //Modifier le VOID. static unsafe void GetDifferences(Bitmap a, Bitmap b) { //On obtient la surface de travail des Bitmaps. Cela permet de traiter directement leurs pixels. //On prétend ici que les deux images ont la même taille. Rectangle surfaceTravail = new Rectangle(Point.Empty, a.Size); BitmapData bmpA = a.LockBits(surfaceTravail, ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); BitmapData bmpB = b.LockBits(surfaceTravail, ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); //Nous permet de "voir" deux couleurs. int* couleurA, couleurB; int difference; //Ici on dit que notre pointeur (visionneur) est au début des deux bitmaps couleurA = (int*)bmpA.Scan0; couleurB = (int*)bmpB.Scan0;
for(int y = 0; y < surfaceTravail.Height; y++) { for(int x = 0; x < surfaceTravail.Width; x++) { //On calcul la différence entre la couleur B et la couleur A. Pour récupérer la couleur B, il faudra donc ajouter la couleur A. //De plus, on passe à la couleur suivante grâce au ++. C'est l'arithmétique des pointeurs qui fait que cela fonctionne. difference = (*couleurB++) - (*couleurA++); //Faire quelque chose avec cette différence. Par exemple, enregistrer (x,y, difference) et l'envoyer. throw new NotImplementedException("Il ne se passe rien avec la différence"); } } } Ce code est fonctionnel à trois conditions: 1. Les deux images doivent avoir la même taille 2. Les deux images doivent avoir un format 32 bpp X8R8G8B8 (soit 8 bit par canal de couleur plus un canal 8bit inutilisé). Cela permet d'utiliser l'arithmétique de pointeur sur les entiers (int*) qui est plus efficace que celle sur les images 24bit R8G8B8 (de plus il n'y a pas de stride trop grand et le processeur est optimisé pour un traitement 32bit). Pour que ça prenne moins de place tu pourais prendre le 16 bit R5G6B5 ou X1R5G5B5. Mais là tu serais limité à 65536 couleurs pour le R5G6B5 et 32768 couleurs pour le X1R5G5B5.
Mais il manque à ce code la partie qui gère les différences. On l'obtient, oui, mais on ne fait strictement rien avec.
Le truc le moins compréhensible du code est (*couleurB++). Cela veut dire "Je veux voir la couleur où est couleurB puis je veux que couleurB représente la couleur du pixel suivant". Ce code est strictement équivalent à: difference = *couleurB - *couleurA; couleurB++; couleurA++;
Si tu as des questions, pose-les . Pour quelqu'un du monde C# les pointeurs ça peut venir compliquer d'un cran les codes.
«L'erreur est humaine mais un véritable désastre nécessite un ordinateur.» «Selon les derniers chiffres, 43 % des statistiques sont fausses»
|
|
Cette discussion est classée dans : images, contient, comparaison, byte, bytes
Répondre à ce message
Sujets en rapport avec ce message
Comparaison de deux System.Byte[] en C# [ par sabrinaset ]
Salut,Comment est-ce que je peux comparer rapidement deux tableaux de byte?Merci pour vos réponses
int to byte[] [ par Sobieski ]
Bonjour,Je cherche à envoyer un tableau de bytes, mais j'ai des valeurs en int. J'aimerais savoir comment faire d'un int un tableau de bytes (byte[]).
Multiplication bytes [ par clubberzZ ]
Bonjour à tous,J'éxplique mon problème, je souhaiterais faire une multiplication de byte par un chiffre (une variable que je récupère auparavant) :byt
comparaison de fonds d'images [ par masmoudiimen ]
bonjour,j'ai besoin de tester si deux images ont le même fond ou pasest ce que quelqu'un peut m'aider à trouver un algorithme qui me permet de faire ç
comparaison de byte array [ par olibara ]
BonjourA part faire une boucle existe-t-il une methode de comparaison de deux byte array ?
Changer la dimension d'un byte array [ par olibara ]
Bonjour, J'ai l'habitude de manipuler des tableaux en C mais csharp me fait des caprices Je veux dimensionner un tableau de 5 byte et fixer cette
Une p'tite colle ! [ par sebmafate ]
Dans le code suivant, pourquoi ai-je une boucle infinie ?byte[] bytes = new bytes[256];for (byte i=0; i bytes[i] = (byte)(255 - i);}<A href="h
SoS ImageList + ListView [ par petitelarve ]
Kelkun saurait comment utiliser ImageList dans une ListView ??? Je veux juste afficher les items avec petites photo ... Le codes qui pour l'instant ne
Remplir un comboBox avec un ArrayList [ par francesdereve ]
mais avec la methode qui contient le combobox en parametre cela a marcheCela correspond à ma demarche,mon probleme c'etait le OdbcDataReader car quand
Livres en rapport
|
Derniers Blogs
TECHDAYS PARIS 2010 : PLAN DE MIGRATION VERS SHAREPOINT 2010TECHDAYS PARIS 2010 : PLAN DE MIGRATION VERS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Arnault Nouvel et Antoine Dongois Le processus à prendre : Apprendre (découvrir la plateforme) Préparer (documenter l'historique et choisir la méthode de MAJ) Test (Test de MAJ) Implémenter (Effectuer la MAJ) Valid...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2010 : LA PLEINIèRE DU SECOND JOURTECHDAYS PARIS 2010 : LA PLEINIèRE DU SECOND JOUR par ROMELARD Fabrice
Après un retour sur l'histoire des TechDays de Paris et le fait que ce soit le plus gros event MS au monde (du fait de sa gratuité), le président de MS France (Eric Boustoullier) a fait une présentation de la vision Microsoft pour les années à venir...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice CRéATION D'UNE BASE DE DONNéE SOUS SQL AZURECRéATION D'UNE BASE DE DONNéE SOUS SQL AZURE par junarnoalg
Sans rentrer dans les détails, je me propose ici de faire un rapide tour de ce que propose SQL Azure.
SQL Azure est avant tout un service d'hébergement de base de données relationnelles construit sur SQL Server. Il permet aux entreprises d...
Cliquez pour lire la suite de l'article par junarnoalg TECHDAYS PARIS 2010 : LES SERVICES D'APPLICATIONS DANS SHAREPOINT 2010TECHDAYS PARIS 2010 : LES SERVICES D'APPLICATIONS DANS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Xavier Moreels et Julien Bakmezdjian Ce sujet est lié au partage des applications comme services dans SharePoint 2010, ceci représente la possibilité de créer sa propre application qui sera utilisable comme ceux en standard : Search...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
Comparez les prix

HTC Hero
Entre 550€ et 550€
|