Метод средней абсолютной разности для проекта стабилизации видео в C ++ / CLI - PullRequest
0 голосов
/ 11 сентября 2010

Я пытаюсь реализовать проект стабилизации видео в C ++ / cli. Прежде всего, у меня есть последовательности изображений bmp, и я нашел векторы движения, которые показывают, насколько конкретная область пикселей перемещается между каждым кадром изображения. Например, у меня есть изображение 256 * 256, я выбрал область 200 * 200 в первом кадре изображения и в кадре второго изображения. И я обнаружил, как много пикселей перемещается между первой областью и второй областью. Когда алгоритм перешел к последнему изображению, программа завершила Работа. В конце концов, я получил векторы движения. Я сделал эту операцию, используя метод абсолютного среднего. Это сработало, но слишком медленно. Мой пример кода приведен здесь, я нашел только один индекс вектора движения (направление x и направление y):

//M:image height =256

//N.image width =256

//BS:block size=218


//selecting and reading first and second image frame



frame = 1;

s1 = "C:\\bike\\" + frame + ".bmp";
image = gcnew System::Drawing::Bitmap(s1, true);

s2 = "C:\\bike\\" + (frame + 1) + ".bmp";
image2 = gcnew System::Drawing::Bitmap(s2, true);

for (b = 0; b < M; b++){
    for (a = 0; a < N; a++)
{
    System::Drawing::Color BitmapColor = image->GetPixel(a, b);
I1[b][a] = (double)((BitmapColor . R * 0.3) + (BitmapColor . G * 0.59) + (BitmapColor . B * 0.11));
}
}

for (b = 0; b < M; b++){
    for (a = 0; a < N; a++)
{
    System::Drawing::Color BitmapColor = image2->GetPixel(a, b);
I2[b][a] = (double)((BitmapColor . R * 0.3) + (BitmapColor . G * 0.59) + (BitmapColor . B * 0.11));
}
}



//finding blocks

a = 0;
for (i = 19; i < 237; i++){
    b = 0;
    for (j = 19; j < 237; j++){

        Blocks[a][b] = I2[i][j];
        b++;
    }
    a++;
}


//finding motion vectors according to the mean absolute differences


//MAD  method

for (m = 0; m < (M - BS); m++){
    for (n = 0; n < (N - BS); n++){

        toplam = 0;
        for (i = 0; i < BS; i++){

            for (j = 0; j < BS; j++){

                toplam += fabs(I1[m + i][n + j] - Blocks[i][j]);


            }
        }


// finding vectors

        if (difference < mindifference) {
            mindifference = difference;
            MV_x = m;
            MV_y = n;
        }


    }
}

Этот пример кода сработал. Но это очень медленно. Мне нужно реализовать оптимизацию кода. Как я могу сделать это, не используя для циклов, например, я делаю индексацию в C ++ / cli, как коды MATLAB (например, I1 (1:20) = 100).

Не могли бы вы помочь мне, пожалуйста?

С наилучшими пожеланиями ...

1 Ответ

0 голосов
/ 13 сентября 2010

Пара вещей, на которые стоит обратить внимание:

Во-первых, циклы в C ++ не медленны по сравнению со встроенными функциями. В MatLab чем меньше операций, тем лучше, поэтому лучше вызывать встроенные функции, которые представляют собой одну операцию, выполняемую с оптимизированным кодом. В C ++ ВАШ код оптимизируется одинаково со встроенными функциями.

Далее GetPixel чрезвычайно медленно. Попробуйте Bitmap.LockBits вместо. По иронии судьбы, это, кажется, противоречит моему предыдущему утверждению, но на самом деле это не потому, что цикл внутри LockBits быстрее, чем вы делаете цикл, а потому, что GetPixel использует другой метод, который намного медленнее.

Как только вы переключитесь на LockBits, вы, вероятно, сможете снова удвоить или утроить вашу скорость, развернув цикл, если компилятор еще этого не делает.

Наконец, убедитесь, что вы правильно используете локальность кэша. Попробуйте оба зацикленных порядка (например, for (a...) for (b...) и for (b...) for (a...)) и измерьте время каждого из них, чтобы выяснить, какой из них быстрее.

...