Russian Qt Forum

Программирование => Алгоритмы => Тема начата: m_ax от Октябрь 21, 2020, 17:36



Название: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 17:36
Всем доброго времени суток, камрады!

Задача такая:
Имеется матрица пикселей: каждый пиксель имеет свои координаты (x, y) и значение (R, G, B). Причём большинство пикселей "битые",
пусть для определённости, 95% всех пикселей нерабочие, и мы можем работать только с оставшимися 5% "живых" пикселей. Живые пиксели
равновероятно распределены по всей матрице и мы знаем их координаты (x, y).
Вопрос: как на основе "живых" пикселей наиболее "корректно" восстановить всё изображение?

Я не специалист в этом вопросе и не знаю какие сейчас существуют наиболее топовые алгоритмы, которые эту проблему решают.
Буду благодарен за комментарии, предложения и возможные направления)

Заранее спасибо)  





Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 21, 2020, 17:38
Сейчас нейросети картины дорисовывают... :) Вот я бы опять в эту сторону смотрел.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 17:45
Сейчас нейросети картины дорисовывают... :) Вот я бы опять в эту сторону смотрел.


Пожалуй, да) Это, как я понимаю, проблема классификации.. Входные данные это 2D вектор (x, y), а выходной - 3D (R, G, B).
 


Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 21, 2020, 19:07
Входные данные это 2D вектор (x, y), а выходной - 3D (R, G, B).
Да тут огромный простор для экспериментов. :)
Я бы тренировал сеть показывая исходную картинку (где все битые пиксели заменялись [0, 0, 0]), а в качестве правильного ответа показывал бы валидную картинку.
 


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 19:17
Входные данные это 2D вектор (x, y), а выходной - 3D (R, G, B).
Да тут огромный простор для экспериментов. :)
Я бы тренировал сеть показывая исходную картинку (где все битые пиксели заменялись [0, 0, 0]), а в качестве правильного ответа показывал бы валидную картинку.
 

А что значит валидная картинка? У меня условно только 5% живых пикселей, случайно распределённых по матрице)


Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 21, 2020, 19:21
А что значит валидная картинка? У меня условно только 5% живых пикселей, случайно распределённых по матрице)
Ну сеть то нужно вначале натренировать, поэтому понадобяться некие исходные картинки. Дальше мы берем хорошую картинку, убиваем по определенным правилам 95% и отдаем эту пару сети. И там 100500 разных картинок. :)
А потом при запросе мы даем сети битую картинку, а она нам восстановленную (на ее взгляд). :)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 19:41
А что значит валидная картинка? У меня условно только 5% живых пикселей, случайно распределённых по матрице)
Ну сеть то нужно вначале натренировать, поэтому понадобяться некие исходные картинки. Дальше мы берем хорошую картинку, убиваем по определенным правилам 95% и отдаем эту пару сети. И там 100500 разных картинок. :)
А потом при запросе мы даем сети битую картинку, а она нам восстановленную (на ее взгляд). :)

Так, хорошо, идею понял.. :)
Но мне не совсем очевидно следующее:
Пусть у нас есть 100500 валидных картинок, одинаковой размерности (соответствующих размерности нашей восстанавливаемой) с одинаковым набором живых пикселей.
Нейросеть выцепляет некоторые корреляции между координатами живых пикселей с их значениями (R, G, B).
Мне не очевидно, почему обученная сеть, на основе "левых" вылидных картинок, сможет восстановить конкретно совершенно другую картинку?


Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 21, 2020, 19:57
Мне не очевидно, почему обученная сеть, на основе "левых" вылидных картинок, сможет восстановить конкретно совершенно другую картинку?
Конечно, другую картинку она не восстановит. :)
Если сеть тренировать на пейзажах, а потом показать ей "убитого" робота, то она из него пейзаж и восстановит. :)
Я думал у вас некий определенный набор картинок будет.
А так натренировать сеть на всё-всё-всё врядли получится. :)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 20:11
Мне не очевидно, почему обученная сеть, на основе "левых" вылидных картинок, сможет восстановить конкретно совершенно другую картинку?
Конечно, другую картинку она не восстановит. :)
Если сеть тренировать на пейзажах, а потом показать ей "убитого" робота, то она из него пейзаж и восстановит. :)
Я думал у вас некий определенный набор картинок будет.
А так натренировать сеть на всё-всё-всё врядли получится. :)

Мне не очевидно, почему обученная сеть, на основе "левых" вылидных картинок, сможет восстановить конкретно совершенно другую картинку?
Конечно, другую картинку она не восстановит. :)
Если сеть тренировать на пейзажах, а потом показать ей "убитого" робота, то она из него пейзаж и восстановит. :)
Я думал у вас некий определенный набор картинок будет.
А так натренировать сеть на всё-всё-всё врядли получится. :)

Вот  :)
Я немного слукавил - у меня уже есть решение этой проблемы, правда не без своих минусов.. Хотел просто сравнить разные подходы.
И да, моё решение - это именно machine learning  :)

Вот в аттаче  https://dropmefiles.com.ua/ru/LANZ8Q6mxD (https://dropmefiles.com.ua/ru/LANZ8Q6mxD) прикрепляю архив с картинками - оригинальными и восстановленными на основе 5% случайных пикселей :)
Ну, как вам?  :)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 20:22
Вот исходники для двух примеров. Во втором примере нужно png картинку в корень положить (example2) с именем "photo.png" + boost::gil,
а в первом примере нужно иметь установленный gnuplot http://www.gnuplot.info/ (http://www.gnuplot.info/) )


Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 21, 2020, 20:27
Ну, как вам?  :)
Шикарно.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 21:13
Прошу прощения: перепутал example1 с example2... Исправил..


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 21, 2020, 22:13
Ну, как вам?  :)
Шикарно.

Вы знаете, я сравнивал с классической нейросетью (tiny_dnn) в плане обучения её по времени.. Так вот (не исключаю, что у меня руки не из того места растут) она в статистическом плане всегда проигрывает vanda-е..Т.е. время обучения  у неё нереально большое..(


Название: Re: Восстановление изображения
Отправлено: qate от Октябрь 22, 2020, 00:13
нужно png картинку в корень положить (example2) с именем "photo.png" + boost::gil,

как посмотреть на картинку, от которой осталось 5% из исходной ?
boost::gil не знаю - как сохранить не соображу


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 22, 2020, 06:41
нужно png картинку в корень положить (example2) с именем "photo.png" + boost::gil,

как посмотреть на картинку, от которой осталось 5% из исходной ?
boost::gil не знаю - как сохранить не соображу

Да и не нужно на неё смотреть.. Просто берёте png картинку, называете её photo.png и кидаете её в папочку example2...
boost::gil - это Generic Image Library - библиотека для работы с изображениями)


Название: Re: Восстановление изображения
Отправлено: qate от Октябрь 22, 2020, 11:14
Да и не нужно на неё смотреть..

хочется понять из какого изображения получается восстановление


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 22, 2020, 12:10
хочется понять из какого изображения получается восстановление
И мне, присоединяюсь

Задача такая:
Имеется матрица пикселей: каждый пиксель имеет свои координаты (x, y) и значение (R, G, B). Причём большинство пикселей "битые",
пусть для определённости, 95% всех пикселей нерабочие, и мы можем работать только с оставшимися 5% "живых" пикселей. Живые пиксели
равновероятно распределены по всей матрице и мы знаем их координаты (x, y).
Вопрос: как на основе "живых" пикселей наиболее "корректно" восстановить всё изображение?
Ну если знаем какие "живые" а какие "битые" - то все не так уж плохо. Разумеется вещь известная и поиски готового решения здесь к месту. Но и великом здесь неплохо - просто триангуляция (по Борису Николаевичу), а дальше дело сводится к тому самому "закрашиванию треугольника" (от которого научный работник воротил нос)



Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 22, 2020, 13:35
Цитировать
хочется понять из какого изображения получается восстановление

Цитировать
И мне, присоединяюсь

Хорошо, представим такую модельную ситуацию, что представлена в exapmple2:
У нас есть оригинальное изображение (W*H) пикселей. Мы его загружаем
Код
C++ (Qt)
   boost::gil::rgb8_image_t img;
   boost::gil::read_image("photo.png", img, boost::gil::png_tag());
   boost::gil::rgb8_view_t view = boost::gil::view(img);
 
И далее говорим, что нам доступны только 5% пикселей
(равновероятно распределённых, но в то же время мы знаем их координаты и значения R G B для каждого такого пикселя)
от общего их числа W*H.
В example2 это моделируется с помощью случайных чисел:
Код
C++ (Qt)
std::random_device rd;
   std::mt19937 gen(rd());
 
   std::uniform_int_distribution<size_t> dist_x(0, view.width()-1);
   std::uniform_int_distribution<size_t> dist_y(0, view.height()-1);
 
   specmath::compsci::vanda vanda;
 
   auto start = std::chrono::high_resolution_clock::now();
 
   for (size_t i = 0; i < TRAINING_SIZE; ++i)
   {
       /* choose random pixel coordinates */
       size_t xi = dist_x(gen);
       size_t yi = dist_y(gen);
 
       boost::gil::rgb8_pixel_t pixel = view(xi, yi);
 
       /*
        * input data vec_t{xi, yi},
        * output data vec_t{R, G, B}
       */

       dataset.add( { double(xi), double(yi) },
                    { double(pixel[0]), double(pixel[1]), double(pixel[2]) } );
   }
 
Т.е. фактически мы имеем доступ только к этим живым пикселям.
Как будет выглядеть такая битая картинка? Ну, например, как предложил Old : давайте закрасим все битые пиксели чёрным цветом (0, 0, 0), а живые трогать не будем.
Вот вам и картинка: точнее набор точек на чёрном фоне (звёздное небо).

Цитировать
Ну если знаем какие "живые" а какие "битые" - то все не так уж плохо. Разумеется вещь известная и поиски готового решения здесь к месту. Но и великом здесь неплохо - просто триангуляция (по Борису Николаевичу), а дальше дело сводится к тому самому "закрашиванию треугольника" (от которого научный работник воротил нос)
Научный сотрудник и дальше будет воротить носик от триангуляции) А других подходов нет? :)

PS Перезалил исходники примеров..


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 22, 2020, 13:54
Цитировать
Научный сотрудник и дальше будет воротить носик от триангуляции)
И, кстати, на то есть свои причины..


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 22, 2020, 14:20
Т.е. фактически мы имеем доступ только к этим живым пикселям.
Зачем тогда затемнять задачу понятием "битых"? Проще сказать "имеется 5% пыкселей, восстановить/интерполировать по ним остальные 95%"

Научный сотрудник и дальше будет воротить носик от триангуляции)
Это не очень разумно, и вообще знать классику полезно. А если больше нравится "собирать", то триангуляция - популярнейший алгоритм, реализаций масса. Хотя здесь может и "найти все" удастся  :)

А других подходов нет? :)
Ну в прынцыпе можно задействовать любой из методов интерполяции начиная с простейшего "nearest neighbours" (всего их, насколько помню, 20). На практике, однако, доминирует Делоне

Обычно подобная задача возникает в контексте "lazy". Т.е. взяли точку и смотрим, может ли ее цвет быть интерполирован на основании уже имеющихся. Если нет - считаем эту точку (дорого/долго). Но если все точки даны (уж не знаю откуда), то это Вас не касается

И, кстати, на то есть свои причины..
Не вижу никаких причин мудрить и избегать стандартного/типового решения в данном случае


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 22, 2020, 14:39
Цитировать
Зачем тогда затемнять задачу понятием "битых"? Проще сказать "имеется 5% пыкселей, восстановить/интерполировать по ним остальные 95%"
Согласен, ok)

Цитировать
Это не очень разумно, и вообще знать классику полезно. А если больше нравится "собирать", то триангуляция - популярнейший алгоритм, реализаций масса. Хотя здесь может и "найти все" удастся
У триангуляции есть свои минусы.
Во-первых она дорого обходится, особенно когда входной вектор это не 2D (x, y), а что то с большей размерностью.
Суть триангуляции - это просто значение в некоторой точке определяемое линейной комбинацией соседних:
res = a1 * x + a2 * y + b,
где константы a1, a2, b находятся из системы уравнений. Если размерность входного вектора будет расти, то и число констант будет расти и, соответственно, система уравнений будет разрастаться.  Это не хорошо..

Во-вторых, триангуляция - это локальная теория (локальное приближение "nearest neighbours") Это тоже не есть хорошо.
Я хочу, чтобы алгоритм, принимая решение, основывался на полученном опыте от всех   предыдущих точках..
Т.е. я хочу чтобы он учитывал статистику.  :)


Название: Re: Восстановление изображения
Отправлено: qate от Октябрь 22, 2020, 15:27
PS Перезалил исходники примеров..

не углядел - где запись в файл исходного (поломанного) изображения ?


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 22, 2020, 15:41
Во-первых она дорого обходится, особенно когда входной вектор это не 2D (x, y), а что то с большей размерностью.
А разве Вы формулировали задачу для большей размерности? См стартовый пост, Вы толкуете о "матрице пыкселей". Разумеется хотя бы 3D(x, y, z) точки - и триангуляция уже не катит.

В трехмерном случае сначала надо хотя бы найти ближайших - и это не так уж просто, обычно октодерево. Далее
Суть триангуляции - это просто ..
Рассмотрим такой случай, есть 3 точки

*-----*-------------*

Мы хотим интерполировать значение в правой на основании имеющихся, в том числе и 2 левых на схеме выше. Так вот триангуляция дает четкий ответ какие точки будут использоваться как "источники" а какие нет. Напр самая левая наверняка использоваться не будет, т.к. не видно как правая может попасть в тр-к со стороной из 2 левых

А без этого ясности нет, ну нашли N "соседей" и... что с ними делать?

Т.е. я хочу чтобы он учитывал статистику.  :)
Если Ваши детки научатся красить тр-к и триангулировать - будет очень неплохо, потому что обычно выпускник ВУЗа этого не умеет. Ставьте скромные но реальные цели. А всяких там "нейронов" (и др говна) - поверьте, и без Вас наберутся
Цитировать
Кто не умеет учить - учит как надо учить
:)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 23, 2020, 08:28
Цитировать
не углядел - где запись в файл исходного (поломанного) изображения ?
В этом примере реального поломанного файла не существует. Мы загружаем оригинальную картинку, но говорим, что нам доступны только определённые пиксели. (по сути это модель битой картинки) Задача - зная всё о живых пикселях (их координаты и цвет) восстановить всю картинку.

Цитировать
Рассмотрим такой случай, есть 3 точки
Это что сейчас, 1D задача?

Цитировать
А без этого ясности нет, ну нашли N "соседей" и... что с ними делать?
Вот в алгоритме vanda эта проблема решается и даёт неплохие результаты, подозреваю, что даже лучше чем может дать триангуляция.

Цитировать
Если Ваши детки научатся красить тр-к и триангулировать - будет очень неплохо, потому что обычно выпускник ВУЗа этого не умеет. Ставьте скромные но реальные цели. А всяких там "нейронов" (и др говна) - поверьте, и без Вас наберутся
Слава богу, детки другими вопросами занимаются, более фундаментальными)


Название: Re: Восстановление изображения
Отправлено: qate от Октябрь 23, 2020, 10:46
В этом примере реального поломанного файла не существует.

я это понял, но хочу увидеть глазами как оно "поломалось", а как сохранить в файл - не знаю )


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 23, 2020, 10:48
Это что сейчас, 1D задача?
Нет, 2D, может и 3D. Здравый смысл говорит что для интерполяции правой точки самая левая должна быть отброшена т.к. она полностью "перекрыта" средней. Триангуляция это разруливает т.к. она автоматом создает "наилучшие" тр-ки. А вот разнообразные взвешивания нет.

Вот в алгоритме vanda эта проблема решается и даёт неплохие результаты, подозреваю, что даже лучше чем может дать триангуляция.
Не слышал о таком алгоритме, но рискну утверждать что нет, ну хотя бы потому что интерполяция по тр-кам "бесшовна", т.е. точки на ребре вычисляются одинаково по 2 смежным тр-кам. А в Ваших рез-тах прут "зубы".

Слава богу, детки другими вопросами занимаются, более фундаментальными)
А что Вы считаете "фундаментальным"? По-моему та же триангуляция - один из самых что ни на есть фундаментальных алгоритмов. И если человек ее не писал (а так, "собрал") он многих вещей не догоняет.

А все эти "нейросети" .. ну да, это интересно, забавно, в конце-концов "модно" (что не значит "плохо"). Но до "фундаментальности" там еще ой далеко :)  Затея со статистикой по картинкам - ну а с чего Вы взяли что 2 картинки как-то коррелированы, имеют что-то общее?  Возможно Вы хотите "идти в ногу со временем", поближе к "современным технологиям". Но без понимания основ рез-т печален. Перед тем как тыкать нейросеть в каждую щель лучше поинтересоваться как люди делали "до того".

А деток все-таки жалко  :'(


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 23, 2020, 11:42
В этом примере реального поломанного файла не существует.

я это понял, но хочу увидеть глазами как оно "поломалось", а как сохранить в файл - не знаю )


Вот добавил сохранение "поломанного" изображения



Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 23, 2020, 11:51
Цитировать
А что Вы считаете "фундаментальным"? По-моему та же триангуляция - один из самых что ни на есть фундаментальных алгоритмов. И если человек ее не писал (а так, "собрал") он многих вещей не догоняет.
Ну я же не программирование и алгоритмы преподаю, а физику) Хотя в прошлом семестре был такой один курс, но там из-за пандемии всех на удалёнку отправили..

Цитировать
Затея со статистикой по картинкам - ну а с чего Вы взяли что 2 картинки как-то коррелированы, имеют что-то общее?

Я и не говорил о 2-ух и более картинках. "Статистика" собирается с одной картинки. При триангуляции, вы получаете однозначный результат на основе ближайших точек, а здесь нет. На результат будет влиять и предыстория. 



Название: Re: Восстановление изображения
Отправлено: qate от Октябрь 23, 2020, 12:24
Вот добавил сохранение "поломанного" изображения

оказалось очень просто )
итого сравнение после восстановления - очень впечатляет, разве что очень долго


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 23, 2020, 12:39
Цитировать
итого сравнение после восстановления - очень впечатляет, разве что очень долго

А с триангуляцией будет ещё дольше)


Название: Re: Восстановление изображения
Отправлено: qate от Октябрь 23, 2020, 13:06
а нет ли готовых натренированных бесплатных сетей на tensorflow ?
как например https://github.com/susheelsk/image-background-removal


Название: Re: Восстановление изображения
Отправлено: Racheengel от Октябрь 23, 2020, 16:07
Если мы имеем 5% "хороших" и "равномерно распределённых" пикселей, то это означает, что на 100 пикселей 5 будут нести корректную информацию, т.е. из 20 - 1 пиксель "нормальный".
Тогда можно представить картинку как матрицу, состоящую из ячеек 5x4 пикселей.
Каждая точка каждой ячейки поначалу имеет цвет попавшего в неё "нормального" пикселя.
Далее надо только интерполировать значения пикселей в ячейках.
Зачем тут машин-лернинг?


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 23, 2020, 16:20
Цитировать
а нет ли готовых натренированных бесплатных сетей на tensorflow ?
Не исключаю) Tensorflow - это очень мощная либа)

Цитировать
Если мы имеем 5% "хороших" и "равномерно распределённых" пикселей, то это означает, что на 100 пикселей 5 будут нести корректную информацию, т.е. из 20 - 1 пиксель "нормальный".

Нет, не "равномерно распределённых", а равновероятно распределённых (с однородной плотностью распределения)

Цитировать
Зачем тут машин-лернинг?
А почему бы и нет?  :)


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 24, 2020, 10:59
Далее надо только интерполировать значения пикселей в ячейках.
Зачем тут машин-лернинг?
Ну "только" здесь не то слово, работы с интерполяцией там хватит. Как я понял, смысл в использовании популярных нейросетей (требующих обучения), сама задача чисто для примера. Но совершенно неясно как (или "на чем") происходит это обучение.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 24, 2020, 11:11
Далее надо только интерполировать значения пикселей в ячейках.
Зачем тут машин-лернинг?
Ну "только" здесь не то слово, работы с интерполяцией там хватит. Как я понял, смысл в использовании популярных нейросетей (требующих обучения), сама задача чисто для примера. Но совершенно неясно как (или "на чем") происходит это обучение.

Почему же неясно? Мы даём координаты живого пикселя и говорим, что им соответствует пиксель вот с такими значениями R, G, B. Затем берём другой живой пиксель с координатами (x, y) и говорим, что он имеет уже вот такие R,G,B.. И так далее по всем живым пикселям, о которых нам всё известно.
А теперь мы подсовываем ей произвольные координаты (x, y) и спрашиваем у неё: А какие R,G,B с её точки зрения, должны быть у данного пикселя.  
Вот и вся магия) (Точнее, вся магия там под капотом, но..)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 24, 2020, 18:18
Igors, и всё же, я не совсем понимаю следующее: Если у нас имеется такое случайное распределение "живых" пикселей, то разбиение на треугольники (мы сейчас о 2D говорим) может быть реализовано множеством вариантов.. Как предложенные вами алгоритмы выбирают предпочтение одному из многих таких случаев?


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 24, 2020, 19:45
Igors, и всё же, я не совсем понимаю следующее: Если у нас имеется такое случайное распределение "живых" пикселей, то разбиение на треугольники (мы сейчас о 2D говорим) может быть реализовано множеством вариантов.. Как предложенные вами алгоритмы выбирают предпочтение одному из многих таких случаев?
Ну "предложенное мною" - слишком громко звучит, все это известно уже почти сотню лет :) При триангуляции есть единственный (он же наилучший) вариант, никакого множества нет. Собсно в этом идея DT (Delauney Triangulation). Хотя есть  CDT (Constrained..) типа "хорошо или плохо, но это ребро(а) должно быть" - но то уже навороты.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 24, 2020, 19:52
Igors, и всё же, я не совсем понимаю следующее: Если у нас имеется такое случайное распределение "живых" пикселей, то разбиение на треугольники (мы сейчас о 2D говорим) может быть реализовано множеством вариантов.. Как предложенные вами алгоритмы выбирают предпочтение одному из многих таких случаев?
Ну "предложенное мною" - слишком громко звучит, все это известно уже почти сотню лет :) При триангуляции есть единственный (он же наилучший) вариант, никакого множества нет. Собсно в этом идея DT (Delauney Triangulation). Хотя есть  CDT (Constrained..) типа "хорошо или плохо, но это ребро(а) должно быть" - но то уже навороты.

Ну Ok, я по другому задам вопрос: У Вас есть изображение (1000x1000).. Как Вы оцениваете время и память, минимально необходимые,
чтоб максимально корректно восстановить исходное изображение (методом триангуляции)? Возьмём частный случай, когда, живых пикселей всего 5 %?


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 24, 2020, 20:19
Ну Ok, я по другому задам вопрос: У Вас есть изображение (1000x1000).. Как Вы оцениваете время и память, минимально необходимые,
чтоб максимально корректно восстановить исходное изображение (методом триангуляции)? Возьмём частный случай, когда, живых пикселей всего 5 %?
50K точек? Ну будут "секунды", но не "десятки секунд". Расход памяти не заслуживает обсуждения. А вот в квачестве я отнюдь не уверен - вероятен сильный/чрезмерный блюр.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 24, 2020, 20:24
Цитировать
50K точек? Ну будут "секунды", но не "десятки секунд".
Десятки секунд? Серьёзно? :)
Я сейчас о CPU говорю, однопоточном... Если есть желание, можем посоревноваться) Время выбирайте сами) (Когда Вам удобно))


Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 24, 2020, 20:31
Если есть желание, можем посоревноваться)
Чтобы соревноваться в скорости, нужно как минимум сравняться в качестве, а судя по
А вот в квачестве я отнюдь не уверен - вероятен сильный/чрезмерный блюр.
о качестве говорить не приходится. :)

С таким же успехом можно соревноваться с алгоритмом замещающим битые пиксели случайными. :)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 24, 2020, 20:40
Согласен, но всё же интересно сравнить память и время восстановления "большой картинки".. И более того, у нас есть объективный показатель этого: это квадрат разности исходного изображения с предсказанным.. (Хотя это тоже очень условно и не фундаментально..)  
Но вашу мысль, я понял)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 24, 2020, 20:47
Ну и почему бы и нет? Проиграю я - я признаю свою неправоту.. Это нормально)

В конце-концов, так устроена жизнь)


Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 24, 2020, 21:01
Ну и почему бы и нет? Проиграю я - я признаю свою неправоту.. Это нормально)

В конце-концов, так устроена жизнь)
Я не вкоей мере не отговариваю. :) Мне самому интересно посмотреть,что получиться после триангуляции. Но если соревноваться в скорости и памяти, то нужно как-то определиться с получаемым результатом. Он должен быть примерно равен у всех участников. Для начала можно сравнить точность восстановления. Исходная картинка одна на всех, мы ее "убили" и отдали алгоритмам, а потом сравнили результаты с оригиналом в процентах попадания каждого пикселя.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 24, 2020, 21:13
Ну и почему бы и нет? Проиграю я - я признаю свою неправоту.. Это нормально)

В конце-концов, так устроена жизнь)
Я не вкоей мере не отговариваю. :) Мне самому интересно посмотреть,что получиться после триангуляции. Но если соревноваться в скорости и памяти, то нужно как-то определиться с получаемым результатом. Он должен быть примерно равен у всех участников. Для начала можно сравнить точность восстановления. Исходная картинка одна на всех, мы ее "убили" и отдали алгоритмам, а потом сравнили результаты с оригиналом в процентах попадания каждого пикселя.

Да, именно  об этом я и говорю, чтоб всё было "инвариантно". Я готов предоставить все тесты и  разъяснить все тонкости своего алгоритма.. В этом плане я всегда за свободные и открытые  знания )   


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 25, 2020, 13:03
Я готов предоставить все тесты и  разъяснить все тонкости своего алгоритма..
А разве у Вас есть что-то "свое"?  :)
В этом плане я всегда за свободные и открытые  знания )
Как оно хвостик подняло залив керосин в найденную либу :) Эти нейросети - прекрасная ниша для сачков и тунеядцев всех мастей. Раньше они все около "просто сети" терлись

Если есть желание, можем посоревноваться) Время выбирайте сами) (Когда Вам удобно))
Нет. Времени точно не будет по крайней мере в ближайшие неск месяцев. Да и писать там довольно много, за рамками (интересного) баловства


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 25, 2020, 13:12
Цитировать
А разве у Вас есть что-то "свое"?
Ну представьте, да)

Цитировать
Как оно хвостик подняло залив керосин в найденную либу  :) Эти нейросети - прекрасная ниша для сачков и тунеядцев всех мастей. Раньше они все около "просто сети" терлись
Подождите, vanda - это не нейросеть! Это нечто среднее между random forest и интерполяцией.   Давайте разделять понятия!

Цитировать
Нет. Времени точно не будет по крайней мере в ближайшие неск месяцев. Да и писать там довольно много, за рамками (интересного) баловства
Хорошо, как появится задачка, инторполировать данные, тогда и поговорим) И сравним)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 25, 2020, 13:24
Более того, эта задача уходит корнями в более общий случай (когда входной вектор имеет гораздо большую размерность)
И восстановление изображения - это просто побочный эффект исследований..
И в общем случае триангуляция не поможет в принципе..


Название: Re: Восстановление изображения
Отправлено: Old от Октябрь 25, 2020, 13:46
Подождите, vanda - это не нейросеть! Это нечто среднее между random forest и интерполяцией.   Давайте разделять понятия!
Да кто там будет разбираться в этих тонкостях... :)
Если появляется что-то сложней циклов с индексами и огромных свитчей, хвостик у нашего среднего программиста падает на пол шестого. И оправдывает он это для себя - ненужностью. :)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 25, 2020, 14:05
Цитировать
Да кто там будет разбираться в этих тонкостях...  :)
Ну а вдруг?  :)  Я всегда открыт для обсуждения идей :)


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 25, 2020, 14:29
Хорошо, как появится задачка, инторполировать данные, тогда и поговорим) И сравним)
Ну поговорить-то можно, задача такая

- Есть N базовых (небитых) точек (x, y, z) разбросанных по поверхностям различных 3D объектов. Требуется в данной точке интерполировать цвет на основании ближайших базовых. Если это невозможно, то выполнить (дорогостоящий) расчет цвета в данной точке. К сожалению, вновь посчитанная точка не становится базовой, т.к. впарываемся в зависимость от порядка расчета (multi-threading обязателен).

Подобные "простые" задачки - всегда страшный гемор. Во-первых, надо решить что есть "ближайшая", поэтому для каждой базовой вычисляется, грубо говоря, "радиус захвата". Также точки могут не биться по геометрии, напр 2 соседки но на разных гранях куба не должны интерполироваться. Это довольно очевидный случай, проверил нормали - и все. Но есть гораздо более подлые, напр "ступенька". Во-вторых надо как-то найти ближайших, используется ocTree (multi вариант) у которого свои заморочки. Ну и наконец надо как-то осреднить/интерполировать значение из ближайших. Здесь я, правду сказать, ничего не нашел, тупенько взвесил используя упомянутые "радиусы захвата". Если вес оказался слишком мал - считаем новую точку.

Задача вроде бы похожа на Вашу но... Обратите внимание что сама/собсно интерполяция - лишь неск % работы. И, конечно, головная боль - качество. Артифакты на фотках Ваших баб воспринимаются спокойно - конечно, и за такое спасибо на 5%. Но на рендере это не разговор - значит еще надо задирать параметры вплоть до полного расчета. Но тогда кадр может считаться часами, а то и сутками.

Ну хорошо, вот допустим я хочу задействовать "современные технологии". Мои действия?  :)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 25, 2020, 14:37
Ну дык в чём проблема? Давайте сравним?
(я сейчас о 2D говорю) Хотя любая размерность приемлема)


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 26, 2020, 10:15
Кстати выше у товарища мелькнула хорошая мысль - визуализировать исходные данные. Сделаем это (аттач). Это первая попавшаяся фотка города. Значимые пиксели имеют альфу = 1, остальные 0. Предлагаю проверить что получится. Извиняюсь за доставленные неудобства (вместо rand надо использовать альфу) но надеюсь они невелики. А потом сравним с  исходной фоткой. Потому что пока "оригинал" на руках - злоупотребления возможны.


Название: Re: Восстановление изображения
Отправлено: Racheengel от Октябрь 26, 2020, 10:47
Нет, не "равномерно распределённых", а равновероятно распределённых (с однородной плотностью распределения)

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

В любом случае, задача ИМХО сводится к сегментированию и триангуляции, даже если распределение не "равновероятно" и не "равномерно".


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 26, 2020, 14:48
.. в каждой "макроячейке" гарантируется наличие одного "не-битого" пикселя.
Эту "макроячейку" называют "site" а картинку разбитую на такие сайты - диаграммой Вороного. Но это нормальная человеческая логика. Здесь же предлагается др подход, вот
Почему же неясно? Мы даём координаты живого пикселя и говорим, что им соответствует пиксель вот с такими значениями R, G, B. Затем берём другой живой пиксель с координатами (x, y) и говорим, что он имеет уже вот такие R,G,B.. И так далее по всем живым пикселям, о которых нам всё известно.
А теперь мы подсовываем ей произвольные координаты (x, y) и спрашиваем у неё: А какие R,G,B с её точки зрения, должны быть у данного пикселя.   
Вот и вся магия) (Точнее, вся магия там под капотом, но..)
Ну т.е. есть какой то "бог из машины" (как говорили древние), надо лишь накормить его данными, а потом спросить - и он сам все разрулит! Искусственный интеллект, батенька :)

Конечно такой подход аморален, но давайте (постараемся) "быть объективными" и посмотреть что он дает


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 26, 2020, 20:18
Кстати выше у товарища мелькнула хорошая мысль - визуализировать исходные данные. Сделаем это (аттач). Это первая попавшаяся фотка города. Значимые пиксели имеют альфу = 1, остальные 0. Предлагаю проверить что получится. Извиняюсь за доставленные неудобства (вместо rand надо использовать альфу) но надеюсь они невелики. А потом сравним с  исходной фоткой. Потому что пока "оригинал" на руках - злоупотребления возможны.

Держите ваш Донецк)

https://dropmefiles.com/4S0FR (https://dropmefiles.com/4S0FR)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 26, 2020, 20:22
Нет, не "равномерно распределённых", а равновероятно распределённых (с однородной плотностью распределения)

Да, конечно. Но это как раз означает, что в каждой "макроячейке" гарантируется наличие одного "не-битого" пикселя.

Нет, не гарантируется)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 26, 2020, 22:06
Кстати выше у товарища мелькнула хорошая мысль - визуализировать исходные данные. Сделаем это (аттач). Это первая попавшаяся фотка города. Значимые пиксели имеют альфу = 1, остальные 0. Предлагаю проверить что получится. Извиняюсь за доставленные неудобства (вместо rand надо использовать альфу) но надеюсь они невелики. А потом сравним с  исходной фоткой. Потому что пока "оригинал" на руках - злоупотребления возможны.

Держите)

https://dropmefiles.com/4S0FR (https://dropmefiles.com/4S0FR)

Я бы хотел прокомментировать полученный результат. Фото города имеет много мелких деталей и как следствие, неизбежно появляются "зубы". Это нормально..
Восстановление изображения составило  76 min. (это при radius = 3 - это внутренний параметр vanda, который передаётся в метод train)
Код
C++ (Qt)
/* radius = 3.0 */
   vanda.train(dataset, 3.0);
 

А теперь бы хотелось сравнить это с триангуляцией, как по качеству так и по времени.. Ну и по памяти.. В однопоточном варианте на CPU)


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 27, 2020, 13:33
Я бы хотел прокомментировать полученный результат. Фото города имеет много мелких деталей и как следствие, неизбежно появляются "зубы". Это нормально..
Зубы можно убрать но ценой дальнейшего размытия, этот "xрен" может оказаться совсем не слаще "той редьки". Возможно Вы хотели сказать простой вещь типа "если данных нет - то их и нет", т.е. мы объективно не можем надеяться на идеальное качество при 5% данных. Получили узнаваемый имедж - уже хорошо. С этим никто не спорит

Восстановление изображения составило  76 min.
"Серьезно"? Я полагал что речь идет о чем-то.. ну до минуты максимум.

А теперь бы хотелось сравнить это с триангуляцией, как по качеству так и по времени.. Ну и по памяти.. В однопоточном варианте на CPU)
Как я уже пояснил - нет, триангуляция за рамками "экспериментов". Если Вас устроит, я могу склепать какой-нибудь велик, напр что-то типа Гаусса. Рез-т конечно будет хуже чем с триангуляцией - но соразмерим, разницы "на порядок" не будет. Ну и, как всегда, не "сию минуту", я не могу все бросить в творческом порыве :)

Да, оригинал (https://ru.files.fm/u/vwaqqh8n)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 27, 2020, 14:40
Цитировать
"Серьезно"? Я полагал что речь идет о чем-то.. ну до минуты максимум.
Там сортировка списка групп дорого обходится, поэтому так долго получается..

Цитировать
Ну и, как всегда, не "сию минуту", я не могу все бросить в творческом порыве
Хорошо)


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 28, 2020, 13:13
Файлы (включая исходник) здесь (https://ru.files.fm/u/q9r2avjm)

Алгоритм: берем строку имеджа и интерполируем пиксели лежащие между 2 базовыми. Веса считаем как 1 / расстояние. Получаем Pass_1 (https://ru.files.fm/u/w9uqzusk). Затем делаем то же самое по столбцу имеджа Pass_2 (https://ru.files.fm/u/mz2nv3c8) и по диагоналям Pass_3 (https://ru.files.fm/u/4mwbrsdw) и Pass_4 (https://ru.files.fm/u/gpjyt68m). Ну и для приличия немного подблюрим (аттач)

Конечно сей велик ни на что не претендует, и я не стану утверждать что "он лучше" :) Но главную задачу "получить узнаваемый имедж" он решает. По ходу дела зароились задумки "как лучше", но ну нафиг, работать надо  :)


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 28, 2020, 15:25
Спасибо за пример. Идея в общем понятна) И по скорости и по качеству весьма недурно.
Правда, всё это хорошо, когда у вас все данные упорядоченны и отображены в виде матрицы с random access доступом за O(1)  :)

Подход приведённый мной не подразумевает такой упорядоченности: есть набор входных и выходных векторов и всё)
Соответственно и время так сильно отличается. Но с другой стороны можно рассматривать большие размерности как входных, так и выходных векторов.   


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 29, 2020, 13:29
Правда, всё это хорошо, когда у вас все данные упорядоченны и отображены в виде матрицы с random access доступом за O(1)  :)
Совершенно верно, все это лишь "игры с картинкой".
[off]
Какой идиотский это навязанный термин "random access" - ну чем было плохо "прямой доступ" :'(
[/off]

Но с другой стороны можно рассматривать большие размерности как входных, так и выходных векторов.   
Алгоритм который бы работал в 2D/3D/4D и.т.д. вероятно будет "слишком общим" и поэтому мало ценным/интересным. Меня никогда не останавливало соображение типа "да это, мол, не распространяется на N измерений", тем более что 3 измерения (реальное геометрическое пр-во) - более чем достаточно чтобы нажить грыжу.

Подход приведённый мной не подразумевает такой упорядоченности: есть набор входных и выходных векторов и всё)
А можно как-то ознакомиться с этим подходом? (если это не секрет). Вы упоминаете о некой vanda, но что это - я без понятия. Может ушами прохлопал, please "ткните носиком"

Интерполяция (конкретно интерполяция в 3D) - одна из "вечных" задач, она всегда актуальна. Однако постановка существенно отличается от простого "запрашиваем цвет по (x. y)". Это типа "сейчас отсюда вылетит птичка" :), на деле все гораздо хуже. Основные моменты

1) Представительность/достоверность. Напр в 3D запросная точка может оказаться там "куда Макар телят не гонял", такую надо считать (а не интерполировать)

2) Не все может интерполироваться со всем, напр освещенность одной грани куба не имеет ничего общего с другой (хотя точки на разных гранях могут быть сколь угодно близко)

3) "Покрытие" (добрая половина работы). Это тут хорошо, мол, "извне" даны 5% достоверных. А по жизни базовые точки выбираются самостоятельно, и необходимо обеспечить максимальное попадание множества запросных точек туда где интерполяция разумна. Первый шаг (splattering) похож на Ваш - да, делаем N базовых, равновероятных. Но это лишь "начало большого пути" 

Не, ну старый ретроград не совсем уж чужд новых идей/веяний, но как/куда приткнуть эти нейросети (или что еще)? Если по-прежнему делать все что выше - то где "выйгрышь"? А не делать и уповать на чудо - не наш метод. Да и 76 минут обучения как-то пугает.. за что боремся?
 


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 29, 2020, 14:52
Цитировать
А можно как-то ознакомиться с этим подходом? (если это не секрет). Вы упоминаете о некой vanda, но что это - я без понятия. Может ушами прохлопал, please "ткните носиком"
Нет, не секрет) Сегодня-завтра напишу детали алгоритма..


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 30, 2020, 13:20
Итак, суть алгоритма.

Фактически он состоит из двух частей. В первой части нам необходимо разбить наше множество входящих векторов на группы.
Этим занимается метод train.
Код
C++ (Qt)
void train(const training_dataset & dataset, const real_t & radius = 0.0)
   {
       if (dataset.empty())
           return;
 
       for (size_t i = 0; i < dataset.size(); ++i)
       {
           auto it = m_groups.begin();
           bool is_added = false;
 
           while (it != m_groups.end())
           {
               it = std::find_if(it, m_groups.end(), [&](const group_t & g)
               {
                   return g.is_contain(dataset[i].first, sqr(radius));
               });
 
               if (it != m_groups.end()) {
                   it->add( dataset[i].first, dataset[i].second );
                   is_added = true;
                   ++it;
               }
           }
 
           if (!is_added) {
               m_groups.emplace_front(dataset[i].first, dataset[i].second);
           }
       }
   }
 
Каждая группа содержит "базисный" вектор - просто центр масс всех точек, что попали в неё (об этом ниже) и среднее значение
выходного вектора, соответствующего базисной точки. В данном случае, критерий принадлежности какой-либо точки группе определяется
просто как попадание её внутрь гиперсферы радиуса R (radius - это параметр, который пользователь устанавливает сам. Чем больше R, тем меньше групп в итоге будет).
Сам центр сферы находится отсчитывается от базиса. Если точка попала в группу, то базис пересчитывается (центр масс смещается) и пересчитывается среднее значение выходного вектора.
Разумеется одна и та же входная точка может принадлежать нескольким группам.
Код
C++ (Qt)
Т.е. если точка принадлежит групе, то происходит следующее:
void add(const vec_t & input, const vec_t & output)
       {
           ++m_count;
 
           for (size_t i = 0; i < m_stat.size(); ++i)
           {
               m_stat[i] += (output[i] - m_stat[i])/m_count;
           }
 
           for (size_t i = 0; i < m_basis.size(); ++i)
           {
               m_basis[i] += (input[i] - m_basis[i])/m_count;
           }
       }
 

Понятно, что разбиение на группы не единственно и имеет комбинаторно большое число вариантов.
После того, как все исходные данные разбиты на группы можно переходить ко второй части алгоритма: Предсказание (метод predict)
Код
C++ (Qt)
vec_t predict(const vec_t & data, const real_t & q = 0.5) const
   {
       if (m_groups.empty())
           return vec_t();
 
       if (m_groups.size() == 1)
           return m_groups.begin()->statistics();
 
       m_groups.sort( [&](const group_t & a, const group_t & b)
       {
           return a.sqr_distance_from(data) < b.sqr_distance_from(data);
       });
 
       vec_t stat(m_groups.begin()->statistics_size(), 0.0);
 
       real_t w = (1.0 - q)/(1.0 - std::pow(q, m_groups.size()));
 
       for (const auto & group : m_groups)
       {
           for (size_t j = 0; j < stat.size(); ++j)
           {
               stat[j] += w*group.statistics(j);
           }
           if (w < err)
               break;
           w *= q;
       }
 
       return stat;
   }
 

Суть этого метода заключается в следующем: Мы подаём на вход произвольный входной вектор data.
И далее сортируем наш список групп в порядке возрастания расстояния от входного вектора data до базисных векторов
групп. Т.е. в отсортированном списке первыая группа будет всех ближе к data, вторая группа чуть дальше и т.д..
Теперь осталось найти результирующий выходной вектор.
Его компоненты stat_i определяются по формуле:
stat_i = sum_n^groups.size ( c_n * (group_n).statistics_i ),
где коэффициенты c_n = w * q^n и  удовлетворяют условию нормировки:
sum_n c_n = 1,
так, что w = (1 - q)/(1 - q^N), где N - число групп, причём 0 < q < 1, и характеризует число ближайших соседей
дающих вклад в итоговое значение выходного вектора. Чем ближе q к единице, тем большее число ближайших соседей будет учтено
и тем более "разблюреней", будет результат, и напротив. q - это второй параметр в этом алгоритме, который задаёт пользователь.

Вот, собственно и всё. :)    

Исходники с примером в аттаче.


Название: Re: Восстановление изображения
Отправлено: Igors от Октябрь 31, 2020, 11:18
Позвольте "попридираться" к деталям :)
Если точка попала в группу, то базис пересчитывается (центр масс смещается) и пересчитывается среднее значение выходного вектора.
Типовая подлянка: после того как центр пересчитан, следующая точка может уже не попасть в группу. Или попасть. В любом случае получается зависимость от порядка добавления точек, так нельзя

Мы подаём на вход произвольный входной вектор data.
И далее сортируем наш список групп в порядке возрастания расстояния от входного вектора data до базисных векторов
групп. Т.е. в отсортированном списке первыая группа будет всех ближе к data, вторая группа чуть дальше и т.д..
Любая сортировка на этапе использования не годится. Ну хотя бы потому что multi-threaded = обязон. И, судя по времени, очень может быть что где-то насвистели и месите данные (а не указатели)

А вот саму идею/суть я, наверное, не понял. Пока я вижу только "найти ближайших", да, есть такая подзадача, и она не так уж проста. Но есть типовые способы, напр ocTree или kd-tree (оба кстати распространяются на N измерений). С ними время должно быть до секунды, ну ладно, пару секунд. Или разбиение на группы/кластеры несет еще какой-то смысл (не уловил какой) ?

Еще деталь: такие, казалось бы, совершенно "элементарные" вещи как "радиус R" в 3D далеко не очевидны :) Напр рендерится нечто "далекое" (у линии горизонта) - здесь разумный R порядка километров. Но на той же картинке у ближнего (к камере) объекта радиус R может быть миллиметр и меньше.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 31, 2020, 13:21
Цитировать
Типовая подлянка: после того как центр пересчитан, следующая точка может уже не попасть в группу. Или попасть. В любом случае получается зависимость от порядка добавления точек, так нельзя
Это нормально (если "точка выйдет из группы"), поскольку вместе с этим и вклад от её значения (выходного вектора) также будет давать всё более малый и малый вклад в итоговое среднее значение.

Цитировать
Любая сортировка на этапе использования не годится. Ну хотя бы потому что multi-threaded = обязон.

Как то уж слишком радикально.. Без сортировки не обойтись, поскольку данные неупорядочены и вы не можете знать заранее, какая точка попадёт в метод predict.
Потом, что мешает мне распараллелить  процесс? Заряжу thread_pool и буду ему скармливать очередной входящий вектор..Не вижу проблемы..

Цитировать
Но есть типовые способы, напр ocTree или kd-tree (оба кстати распространяются на N измерений).
Да, соглашусь, здесь напрашивается kd-tree.. Надо попробовать.
    
