Plain 223 9 сентября, 2022 Опубликовано 9 сентября, 2022 · Жалоба 6 часов назад, iiv сказал: не такой, как у меня - и в центре, и по краям свои коэффициенты Вы пока не знаете, какая она, Вам это фактически все здесь говорят. Снимите линейный эталон однократно и правильно, т.е. не с руки мятую бумажку, а камеру в штатив, эталонную плоскоть перпендикулярно её физической оси, и т.д. 6 часов назад, iiv сказал: кажется, понял о чем Вы имели ввиду ... и передать это все по компорту наверх на какой-то обычный компьютер Не поняли. Процессор камеры ищет в кадре светодиод, получает снаружи его линейные координаты с его энкодера, а значит, получает однозначное соответствие координаты данной точки камеры реальному углу. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 9 сентября, 2022 Опубликовано 9 сентября, 2022 · Жалоба 12 hours ago, _pv said: то что на картинке из-за своей несимметричности похоже надо лечить каким-то произвольным полиномом от x,y, а не радиально симетричным по r с чётными степенями. качество картинки отвратительное конечно, но если пройтись градиентным фильтром и размазать gr = ImageAdjust[GaussianFilter[GradientFilter[GaussianFilter[ColorConvert[img, "Grayscale"], 2], 2], 4]] что-то разглядеть можно вытащить данные и натянуть 2х мерный фит экспоненты, погнутой вдоль полинома grd = ImageData[gr]; data = Flatten[Table[{x, y, grd[[y, x]]}, {y, Length[grd]}, {x, Length[grd[[1]]]}], 1]; expr = a*Exp[-(y - (y0 + y1*x + y2*x^2 + y3*x^3 + y4*x^4))^2/2/sy] + b; fit = FindFit[data, expr, {{y0, #}, {y1, 0}, {y2, 0}, {y3, 0}, {y4, 0}, {sy, 5}, {a, 0.2}, {b, 0.3}}, {x, y}] & /@ {75, 130, 175, 220, 264, 308, 351, 393, 435, 490} выглядит как-то так вблизи {{y0 -> 87.7292, y1 -> -0.146309, y2 -> 0.000279265, y3 -> 3.62452*10^-7, y4 -> -7.28475*10^-10, sy -> 4.45341, a -> 0.11059, b -> 0.293883}, {y0 -> 134.557, y1 -> -0.287593, y2 -> 0.00148697, y3 -> -2.73506*10^-6, y4 -> 1.73526*10^-9, sy -> 5.88032, a -> 0.186041, b -> 0.292935}, {y0 -> 175.161, y1 -> -0.216324, y2 -> 0.00129499, y3 -> -2.53724*10^-6, y4 -> 1.6346*10^-9, sy -> 6.31835, a -> 0.207331, b -> 0.29263}, {y0 -> 219.418, y1 -> -0.146834, y2 -> 0.000903935, y3 -> -1.76892*10^-6, y4 -> 1.11553*10^-9, sy -> 5.16709, a -> 0.246005, b -> 0.292465}, {y0 -> 263.825, y1 -> -0.0721467, y2 -> 0.000454634, y3 -> -9.13689*10^-7, y4 -> 5.80904*10^-10, sy -> 4.6724, a -> 0.271664, b -> 0.292343}, {y0 -> 307.561, y1 -> 0.0313504, y2 -> -0.000230062, y3 -> 4.92199*10^-7, y4 -> -3.41197*10^-10, sy -> 4.70917, a -> 0.265807, b -> 0.292388}, {y0 -> 351.353, y1 -> 0.111996, y2 -> -0.000739691, y3 -> 1.48542*10^-6, y4 -> -9.68673*10^-10, sy -> 5.46529, a -> 0.236075, b -> 0.292496}, {y0 -> 393.196, y1 -> 0.174529, y2 -> -0.000967397, y3 -> 1.69454*10^-6, y4 -> -9.70441*10^-10, sy -> 6.22441, a -> 0.193682, b -> 0.292795}, {y0 -> 435.257, y1 -> 0.187255, y2 -> -0.000874856, y3 -> 1.35374*10^-6, y4 -> -7.22933*10^-10, sy -> 6.19187, a -> 0.199524, b -> 0.292738}, {y0 -> 475.104, y1 -> 0.158682, y2 -> -0.000352023, y3 -> -2.07054*10^-7, y4 -> 5.87065*10^-10, sy -> 5.55553, a -> 0.140875, b -> 0.293453}} сам по себе, особенно на краях, фит немного не справился, Show[ImageReflect[gr], Plot[((y0 + y1*x + y2*x^2 + y3*x^3 + y4*x^4) /. #) & /@ {fit}, {x, 1, Length[grd[[1]]]}, PlotStyle -> {Red, Thick}]] надо ему аккуратнее подсказывать начальные условия, ну или картинку с нормальной освещённостью снять. останется сделать то же самое по вертикали, получится dx,dy от (x,y) и потом вывернуть полиномы для обратного преобразования. но вот делать это полностью автоматически без подсказок внутри esp32 я бы не стал, на время калибровки wifi/синезуб поднять для получения картинки будет имхо куда проще. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexunder 4 9 сентября, 2022 Опубликовано 9 сентября, 2022 · Жалоба On 9/8/2022 at 9:38 AM, iiv said: хочется из говна и палок, ибо бюджет не позволяет. можно на RPi 3 поднять, эта модель уже менее популярна и стоит наверное от силы 30-40 евро, не сильно дороже вашего модуля. Зато можно сделать, как @_pv показал, с OpenCV или библиотекой на ваш выбор. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 9 сентября, 2022 Опубликовано 9 сентября, 2022 · Жалоба 28 minutes ago, alexunder said: можно на RPi 3 поднять, то, что я описал и в esp32 упихать можно попробовать. но если всё равно придётся вытаскивать картинку наружу, то проще на телефон "калибровку" переложить, тем более что если это действителньо линзы сильно кривые, возможно сделать полностью автоматическую калибровку, с единственной кнопкой "сделать за@#$%ь", которая работает железно в любых условиях будет сложнее чем "полуавтоматическую", где параметры натягиваемой сетки можно немного на ходу подкрутить руками, глядя на кривой результат, то есть добавляется ещё какой-то пользовательский интерфейс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iiv 29 10 сентября, 2022 Опубликовано 10 сентября, 2022 · Жалоба Спасибо огромное, plain, _pv, alexunder за очень полезные советы и помощь!!! Во-первых, попробовал собрать простенький стенд, где бы можно было бы максимально точно зафиксировать камеру перпендикулярно миллиметровки без ИК фильтров и повторил все измерения. Картинки у других девяти камер оказались существенно лучше, после нескольких фильтраций картинки с этих камер прилагаю ниже. Ту камеру, что я сделал первый снимок, вытащить не могу в этот стенд, так как она залита намертво и, похоже, та чудовищная дисторсия у нее возникла из-за того, что я где-то или криво ИК фильтр прикрутил, или еще как напортачил. 2 plain - спасибо, понял, что Вы имели ввиду, да, полностью согласен с Вами, на стенде измерить будет на порядки проще, а результат измерения, сгладив сразу можно в виде таблицы сохранить в esp32. 2 _pv - спасибо! Я как-то зациклился сразу дисторсию считать, а Вы как раз хорошо надоумили как это сделать правильно, чтобы оценить ее величину. 2 alexunder - спасибо, за идею про PRI3. Я думал над этим, и даже что-то пробовал. У меня там возникает только одна сложность - я не смог с камеры в реальном времени вытаскивать сам битстрим, то есть я что-то таки нашел, но оно по качеству было примерно как у esp32, то есть около 8 бит на 20Мсемплов, а когда хочется вытаскивать больше, то все ехало очень не стабильно. Удобство esp32 в моем случае в том, что я могу raw данные сразу с камеры брать, пусть в не очень супер сильном разрешении. Если бы не было дисторсии, я обработку того, что мне надо на скорости 2МПиксельные картинки по 10 фреймов в секунду на одном ядре esp32 научился обрабатывать, чтобы оставить второе ядро на прием данных и подправление дисторсии. Надо еще раз в RPI3 поиграться, возможно там удастся что-то вытащить лучше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 10 сентября, 2022 Опубликовано 10 сентября, 2022 · Жалоба картинки стали симметричными, можно и двумя-тремя радиальными коэффициентами обойтись c 1+Ki*r^2i как обычно делают. ещё для количественной оценки кривизны наверное можно просто преобразование Хафа от картинки делать и смотреть на распределение "углов" линий, после правильной коррекции там должна быть только пара узких вертикальных полос соответсвующих строго вертикальным ( \( \theta = \pi / 2 \) ) и горизонтальным линиям( \( \theta = 0 \) ). их ширина и будет показывать общую "кривость" объектива, которую и надо минимизировать подбирая коэффициенты перед r^2i. но картинку почистить надо, или хотя бы миллимитровые линии убрать, которые только дополнительный шум дают. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 11 ноября, 2022 Опубликовано 11 ноября, 2022 · Жалоба 15 лет назад работал в конторе, которая именно эти проблемы решала. Там очень любили книгу: Charles Poynton Video and HDTV Algorithms and Interfaces. У меня она есть в pdf. Здесь можно как-то переслать? Просмотрел ее. Там о другом речь идет. Я обработкой не занимался, но помню, что все геометрические проблемы решали при помощи фильтрации. Считали свертки. 1 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Джеймс 4 11 ноября, 2022 Опубликовано 11 ноября, 2022 · Жалоба 19 hours ago, Tarbal said: 15 лет назад работал в конторе, которая именно эти проблемы решала. Там очень любили книгу: Charles Poynton Video and HDTV Algorithms and Interfaces. У меня она есть в pdf. Здесь можно как-то переслать? Всё равно выложите пож-ста : ) Если она не больше 10MB то можно прикрепить к сообщению А лучше на F Т Р Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iiv 29 12 ноября, 2022 Опубликовано 12 ноября, 2022 · Жалоба Спасибо большое за интересную книжку, на зет-либе она есть, но его последнюю неделю лихорадит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 12 ноября, 2022 Опубликовано 12 ноября, 2022 · Жалоба вторая же ссылка в гугле doc.lagout.org /science/0_Computer Science/2_Algorithms/ Digital Video and HD_ Algorithms and Interfaces (2nd ed.) [Poynton 2012-02-07].pdf 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
std 8 4 декабря, 2022 Опубликовано 4 декабря, 2022 · Жалоба On 9/8/2022 at 2:38 PM, iiv said: Хочу научиться калибровать такие камеры, чтобы полностью удалить дисторсию. Дисторсия от "Distortion", искажение. Distorted - искаженный. 1. Возможно идеальное решение методом цифровой бработки сигнала и цифровой 2D фильтрации. С изучением исходной системы единичными функциями Дирака, сверткой, и получением полного отклика. Подготовкой требуемой матрицы 2D фильтра, и далее в каждом кадре покадровой быстрой сверткой. Но для микроконтроллеров это вычислительно слишком сложно. Поэтому обсуждать это далее бессмысленно. 2. Brown–Conrady, а лучше Division Model. Идём сюда https://en.wikipedia.org/wiki/Distortion_(optics)#Software_correction Далее смотрим на формулу в статье Wikipedia, сразу обращая внимание что в большинссве случаев мы имеем дело с радиальной дисторсией и "division model" (вторая ф-ла) более точна, её и советую использовать. Я это писал ~30лет назад и это работало, только оно не исправляло, а вносило искажения. Общая схема алгоритма такова: Используются 2шт. Двумерных буфера (двумерных [y][x] массива). В первом, назовем его Src[y][x], лежит исходная (искаженная) картинка. Во втором, назовем его Target[y][x] строится неискаженная (целевая) картинка. Попиксельно, в двух. вложенных циклах для каждой x,y координаты пиксели переносятся из Src в Target. Координаты пикселя Target[y][x] известны, т.к. алгоритм "бежит" по ним, тогда как Src-координаты, откуда для каждого Target-пикселя взять из Src - вычисляются. Это известно как reverse-transform. Как это указано формула для direct transform, она отыскивает выходные Target-координаты Xu, Yu для известных Xd, Yd Src-координат входного искаженного изображения. Такое пойдет только для первичного теста, так как если отыскивать координаты Target пикселей в итоге останутся дыры и дубликаты. Итоговое решение в том что мы вычисляем и программно записываем пары [Xu, Yu] и [Xd, Yd], с некоторым оверсэмплингом чтобы избежать дыр и потом чисто программно произведим реверс, чтобы для одной пары Target-координат отыскивалась одна пара Src-координат попутно программно устраняя дубликаты. Замечания по реализации. а) Xc,Yc можно принять в центр, т.е. 0,0 и отбросить. б) Координаты со знаком. Т.е. центру картинки соответствует [Xd=0, Yd=0]. Euclidian Distance r есть радиус, т.е. просто расстояние для текущего пикселя от центра картинки. в) Если есть желание зачем-то использовать не Division Model, а Brown-Conrady, то Коэффиценты Pn и члены соответствующие тангенциальной дисторсии можно попробовать отбросить, можно также попробовать отбросить все коэффициенты K2 и старше K2 (т.е. отбросить четвертые и более высокие степени), оставив для начала только вторые степени, т.е. r^2, это будет работать, тем более что для Division Model: Using this model, a single term is usually sufficient to model most cameras[9] г) Вычисленные кооординаты потребуется клиппировать. Примерный упрощенный псведо-код выполняющий direct transform коррекции дисторсии прямиком по упрощенной Division Model с single term. // K1 задано. for Yd = -1 to 1 with enough small step { for Xd = -1 to 1 with enough small step { r = sqrt(Xd*Xd + Yd*Yd); Xu = Xd / (1 + K1 * r*r); Yu = Yd / (1 + K1 * r*r); Xu_ClippedScaled = Clip( width * Xu, 0, width); Yu_ClippedScaled = Clip( height * Yu, 0, height); plot ( Xu_ClippedScaled, Yu_ClippedScaled, GetPixel(width * Xd, height * Yd) ); } } // вместо plot() вестимо StoreTableToMemory(....) . В конечном итоге для трансформации каждого кадра используется только очень быстрый код с вычисленной Transform-таблицей: Target[index] = Src[ TransformTable[index] ] . При этом таблица симметрична в квадрантах, т.е. сохранять можно всего один квадрант. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iiv 29 4 декабря, 2022 Опубликовано 4 декабря, 2022 · Жалоба 16 hours ago, std said: 1. Возможно идеальное решение методом цифровой бработки сигнала и цифровой 2D фильтрации. С изучением исходной системы единичными функциями Дирака, сверткой, и получением полного отклика. Подготовкой требуемой матрицы 2D фильтра, и далее в каждом кадре покадровой быстрой сверткой. Но для микроконтроллеров это вычислительно слишком сложно. Поэтому обсуждать это далее бессмысленно. Спасибо большое за советы! К сожалению, именно этот вариант и обсуждается, так как камера очень широкоугольная (фотки же я выше прилагал) и дисторсия простой моделью не описывается, а также нет гарантированного совмещения оси, то есть нормаль шахматной доски, нормаль поверхности сенсора и оптическая ось объектива - три не коллинеарные вектора и, скорей всего даже линейно независимые, то есть нужны степенные функции по x, y, в дополнении к степенным по r и проще иметь что-то типа 2Д сплайна. На данный момент рабочим вариантом у меня является распознавание одного или нескольких квадратиков в центре картинки через Фурье, и далее итерационное интерполирование послойно во все стороны с дальнейшим улучшением точек такой интерполяции. Пока в esp32 все влезает, так как по сути надо только одну копию картинки в psram и с десяток чисел на каждый узел сетки, что стоит около сотни кбайт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
std 8 5 декабря, 2022 Опубликовано 5 декабря, 2022 · Жалоба 2 hours ago, iiv said: На данный момент рабочим вариантом у меня является распознавание одного или нескольких квадратиков в центре картинки через Фурье, и далее итерационное интерполирование послойно во все стороны с дальнейшим улучшением точек такой интерполяции. Пока в esp32 все влезает, так как по сути надо только одну копию картинки в psram и с десяток чисел на каждый узел сетки, что стоит около сотни кбайт. Третий способ, вручную, без к-л. математики, анализа и прочего. Заработает везде и исправит любые искажения. 1. Вручную выставляем по клеточкам сетку вершин, для чего ваяем примитивный редактор, либо берем готовые софты. 2. Исходная картинка - текстура. Сетка вершин задана. 3. Софтварно текстурируем полигончики на экран в равномерную сетку. Опционально, можем гладить сетку вершин сплайном непосредственно во время движения по сетке. Произойдет (de)warping с вручную заданной картой варпа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iiv 29 5 декабря, 2022 Опубликовано 5 декабря, 2022 · Жалоба Спасибо большое, std за ответ! 9 hours ago, std said: 1. Вручную выставляем по клеточкам сетку вершин, для чего ваяем примитивный редактор, либо берем готовые софты. так я это уже запрограммировал, чтобы сделать полностью автоматически. У меня 24 камеры, для градуировки каждой надо снять хотя бы три кадра, а лучше с десяток. Представляете сколько я бы сидел карпел бы обрабатывая вручную каждый узел на шахматной доске в этих 240 картинках!!! Честно говоря, все это есть в OpenCL, но все пришлось самому перезапрограммировать, так как OpenCL в eps32 ну ни как не лез. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться