Porównanie dwóch obrazków c#

0

Siemka!
Jak najszybciej można porównać dwa obrazki jpg? W internecie jest kilka rozwiązań chciałbym jednak poprosić o coś z doświadczenia co polecacie?

0

Zależy co rozumiesz poprzez "porównanie".

0

Sprawdzanie czy są takie same tylko o to mi chodzi. czy jest jakaś inna metoda jak porównywanie po pixelu?

0

Prościej porównywać po bajcie.

0

Pewnie jak dorwiesz jakąś bibliotekę wizyjną, to będziesz mógł określić stopień podobieństwa na podobnej zasadzie jak w obrazach google (wyszukiwanie obrazem).

0

Jest na to dużo sposobów:

  1. Bardzo naiwny:
/// <summary>
/// sprawdzić czy obrazy są dokładnie równe (może być niebezpieczne przy kodowaniu stratnym jak jpg)
/// </summary>
bool Compare(Bitmap fst, Bitmap snd)
{
    if (fst.Width != snd.Width || fst.Height != snd.Height) { 
        // mają różny rozmiar, nie są więc równe
        return false;
    }

    for(int y = 0; y < fst.Height; y++)
        for (int x = 0; x < fst.Width; x++)
        {
            if (fst.GetPixel(x, y) != snd.GetPixel(x, y)) { return false; }
        }

    return true;
}

Czyli zwracamy false jeśli choć jeden piksel się różni.

Można też wyliczać współczynnik podobieństwa:

/// <summary>
/// Oblicza 'współczynnik nierówności'
/// </summary>
/// <returns>Wartość [0; 1], im większa tym bardziej różnią się obrazy (0 = takie same, 1 = negatyw)</returns>
double Compare(Bitmap fst, Bitmap snd)
{
    if (fst.Width != snd.Width || fst.Height != snd.Height)
    {
        // można np. stworzyć kopię drugiego o odpowiedniej wielkości
        // ...albo rzucić wyjątkiem
    }

    long totalDiff;
    for (int y = 0; y < fst.Height; y++)
        for (int x = 0; x < fst.Width; x++)
        {
            var fstPixel = fst.GetPixel(x, y);
            var sndPixel = snd.GetPixel(x, y);
            totalDiff += Math.Abs(fstPixel.R - sndPixel.R) +
                Math.Abs(fstPixel.G - sndPixel.G) +
                Math.Abs(fstPixel.B - sndPixel.B);
        }

    return 1 - (totalDiff / (fst.Width * fst.Height * 256.0 * 3))
}

Obydwa podane sposoby są dość wolne (to raczej nie problem jeśli działasz na jednym tylko obrazie, ale...).

Rozwiązań jest wiele, np. działać na wskaźnikach zamiast wolnych GetPixel - zainteresuj się na przykład http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx

0 użytkowników online, w tym zalogowanych: 0, gości: 0