Цитировать
Еще деталь: такие, казалось бы, совершенно "элементарные" вещи как "радиус R" в 3D далеко не очевидны  :)
Для меня очевидна) Т.е. я всегда могу оценить порядок этой величины, который будет для меня приемлем в контексте моей задачи.


Название: Re: Восстановление изображения
Отправлено: m_ax от Октябрь 31, 2020, 15:41
Цитировать
Да, соглашусь, здесь напрашивается kd-tree.. Надо попробовать.
Правда, здесь возникает такой неприятный момент.. Если я фиксирую точность в определении компонент выходного вектора (x_i +- err) и фиксирую параметр q,
то я, в принципе, могу однозначно сказать (читай подсчитать) сколько мне нужно ближайших соседей (n) упорядоченных по расстоянию от запрашиваемой точки.
Чем меньше q, тем, соответственно, меньше таких соседей нужно:
Код
C++ (Qt)
n = 1 + log(err/(1-q))/log(q) + O(q^N)  // 0 < q < 1
 
Если n << N (N - training size) то сейчас, в лучшем случае, я получу такой отсортированный список за O(N). А с kd-tree за один запрос,  смогу ли я получить такой отсортированный список за меньшее время? Мне вот это совсем не очевидно.. ???  

Т.е. для наглядности, у нас есть training_data (2D)
Код
C++ (Qt)
input_data = { {1, 2}, {12, -34}, {5, 7}, ..., {x_N, y_N} }
 
На вход метода predict подаётся вектор { x, y }.
Мне нужно за минимальное время получить отсортированное по расстоянию от точки {x, y} до каждой из точек input_data подмножество input_data, размером n.

Не выйлется ли это за то же самое O(N)?


Название: Re: Восстановление изображения
Отправлено: Igors от Ноябрь 01, 2020, 10:21
Мне нужно за минимальное время получить отсортированное по расстоянию от точки {x, y} до каждой из точек input_data подмножество input_data, размером n.
Обычная техника работы с kd_tree:

- на каждом делении дерева добавляем "медиану" с расстоянием < R в (статический) массив и подсчитываем суммарный вес. Если он превысил некоторую величину, это понимается как сигнал "ближайших слишком много, берем только самых ближних". Тогда сортируем массив по весу и последующие точки вставляем в сортированный массив (если вес > последнего то вытесняем его) или игнорируем (если <). Это соответствует автоматьчному уменьшению R. Часто также используется не вес а "макс число ближайших"

Недостаток кв-tree: требуется фиксированный R, если это не так, то приходится использовать макс R, но тогда скорость поиска падает


Название: Re: Восстановление изображения
Отправлено: Igors от Ноябрь 01, 2020, 11:01
Для меня очевидна) Т.е. я всегда могу оценить порядок этой величины, который будет для меня приемлем в контексте моей задачи.
И я даже знаю какой :) Но стоит спросить себя типа "а кто (или как, зачем, для чего и.т.п) будет юзать мой софт ?". И если Вы сами не видите вариантов - то зачем его писать? Ну в самом деле, если у меня уже есть картинка - то зачем ее ломать и затем восстанавливать? Понятно что это хороший тест, но с практическим применением как-то "не густо", все упирается в "а откуда взять базовые точки?".

А между тем задача интерполяции весьма актуальна/востребована и многие (включая меня) писали и будут писать свои велики, не говоря уже о многих днях гугления чтобы (безуспешно) найти что-то готовое. Разница а постановке

Ваша постановка (если не так понял - поправьте):
Цитировать
интерполировать заданную точку(и) га основании N заданных, желательно для любого числа измерений
Профессиональная постановка:
Цитировать
есть 3D сцена из полигонных моделей. Выполнить (трудоемкий) расчет лишь в некоторых точках, в остальных (которые будет запрашивать рендер) обойтись интерполяцией.
Может показаться что вторая легко сводится к первой, но это не так. Ну и конечно я не пытаюсь что-то от Вас получить, навязать Вам (реально трудную) работу и.т.п. Просто я этим занимался, если интересно - можем поговорить.


Название: Re: Восстановление изображения
Отправлено: Old от Ноябрь 01, 2020, 11:12
Ваша постановка...

Профессиональная постановка...

Это вы поскромничали. :)
Нужно было так:

Неправильная постановка...

Истинная постановка...


Название: Re: Восстановление изображения
Отправлено: m_ax от Ноябрь 01, 2020, 20:33
Цитировать
Нужно было так:

Неправильная постановка...

[Истинная постановка...
:)
За что я обожаю этот форум)

Цитировать
Ну и конечно я не пытаюсь что-то от Вас получить, навязать Вам (реально трудную) работу и.т.п. Просто я этим занимался, если интересно - можем поговорить.
Да, хорошо..
Только дайте мне время разобраться с kd-tree)
(У меня сейчас университетская деятельность львиную долю времени сжирает..)


Название: Re: Восстановление изображения
Отправлено: m_ax от Ноябрь 03, 2020, 14:34
Цитировать
Обычная техника работы с kd_tree:

- на каждом делении дерева добавляем "медиану" с расстоянием < R в (статический) массив и подсчитываем суммарный вес. Если он превысил некоторую величину, это понимается как сигнал "ближайших слишком много, берем только самых ближних". Тогда сортируем массив по весу и последующие точки вставляем в сортированный массив (если вес > последнего то вытесняем его) или игнорируем (если <). Это соответствует автоматьчному уменьшению R. Часто также используется не вес а "макс число ближайших"

Недостаток кв-tree: требуется фиксированный R, если это не так, то приходится использовать макс R, но тогда скорость поиска падает
Вот! А если я не знаю заранее этот самый R? Как тогда мне обозначить/построить это дерево?
Я понимаю, конечно, что я его, в принципе, могу организовать,
 но когда на вход predict поступают совершенно случайные точки, мне это дерево каждый раз придётся перестраиваить?


Название: Re: Восстановление изображения
Отправлено: Igors от Ноябрь 03, 2020, 16:19
Вот! А если я не знаю заранее этот самый R? Как тогда мне обозначить/построить это дерево?
Я понимаю, конечно, что я его, в принципе, могу организовать,

 но когда на вход predict поступают совершенно случайные точки, мне это дерево каждый раз придётся перестраиваить?
Можно найти "просто ближайших" не имея начального R, конечно это обойдется дороже. Как работает дерево при наличии R

- Взяли средний эл-т массива, у него есть "ось деления" (это единственнык доп данные нужные дереву). Допустим это ось X. Сравниваем расстояние по X от этого среднего эл-та до запросной точки с R. Если оно больше то одну из  половинок массива (в зависимости от знака расстояеия) можно не смотреть, там точно никто не дотянется. Повторяем для оставшейся половинки. Ну а если dist_x меньше R, то придется (рекурсивно) парить обе половинки.

Теперь R не задан, ну хреновато конечно, но решаемо. Просто полагаем его найденному расстоянию и накапливаем сортированный массив. После того как очередной эл-т будет вытолкнут из массива, R станет равен расстоянию до последнего в массиве. Ну т.е. R неуклонно уменьшается. Число соседей (размер сортированного массива) должен быть задано.


Название: Re: Восстановление изображения
Отправлено: m_ax от Ноябрь 16, 2020, 22:35
Разобрался с k-d tree. Действительно, мощная вещь) Время обработки изображения сразу на два порядка сократилось!
Спасибо igors за наводку.
Более того, качество восстановленного изображения стало даже лучше, и это при том, что использовался алгоритм "на коленке"..

Исходники приаттачиваю..



 


Название: Re: Восстановление изображения
Отправлено: Igors от Ноябрь 17, 2020, 11:37
А я уж думал "бобик спекся" :) Иногда приятно ошибиться
По kd-tree

1) Сачкует
Код
C++ (Qt)
index = (index + 1) % m_dimensions;
 
Никто не обещал равномерного распределения по осям, ось деления надо вычислять при построении и хранить в элементе/ноде.

2) Multi-threading
Код
C++ (Qt)
   node* m_best = nullptr;
   real_t m_best_dist = 0.0;
 
Это сразу делает поиск "not thread-safe" (отрезали самое дорогое)  

3)
Код
C++ (Qt)
   vec_t predict(const vec_t & data, size_t tests = 10) const
   {
       size_t N = std::min(m_kdtree.num_nodes(), (tests) ? tests : size_t(1));
 
       vec_t output = m_kdtree.nearest(data).second;
 
       const real_t r = sqrt(3.0/m_kdtree.dimensions()) * m_kdtree.radius();
 
       std::uniform_real_distribution<real_t> dist(-r, r);
 
       for (size_t i = 1; i < N; ++i)
       {
           vec_t p = data;
           for (auto & x : p)
               x += dist(m_gen);
 
           auto stat = m_kdtree.nearest(p).second;
 
           for (size_t j = 0; j < output.size(); ++j)
           {
               output[j] += (stat[j] - output[j])/(i+1);
           }
       }
 
       return output;
   }
 
Как я понял: находим ближайшую к запросной точке. Затем N раз "jitter' (сдвигаем запросную на случайное смещение) и находим ближайшую к сдвинутой. Если я понял верно, то это плохо "зато" медленно. Дерево способно находить N ближайших, с радиусом или без, если хотите - еще пожуем. Предлагаю оформить public поиск так
Код
C++ (Qt)
void kd_tree::nearest(
   const vec_t & ip,   // запросная точка
   double & ioRadius,   // напр -1 если начального R нет
   int iMaxNear;          // макс число ближайших (-1 если всех)
   std::vector<vec_t *> & outPt );   // вектор найденных ближайших
 

Ну ладно, занялся делом вместо сахара - уже хорошо  :)

Edit: пожалуй лучше макс число ближайших передавать явно (а не шифровать в outPt)


Название: Re: Восстановление изображения
Отправлено: m_ax от Ноябрь 17, 2020, 13:28
Цитировать
1) Сачкует
Код
C++ (Qt)
index = (index + 1) % m_dimensions;
 
Никто не обещал равномерного распределения по осям, ось деления надо вычислять при построении и хранить в элементе/ноде.
Не понял.. Причём здесь равномерное/неравномерное распределение точек? Индекс (index) циклически бегает по компонентам вектора.
Т.е. при построении дерева мы сравниваем i-тые компоненты, затем на следующем шаге сравниваются следующие (i+1) компоненты и так далее..
Код
C++ (Qt)
index = (index + 1) % m_dimensions;
 
middle->m_left = make_tree(begin, middle, index); // Здесь индекс уже для следующей компоненты вектора
 
middle->m_right = make_tree(std::next(middle, 1), end, index);
 

Цитировать
2) Multi-threading
Ну да, это можно подправить, например, передавая их (m_best и m_best_dist) в сам метод..

Цитировать
Как я понял: находим ближайшую к запросной точке. Затем N раз "jitter' (сдвигаем запросную на случайное смещение) и находим ближайшую к сдвинутой. Если я понял верно, то это плохо "зато" медленно. Дерево способно находить N ближайших, с радиусом или без, если хотите - еще пожуем. Предлагаю оформить public поиск так
Да, такой вот наивный подход пока.. Я не совсем понял с радиусом. Я не могу заранее делать предположения о его величине.. Более того, для различных входных точек он (радиус) также будет (в общем случае) меняться.
Или мы о разных вещах говорим?




Название: Re: Восстановление изображения
Отправлено: Igors от Ноябрь 17, 2020, 15:12
Не понял.. Причём здесь равномерное/неравномерное распределение точек? Индекс (index) циклически бегает по компонентам вектора.
"Отнюдь". Напр все 2D точки имеют одинаковую координату Y, отличаются лишь координатой X. Тогда деление по Y бесполезно, все деления должны быть по X

Да, такой вот наивный подход пока.. Я не совсем понял с радиусом. Я не могу заранее делать предположения о его величине.. Более того, для различных входных точек он (радиус) также будет (в общем случае) меняться.
Примерно так (писал здесь)
Код
C++ (Qt)
  struct CFindData {
    vec_t mPt;
    double mRad;
    int mMaxNear;
    std::vector<node *> mOut;
  };
 
   void nearest(node ** beg, node ** end, size_t index, CFindData & data )
   {
       auto num = end - beg;   // std::distance?
       if (num < 1)  return;
       node *& mid = *(beg + dist / 2);
 
       bool scanLeft = true, scanRight = true;
 
// пытаемся добавить точку
      data.AddPoint(mid);
       if (num < 2)  return;
 
// если радиус есть (был или появился после AddPoint),
// то отсекаем точки что заведомо далеко
      if (data.mRad >= 0.0) {
        real_t dx = mid->get(index) - data.mPt[index];
 
        scanRight = (dx < data.mRad);
        scanLeft  = (dx > -data.mRad);
    }
 
    index = (index + 1) % m_dimensions;   // халтура
 
// продолжаем рекурсивно
    if (scanLeft)
       nearest(beg, &mid, index, data);
 
    if (scanLeft)
       nearest(&mid + 1, end, index, data);
  }
 

Теперь добавление точки
Код
C++ (Qt)
bool CFindData::AddPoint( node * pt )
{
// гонорируем точку за границами радиуса
  double dist = pt->distance(mPt);
  if ((mRad >= 0.0) && (dist >= mRad)) return false;
 
// вставляем точку в сортированный вектор
  auto it = std::lower_bound(mOutPt.begin(), mOutPt.end(),  pt, CompDistFunc);
  mOutPt.insert(it, pt);
 
// вычисляем новый радиус
 if (mMaxNear > 0) {
    if (mOutPt.size() > mMaxNear)    
      mOutPt.resize(mMaxNear);
 
    if (mOutPt.size() >= mMaxNear)    
      mRad = mPt.distance(*mOutPt.back());
  }
  else
     assert(mRad >= 0.0);   // хотя бы 1 (mRad и mMaxNear) должен быть задан
 
  return true;
}
 
Edit: подправил num (условие выхода)


Название: Re: Восстановление изображения
Отправлено: m_ax от Ноябрь 17, 2020, 21:02
Хорошо, спасибо! Я согласен с тем, что если мы задаём при запросе конкретный радиус, то за один проход дерева мы в принципе сможем собрать все точки лежайшие внутри гиперсферы радиуса R. В худшем случае, если радиус будет превышать размер "облака точек" то это выйлется асимптотически за O(N*log(N)), что тождественно quick_sort.. А в лучшем случае это будет за O(log(N)).
Я так и не понял по поводу радиуса.. Но буду ещё экспериментировать.. В выходные буду раскуривать эту тему)


Название: Re: Восстановление изображения
Отправлено: Igors от Ноябрь 18, 2020, 10:14
Я согласен с тем, что если мы задаём при запросе конкретный радиус, то за один проход дерева мы в принципе сможем собрать все точки лежайшие внутри гиперсферы радиуса R. В худшем случае, если радиус будет превышать размер "облака точек" то это выйлется асимптотически за O(N*log(N)), что тождественно quick_sort.. А в лучшем случае это будет за O(log(N)).
Я так и не понял по поводу радиуса.. Но буду ещё экспериментировать.. В выходные буду раскуривать эту тему)
Если радиус "слишком велик", то дело сведется к прямому перебору, все ноды будут найдены, дерево ничего не отсечет. Однако если задано mMaxNear, то по достижении макс числа точек радиус появится автоматычно и будет неуклонно уменьшаться. Т.е. если R изначально не задан, то сначала будет прямой перебор, а потом начнутся отсечки

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