Форум программистов, компьютерный форум CyberForum.ru

Работа с большим объемом данных - C++

Восстановить пароль Регистрация
 
petrov522
1 / 1 / 0
Регистрация: 12.12.2009
Сообщений: 26
26.05.2016, 10:57     Работа с большим объемом данных #1
Имеется загруженное изоображение с помощью opencv.
Задача: вывести цвета изображения с из колличеством.
Цвет задаю структурой, хранящей 3 int, RGB соответственно.
Цвета считаются одинаковыми, если евклидовое расстояние между ними меньше eps.
Все пиксели загоняю в map, выводится примерно 200 тыс цветов с их колличеством.
Вопрос: как учесть цвета с помощью евклидового расстояния в этом map?

Добавлено через 10 часов 15 минут
Вот структура:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
struct ObjColor
{
    int B;
    int G;
    int R;
 
    bool operator< (const ObjColor& other) const
    {   
        //double dist = sqrt((this->B - other.B)*(this->B - other.B) + (this->G - other.G)*(this->G - other.G) + (this->R - other.R)*(this->R - other.R));
 
        //if (dist>30)
        {
            // сортировка идет от меньшего к большему
            if (this->B < other.B)
            {
                return true;
            }
            if (this->B == other.B)
            {
                if (this->G < other.G)
                {
                    return true;
                }
                if (this->G == other.G)
                {
                    return (this->R < other.R);
                }
            }
        }       
        return false;
    }       
 
};
Ее записываю в map:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
map<ObjColor, double> Class1::CountMyColor(IplImage *Image)
{
    map <ObjColor, double> color;
 
    ObjColor temp;
 
    for (int y = 0; y < image->height; y += 1) {
        uchar* ptr = (uchar*)(image->imageData + y * image->widthStep);
        for (int x = 0; x < image->width; x++) {
            temp.B = ptr[3 * x];
            temp.G = ptr[3 * x + 1];
            temp.R = ptr[3 * x + 2];
            color[temp]++;
        }
 
    }
    return color;
}
Теперь из множества ключей map. Надо отобрать те, расстояние, между которыми < eps, и слить в один цвет, с подсчетом общего количества пикселей для слитого цвета.

Расстояние определяется по формуле:
D := SQRT ((R2-R1)^2+(G2-G1)^2+(B2-B1)^2)
Как это лучше сделать? Думал, перегрузить у структуры < таким образом, чтобы считалось автоматически. Возможно ли это? В закомментированном коде структуры пробовал это.

Или может лучше записывать изначально в unordered_map и там перегружать ==, но не знаю, как записать вычисление хэш функции в этом случае.

Или попросту в массиве это вычислить. Подскажите, как тогда. Что-то результаты не очень((
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,230
26.05.2016, 13:48     Работа с большим объемом данных #2
petrov522, подсчет расстояния обязателен или оценку близости можно взять в виде модуля разности всех компонентов менее заданной точности? это снизило бы сложность и дало бы возможность заменить все это дело кубической решеткой

Добавлено через 1 минуту
как вариант - в начале загнать все счетчики настоящих цветов в куб в узлах которого будут списки счетчиков настоящих цветов построенный на решетке с шагом 2 * eps / sqrt(3) что бы могло захватить диагональные цвета. потом пробежать по всем узлам куба и объединить цвета с дистанцией менее eps лежащие в одном списке. цвет получаемый после объединения вычислять с использованием веса настоящего цвета равного его счетчику. из за дрейфа цвета получаемого после объединения возможно придется повторять эту процедуру до тех пор пока слияние не прекратиться. кроме того дрейф приводит к тому что решение будет чувствительно к точке из которой начинается перебор

Добавлено через 3 минуты
поэтому я склоняюсь к тому что бы не использовать дистанцию а просто делать куб на сетке 2 * eps
petrov522
1 / 1 / 0
Регистрация: 12.12.2009
Сообщений: 26
29.05.2016, 20:47  [ТС]     Работа с большим объемом данных #3
Интересная идея. Спасибо!! Вот все думал, и над этой идеей, и способами. Пока сделал более простой способ. Свел все имебщиеся цвета к цветам заданным таблицей.
vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,230
29.05.2016, 20:59     Работа с большим объемом данных #4
petrov522, как?
petrov522
1 / 1 / 0
Регистрация: 12.12.2009
Сообщений: 26
31.05.2016, 00:26  [ТС]     Работа с большим объемом данных #5
vxg, задал цвета (в инете можно взять, например, таблицу html цветов, их 216), загнал в массив.
Далее прохожусь по значениям пикселей изображения. Считаем по формуле расстояние между цветами и выбираем табличный цвет для пикселя изоображения с минимальным расстоянием.

Добавлено через 3 минуты
В данном случае может получится, что цвет пикселя сильно не похож на табличный, т.к. табличных цветов не хватает для охвата. В этом случае можно ввести eps, и если минимальное расстояние до табличного цвета больше eps, то либо не относим его к табличным, либо его самого вносим в таблицу.
Yandex
Объявления
31.05.2016, 00:26     Работа с большим объемом данных
Ответ Создать тему
Опции темы

Текущее время: 23:19. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru