Цвет пикселей изображения неправильный - PullRequest
0 голосов
/ 23 декабря 2011

Я пытаюсь сравнить 2 изображения с помощью функции сравнения, называемой SAD (сумма квадратов разностей), я беру блок из каждого изображения и преобразовываю пиксели в оттенки серого и выполняю сравнение. но проблема в том, что если я сравниваю два одинаковых блока, результат sad не равен 0 (так что есть разница). Я проверил несколько ящиков сообщений и увидел, что программа возвращает неправильные цвета для пикселей: например, черный пиксель = 255 вместо 0.

вот код моей функции сравнения:

 public double SAD(bloc Bc, bloc Br)
    {
        double sad = 0;
        {
            BitmapData bmp = image1.LockBits(new Rectangle(Bc.x, Bc.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            BitmapData bmp2 = image2.LockBits(new Rectangle(Br.x, Br.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr2 = bmp2.Scan0;
            IntPtr ptr = bmp.Scan0;
            int bytes = bmp.Width * bmp.Height * 3;
            double gris1, gris2;
            byte[] rgb = new byte[bytes];
            byte[] rgb2 = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgb, 0, bytes);
            System.Runtime.InteropServices.Marshal.Copy(ptr2, rgb2, 0, bytes);
            for (int i = 0; i < rgb.Length; i += 3)
            {

                 gris1 = rgb[i] * 0.2989 + rgb[i+1] * 0.5870 + rgb[i+2] * 0.1140;
                 gris2 = rgb2[i] * 0.2989 + rgb2[i + 1] * 0.5870 + rgb2[i + 2] *  0.1140;

                sad = sad + Math.Abs(gris2 - gris1);

            }
            image2.UnlockBits(bmp2);

            image1.UnlockBits(bmp);
        }

        return sad;

    }

Если я не совсем ясно объясню, пожалуйста, скажите мне, чтобы я переформулировал

Заранее большое спасибо за помощь:)

1 Ответ

1 голос
/ 23 декабря 2011

Одной из возможных проблем является неправильное вычисление количества байтов.У вас есть:

int bytes = bmp.Width * bmp.Height * 3;

Но растровые изображения дополняются, как правило, до 4-байтовой границы.Вам необходимо использовать

int bytes = bmp.Stride * bmp.Height;

Stride - это количество байтов, необходимое для представления строки сканирования.Для 24-битного изображения это будет равно 3 * bmp.Width ПЛЮС количество байтов, необходимых для заполнения (которое может быть равно нулю).

Чтобы проиндексировать массив, вы переходите построчноигнорировать заполненные байты.Вы должны инициализировать свой индекс в начале каждой строки.

for (int row = 0; row < bmp.Height; ++row)
{
    int i = row * bmp.Stride;
    for (int p = 0; p < bmp.Width; ++p)
    {
        // do comparisons with rgb[i], rgb[i+1], rgb[i+2]
        i += 3;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...