Bilddifferenzen erkennen



  • Hallo Leute,

    ich interessiere mich für das Vergelichen von Bitmaps.
    Könnt ihr mir sagen wie ich dabei vorgehe? Gibt es dafür
    evtl. bereits spezielle Klassen oder Funktionen, die das
    etwas erleichtern?

    Danke
    JJay



  • geht es hier um den Pixelweisen vergleich oder um Objekt-, Kantenerkennung etc.?



  • Pixelweis reicht vollkommen! 🙂



  • Das habe ich schonmal gemacht, leider hab ich wohl die Source nicht mehr 😞
    Aber im Prinzip ganz einfach:
    - beide Bitmaps laden (vom Dateisystem mit LoadImage)
    - mit GetObject die BITMAP Struktur auslesen
    - in 2 Schleifen die Pixelwerte vergleichen

    Ich hab die abweichenden Pixel in eine neue Bitmap abgelegt und abgespeichert.
    So konnte man die Unterschiede schön sehen...

    EDIT: vielleicht kann man auch irgendwelche Graphic-Libs nehmen, das war jetzt reine WinAPI



  • Das wra zwra nicht der echte JJay 😉 aber recht hat er.
    Pixelweise reicht. Ich möchte gerne die Bilddifferenzen
    erkennen.

    Ist das sowas wie die Daten in ein Array packen und dann
    vergleichen?



  • Naja .. wie Airdamm schon sagt ... du füllst erst die BITMAP struct und vergleichst dann ihren Inhalt ...



  • Hi, hab mich mal kurz dran gesetzt und was gebastelt...sollte funktionieren:

    // SBitmapCmpInfo speichert die Ergebnisse des Vergleichs.
    struct SBitmapCmpInfo
    {
    	bool fSizeCmp;
    	bool fBitsPixelCmp;
    	bool fColorCmp;
    };
    
    /*
    CompareBitmaps:
    ~~~~~~~~~~~~~~~
    Vergleicht zwei Bitmaps auf folgende Merkmale:
        1. Größe (fSizeCmp)
        2. Farbtiefe (fBitsPixelCmp)
        3. Farben (fColorCmp)
    Diese Vergleichsinformationen werden in der SBitmapCmpInfo-Struktur abgelegt
    (Übergabe per Referenz wg. Performance).
    
    Parameter:
    ~~~~~~~~~~
    Typ               Variable:         Erklärung:
    -----------------------------------------------------------------------------
    HBITMAP        hbmpSrc:        1. zu vergleichende Bitmap
    HBITMAP        hbmpCmp:        2. zu vergleichende Bitmap
    SBitmapCmpInfo bciData:        Ergebnisse des Vergleichs
    bool           fReleaseHandle: Bei Angabe von 'true' werden die Bitmap-Handle in der Funktion freigeben.
    */
    
    bool CompareBitmaps(HBITMAP hbmpSrc, HBITMAP hbmpCmp, SBitmapCmpInfo& bciData, bool fReleaseHandle = false)
    {
    	if(hbmpSrc == NULL || hbmpSrc == NULL)
    	{
    		memset(&bciData, false, sizeof(SBitmapCmpInfo));
    		return (false);
    	}
    
    	BITMAP	bmInfoSrc,
    			bmInfoCmp;
    	HDC		hdcMemSrc,
    			hdcMemCmp;
    	HBITMAP	hbmpPrevSrc,
    			hbmpPrevCmp;
    
    	memset(&bciData, true, sizeof(SBitmapCmpInfo));
    
    	GetObject(hbmpSrc, sizeof(BITMAP), &bmInfoSrc);
    	GetObject(hbmpCmp, sizeof(BITMAP), &bmInfoCmp);
    
    	if(bmInfoSrc.bmBitsPixel != bmInfoCmp.bmBitsPixel)
    		bciData.fBitsPixelCmp = false;
    
    	hdcMemSrc	= CreateCompatibleDC(NULL);
    	hdcMemCmp	= CreateCompatibleDC(NULL);
    	hbmpPrevSrc	= reinterpret_cast<HBITMAP>(SelectObject(hdcMemSrc, hbmpSrc));
    	hbmpPrevCmp	= reinterpret_cast<HBITMAP>(SelectObject(hdcMemCmp, hbmpCmp));
    
    	if(bmInfoSrc.bmHeight != bmInfoCmp.bmHeight ||
    	   bmInfoSrc.bmWidth  != bmInfoCmp.bmWidth)
    	{
    		bciData.fSizeCmp  = false;
    
    		long lOffsetWidth,
    			 lOffsetHeight;
    		if(bmInfoSrc.bmWidth > bmInfoCmp.bmWidth)
    			lOffsetWidth = bmInfoCmp.bmWidth;
    		else
    			lOffsetWidth = bmInfoSrc.bmWidth;
    		if(bmInfoSrc.bmHeight > bmInfoCmp.bmHeight)
    			lOffsetHeight = bmInfoCmp.bmHeight;
    		else
    			lOffsetHeight = bmInfoSrc.bmHeight;
    
    		for(long lXPos = 0L; lXPos < lOffsetHeight; lXPos++)
    		{
    			for(long lYPos = 0L; lYPos < lOffsetWidth; lYPos++)
    			{
    				if(GetPixel(hdcMemSrc, lXPos, lYPos) != GetPixel(hdcMemCmp, lXPos, lYPos))
    				{
    					bciData.fColorCmp = false;
    					break;				
    				}
    			}
    			if(!bciData.fColorCmp)
    					break;
    		}
    
    		SelectObject(hdcMemSrc, hbmpPrevSrc);
    		SelectObject(hdcMemCmp, hbmpPrevSrc);
    		DeleteDC(hdcMemSrc);
    		DeleteDC(hdcMemCmp);
    		if(fReleaseHandle)
    		{
    			DeleteObject(hbmpSrc);
    			DeleteObject(hbmpCmp);
    		}
    		return (true);
    	}
    
    	for(long lXPos = 0L; lXPos < bmInfoSrc.bmHeight; lXPos++)
    	{
    		for(long lYPos = 0L; lYPos < bmInfoSrc.bmWidth; lYPos++)
    		{
    			if(GetPixel(hdcMemSrc, lXPos, lYPos) != GetPixel(hdcMemCmp, lXPos, lYPos))
    			{
    				bciData.fColorCmp = false;
    				break;				
    			}
    		}
    		if(!bciData.fColorCmp)
    				break;
    	}
    
    	SelectObject(hdcMemSrc, hbmpPrevSrc);
    	SelectObject(hdcMemCmp, hbmpPrevSrc);
    	DeleteDC(hdcMemSrc);
    	DeleteDC(hdcMemCmp);
    	if(fReleaseHandle)
    	{
    		DeleteObject(hbmpSrc);
    		DeleteObject(hbmpCmp);
    	}
    	return (true);
    }
    

    Hinweis:
    Sollte die Größe (Breite und Höhe) nicht gleich sein, vergleicht die Funktion die noch verbleibenden Pixel
    auf Farbübereinstimmung.

    PS: Sry aber zu Kommentaren konnte ich mich nit mehr druchwringen, sollte aber verständlich sein 😉 .


Anmelden zum Antworten