В случае векторных букв антиалиасинг не очень-то будет и нужен, нежатого однобитного битмапа вполне хватит. Вместо существующего растеризатора я бы вспомнил спектрум и сделал на Си свой велосипед — благо, только для отрезков с одним цветом заливки это совсем несложно.
Совсем недорого, если вы будете искажать не пиксельную карту, а векторное представление шрифта (и сетки, если захотите).
В самом простом случае, без применения сплайнов или кривых Безье, считайте, что буквы состоят из замкнутой цепи направленной отрезков, узловые точки которого вы определяете с высокой плотностью. Допустим, что при движении по часовой стрелке, область, ограниченная этими отрезками, заполняется цветом тела, а при движении против часовой стрелки — цветом фона, это даст вам возможность создавать дырки в буквах (например, в «б») и цифрах («8»).
Таким образом, перед построением капчи у вас должны быть в распоряжении несколько массивов узловых точек, с указанием направления (CW/CCW) для каждого из массивов. Координаты каждой точки, вне зависимости от принадлежности к какому-либо массиву, вы умножаете на ту же матричную функцию, что у вас использовалась для искажения оригинального изображения на попиксельной основе.
Затем скармливаете вашей графической библиотеке по очереди все полигоны с цветом тела, затем с цветом дырок. Можно, конечно, делать еще и occlusion mapping, но я не помню ни в кириллице, ни в латинице букв с двумя областями связности, одна из которых находилась бы в «дырке» от другой, так что это будет немного перебором.
Экономия будет значительной, даже с расходами на растеризацию полигонов — вам все-таки нужно умножать не каждый пиксель, а только узловые точки векторых букв. Пиксельное зашумление можно добавить в пост-обработке.
Если бы добавить немного антиалиасинга, хотя бы x4 (а лучше x8, т.к. у вас довольно сильные искажения), то было бы уже лучше — как минимум в последнем варианте. Первый из трех вообще нечитаем, у второго нечитаемы отдельные буквы, если их «раздувает» так, что они превращаются в одно пятно.
На самом деле список «отправили» нужно обновлять раз в сутки, тогда деанонимизировать будет намного-намного труднее, а информационность значительно увеличится.
Вы так говорите, как будто что-то плохое! В конце-концов, я отличаюсь в положительную сторону от тех, кто наворует аккаунтов, понарегистрирует детей с 0 постов 0 комментариев, поуказывает у них один адрес и сидит и получает подарки, тварюка.
Отправил подарки за себя и за братца (братец еще не нажал на кнопку «я отправил», т.к. спит). Ждите, что уж. // Надо бы еще открытки вслед отправить, но это если у меня получится на почту выбраться...
Откуда вообще взялось утверждение о том, что палочки и колбочки реагируют не на каждый фотон, а имеют какую-то частоту генерации исходящего сигнала? Мерцание в глазах после монитора объясняется усталостью, а не синхронизацией — ради проверки включите вентилятор, и посидите сначала в темноте при стробоскопическом источните света, а затем при лампе накаливания — никакого зрительного пост-эффекта не будет, чего не скажешь о головной боли.
Смотрел, в случае освещения постоянным источником света — солнцем или лампой накаливания, изображение всегда размыто равномерно, никаких полос повышенной или пониженной плотности нет, как и дискретизации изображения. Если же освещать газоразрядной лампой, то полосы, конечно же, будут, но фактически это стробоскоп, не имеющий отношения к механике человеческого зрения.
Говорить о «частоте считывания» несколько неверно — передача сигнала оптическим нервом идет постоянно и недискретно, тут, скорее, если представить сетчатку в виде люминофорного экрана, речь идет о времени послесвечения — чем больше время послесвечения, тем больше времени потребуется единожды возбужденному «пикселю» на то, чтобы перейти в неактивное состояние. Таким образом, продолжая эту аналогию, все изображения, которые поступают на сетчатку, суммируются по времени, где самые старые изображения имеют наименьший вес (т.к. сигнал почти угас), а новые — наибольший.
В качестве подтверждения этого эффекта возьмите любой маленький яркий точечный источник света и покрутите его в полной темноте у себя перед глазами. Если бы зрение было дискретным без суммирования (съемка с маленькой выдержкой и высокой чувствительностью), то вы бы увидели несколько лампочек в разных фазах прохождения траектории вращения. Если бы зрение было дискретным с суммированием (каждые, к примеру, 1/24 секунды снимается заряд с «матрицы», и значения накопленного заряда во всех пикселях обнуляется), то вы бы видели полосы одинаковой яркости, длина которых зависела бы от скорости вращения источника света, и которые бы следовали одна за одной — т.е. новая полоса начиналась бы там, где заканчивалась предыдущая, и вы никогда бы не видели две полосы одновременно. В реальности же вы увидите полосы спадающей яркости, которые будут тем длиннее, чем быстрее вращается источник света, что полностью соответствует «люминофорному» предположению.
«цепи направленных отрезков, узловые точки которых», конечно же. Не знаю, что на меня нашло.
В самом простом случае, без применения сплайнов или кривых Безье, считайте, что буквы состоят из замкнутой цепи направленной отрезков, узловые точки которого вы определяете с высокой плотностью. Допустим, что при движении по часовой стрелке, область, ограниченная этими отрезками, заполняется цветом тела, а при движении против часовой стрелки — цветом фона, это даст вам возможность создавать дырки в буквах (например, в «б») и цифрах («8»).
Таким образом, перед построением капчи у вас должны быть в распоряжении несколько массивов узловых точек, с указанием направления (CW/CCW) для каждого из массивов. Координаты каждой точки, вне зависимости от принадлежности к какому-либо массиву, вы умножаете на ту же матричную функцию, что у вас использовалась для искажения оригинального изображения на попиксельной основе.
Затем скармливаете вашей графической библиотеке по очереди все полигоны с цветом тела, затем с цветом дырок. Можно, конечно, делать еще и occlusion mapping, но я не помню ни в кириллице, ни в латинице букв с двумя областями связности, одна из которых находилась бы в «дырке» от другой, так что это будет немного перебором.
Экономия будет значительной, даже с расходами на растеризацию полигонов — вам все-таки нужно умножать не каждый пиксель, а только узловые точки векторых букв. Пиксельное зашумление можно добавить в пост-обработке.
// Надо бы еще открытки вслед отправить, но это если у меня получится на почту выбраться...
Говорить о «частоте считывания» несколько неверно — передача сигнала оптическим нервом идет постоянно и недискретно, тут, скорее, если представить сетчатку в виде люминофорного экрана, речь идет о времени послесвечения — чем больше время послесвечения, тем больше времени потребуется единожды возбужденному «пикселю» на то, чтобы перейти в неактивное состояние. Таким образом, продолжая эту аналогию, все изображения, которые поступают на сетчатку, суммируются по времени, где самые старые изображения имеют наименьший вес (т.к. сигнал почти угас), а новые — наибольший.
В качестве подтверждения этого эффекта возьмите любой маленький яркий точечный источник света и покрутите его в полной темноте у себя перед глазами. Если бы зрение было дискретным без суммирования (съемка с маленькой выдержкой и высокой чувствительностью), то вы бы увидели несколько лампочек в разных фазах прохождения траектории вращения. Если бы зрение было дискретным с суммированием (каждые, к примеру, 1/24 секунды снимается заряд с «матрицы», и значения накопленного заряда во всех пикселях обнуляется), то вы бы видели полосы одинаковой яркости, длина которых зависела бы от скорости вращения источника света, и которые бы следовали одна за одной — т.е. новая полоса начиналась бы там, где заканчивалась предыдущая, и вы никогда бы не видели две полосы одновременно. В реальности же вы увидите полосы спадающей яркости, которые будут тем длиннее, чем быстрее вращается источник света, что полностью соответствует «люминофорному» предположению.