begin process at 2010 02 09 13:23:07
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C#

 > 

Multimédia

 > 

Image et Vidéo

 > 

Comparaison de bytes d images


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

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

Declarations

dany.

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

Declarations

danyrecoit.

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»

1 2 3

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


Nos sponsors


Appels d'offres

Sondage...

Comparez les prix


HTC Hero

Entre 550€ et 550€

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,983 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales