Простой алгоритм сопоставления блоков для машинного зрения - PullRequest
0 голосов
/ 06 октября 2019

Я делаю простой алгоритм сопоставления блоков для расчета карты диспаратности между двумя изображениями. Результаты выглядят ужасно, хотя.

По сути, мой алгоритм сначала вычисляет сумму значений (0-255) в блоке вокруг каждого пикселя в двух серых изображениях (возвращаемое значение без знака является кодом ошибки, который я еще не реализовал, 0для успеха):

unsigned Vision::calc_block_sums(
    const Flattened2DArray<unsigned char>& left_img, 
    const Flattened2DArray<unsigned char>& right_img, 
    Flattened2DArray<int>& left_block_sums,  //out
    Flattened2DArray<int>& right_block_sums, //out
    int block_size)
{
    int half_block_size = block_size / 2;
    for (int center_x = 0; center_x < left_img.width(); center_x++) {
        for (int center_y = 0; center_y < left_img.height(); center_y++) {

            int left_block_sum = 0;
            int right_block_sum = 0;

            int start_x = center_x - half_block_size;
            if (start_x < 0) {
                start_x = 0;
            }           
            int end_x = center_x + half_block_size;
            if (end_x >= left_img.width()) {
                end_x = left_img.width();
            }
            int start_y = center_y - half_block_size;
            if (start_y < 0) {
                start_y = 0;
            }
            int end_y = center_y + half_block_size;
            if (end_y >= left_img.height()) {
                end_y = left_img.height();
            }

            for (int x = start_x; x < end_x; x++) {
                for (int y = start_y; y < end_y; y++) {     
                    left_block_sum += left_img(x, y);
                    right_block_sum += right_img(x, y);
                }
            }
            left_block_sums.set(center_x, center_y, left_block_sum);
            right_block_sums.set(center_x, center_y, right_block_sum);
        }
    }
    return 0;
}

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

unsigned Vision::calc_disp_map(
    const Flattened2DArray<int>& left_block_sums, 
    const Flattened2DArray<int>& right_block_sums, 
    Flattened2DArray<unsigned char>& disp_map, //out
    int block_size, 
    int search_length)
{
    for (int x = 0; x < disp_map.width(); x++) {
        for (int y = 0; y < disp_map.height(); y++) {
            int min_distance = 0;
            int lowest_diff = -1;
            for (int i = 0; i < search_length; i++) {
                int target_x = x + (i - search_length / 2);
                if (target_x < 0) {
                    target_x = 0;
                }
                else if (target_x >= right_block_sums.width()) {
                    target_x = right_block_sums.width() - 1;
                }
                int diff = abs(left_block_sums(x, y) - right_block_sums(target_x, y));
                if (lowest_diff == -1 || diff < lowest_diff) {
                    lowest_diff = diff;
                    min_distance = i;
                }
            }
            unsigned char disparity = ((float)min_distance / search_length) * 255;
            disp_map.set(x, y, disparity);
        }
    }
    return 0;
}

left_img:

enter image description here

right_img:

enter image description here

Результат создания изображения png из переменной disp_map с помощью block_size = 15 и search_len = 50:

Result using block_size=15, search_len=50

Желаемые результаты (эта карта диспаратности не в серой шкале, как у меня, но функции должны выглядеть аналогично):

enter image description here

Я понимаю, что ошибка может быть в коде, который я не опубликовал, но, чтобы сохранить исходное сообщение коротким, я думаю, что лучше всего начать с методов, которые выполняют важные части алгоритма, и если они не являются проблемой, переходите к другимcode.

В настоящее время я смотрю этот учебник. Спасибо за любую помощь, спасибо.

...