ovs_pavel 0 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба День добрый коллеги. Возник вопрос по преобразованию видео потока (grayscale, 8 бит/пиксель, 25 кадр/сек) на ПЛИС. Исходный формат - 1280х1024. Необходимый формат - 960x768. Я сделал просто и быстро (было задача главное сделать) - убрал каждую 4-ую строку и каждый четвертый пиксель в строке. Все работает и ок, но видны на косых линиях маленькие ступеньки. Поэтому и вопрос - есть ли простые (именно простые) алгоритмы аппроксимации, которые хорошо ложатся на ПЛИС (ну по соседним пикселям высчитывать новые или что-то в этом роде). Можно ссылку на литературу (не занимался видео обработкой даже в таком простом виде, поэтому и сделал все в лоб). Заранее спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Например, "распределить" каждые 4 входные точки на 3 выходные, линейно: X1 = (3x1 + x2) / 4; X2 = (2x2 + 2x3) / 4; X3 = (x3 + 3x4) / 4; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aat_81 0 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Можно воспользоваться вот этим http://opencores.org/project,video_stream_scaler Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ovs_pavel 0 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Например, "распределить" каждые 4 входные точки на 3 выходные, линейно: X1 = (3x1 + x2) / 4; X2 = (2x2 + 2x3) / 4; X3 = (x3 + 3x4) / 4; Не совсем ясно, где какой пиксел на сколько умножать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Не совсем ясно, где какой пиксел на сколько умножать. Входные: x1, x2, x3, x4 Выходные: X1, X2, X3 Еще то же нужно сделать по координате Y. Получается, из матрицы 4 x 4 нужно сделать 3 x 3. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 16 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Не совсем ясно, где какой пиксел на сколько умножать. Для линейной интерполяции: P'[0] = P[0]; P'[1] = (2/3)*P[1]+(1/3)*P[2]; P'[2] = (1/3)*P[2]+(2/3)*P[3]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ovs_pavel 0 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Для линейной интерполяции: P'[0] = P[0]; P'[1] = (2/3)*P[1]+(1/3)*P[2]; P'[2] = (1/3)*P[2]+(2/3)*P[3]; А эта формула с какого-то источника?? И здесь я так понимаю из входных 4-ех пикселей, мы получаем 3 выходных? И соответственно по 4-ем строкам та же формула. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Для линейной интерполяции: Это не будет равномерным размазыванием 4-х пикселов на 3. Входные пикселы используются с разным весом. Возможно, и заметно не будет, но... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 16 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба И здесь я так понимаю из входных 4-ех пикселей, мы получаем 3 выходных? Обозначив расстояние между пикселями в исходном формате как "d", а расстояние между пикселями в новом формате как "D", находим: 1280*d = 960*D. Откуда: D - d = (1280/960)*d - d = (4/3)*d - d = (1/3)*d. Предполагаем, что все пиксели кратные трем в новом формате совпадают с пикселями кратными четырем в старом формате, тогда: P'[3*n] = P[4*n]. Для остальных пикселей P'[1] и P'[2] (и им подобных) в новом формате видим, что: P'[1] расположен между P[1] и P[2], причем так, что расстояние от P'[1] до P[1] равно (1/3)*d, а расстояние от P'[1] до P[2] равно (2/3)*d, и P'[2] расположен между P[2] и P[3], причем так, что расстояние от P'[2] до P[2] равно (2/3)*d, а расстояние от P'[2] до P[3] равно (1/3)*d. Используя далее линейную интерполяцию, находим значения P'[1] и P'[2]. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Например, "распределить" каждые 4 входные точки на 3 выходные, линейно: X1 = (3x1 + x2) / 4; X2 = (2x2 + 2x3) / 4; X3 = (x3 + 3x4) / 4; Чтобы сохранить яркость прежней, нужно умножить все на 3/4. X[1] = (9x[1] + 3x[2]) / 16; X[2] = (6x[2] + 6x[3]) / 16; X[3] = (3x[3] + 9x[4]) / 16; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Чтобы сохранить яркость прежней, нужно умножить все на 3/4. X[1] = (9x[1] + 3x[2]) / 16; X[2] = (6x[2] + 6x[3]) / 16; X[3] = (3x[3] + 9x[4]) / 16; x[1] = 255, x[2] = 255 -> X[1] = 191. первый вариант правильный был, оно уже на 3/4 умножено X1 = (3x1 + x2) / 4; X2 = (2x2 + 2x3) / 4; X3 = (x3 + 3x4) / 4; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба x[1] = 255, x[2] = 255 -> X[1] = 191. первый вариант правильный был, оно уже на 3/4 умножено Да, что-то я перемудрил. :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба Предполагаем, что все пиксели кратные трем в новом формате совпадают с пикселями кратными четырем в старом формате, тогда: P'[3*n] = P[4*n]. у них размеры разные. если P[0] = 255, а P[1] = 0, то P'[0] должен быть темнее на четверть, а не таким же. поэтому P'[0] = (P[0] + P[1] / 3) / 1.33333333 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 16 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба первый вариант правильный был, оно уже на 3/4 умножено ИМХО, тоже неправильный. Вот если взять линейную входную последовательность и преобразовать, то выходная последовательность будет уже нелинейной.. Имеем входную последовательность: x[1] = 1, x[2] = 2, x[3] = 3, x[4] = 4, x[5] = 5, x[6] = 6. Считаем по формуле: X[1] = (3*x[1] + 1*x[2]) / 4; X[2] = (2*x[2] + 2*x[3]) / 4; X[3] = (1*x[3] + 3*x[4]) / 4; X[4] = (3*x[5] + 1*x[6]) / 4; X[5] = (2*x[6] + 2*x[7]) / 4; X[6] = (1*x[7] + 3*x[8]) / 4; Находим выходную последовательность: X[1] = (3*1 + 1*2) / 4 = 5/4; X[2] = (2*2 + 2*3) / 4 = 10/4; X[3] = (1*3 + 3*4) / 4 = 15/4; X[4] = (3*5 + 1*6) / 4 = 21/4; Находим разницу между последовательными значениями: X[2]-X[1] = 5/4; X[3]-X[2] = 5/4; X[4]-X[3] = 6/4; То есть, на выходе уже нет линейной зависимости.. Как быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 24 марта, 2015 Опубликовано 24 марта, 2015 · Жалоба ИМХО, тоже неправильный. То есть, на выходе уже нет линейной зависимости.. ах так, у Вас зато интегралы не сохраняются. бе-бе-бе :) подайте дельта функцию (один пиксел белый все остальные чёрные), в зависимости от его положения интенсивность получивщейся картинки будет неправильная. или подайте не линейную функцию, а какую-нибудь другую, например параболу и Ваша линейная интерполяция тоже врать начнёт. просто Вы потребовали чтобы линейная функция отображалась в линейную, а ViKo чтобы интегралы сохранялись. что будет лучше выглядеть зависит от картинки, если там очень плавные градиенты то наверное лучше будет от сохранения линейности (в jpege кстати косинусное преобразование именно по этой причине выбрано), а если куча резких переходов, и векторная графика то они с такой линейной интерполяцией не совсем правильно сгладятся. и вертикальная линия в один пиксел под небольшим углом заметно испортится. а можно порядок интерполирующей кривой повыше взять, параболу там по трём точкам или куб по четырём и всё станет заметно красивее, считать придётся чуть побольше, но не сильно. ну или даже так: http://www.dsplib.ru/content/farrow/farrow.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться