Быстрый субпиксельный лазер отмечает точкой обнаружение

Когда у Вас есть некоторые двоичные данные, которые Вы хотите поставить через сеть, Вы обычно не делаете этого, просто передав потоком биты и байты по проводу в формате .raw. Почему? потому что некоторые медиа сделаны для потоковой передачи текста. Вы никогда не знаете - некоторые протоколы могут интерпретировать Ваши двоичные данные как управляющие символы (как модем), или Ваши двоичные данные могли быть завинчены, потому что базовый протокол мог бы думать, что Вы ввели комбинацию специального символа (как то, как FTP переводит окончания строки).

Так для обхождения этого люди кодируют двоичные данные в символы. Base64 является одним из этих типов кодировки.

, Почему 64?
, поскольку можно обычно полагаться на те же 64 символа, присутствующие во многих наборах символов, и можно быть довольно уверены что попытка данных закончиться с другой стороны неповрежденного провода.

10
задан Nosredna 20 July 2009 в 17:53
поделиться

7 ответов

Если вам нужна субпиксельная точность, вы имеете дело с довольно сложной математикой. Я думаю, что эта статья заслуживает внимания. К сожалению, вам придется заплатить, чтобы увидеть его на этом сайте. Если у вас есть доступ к подходящей библиотеке, они могут получить ее для вас.

Ссылка в исходном сообщении предлагала выполнить 1000 вычислений сплайна для каждой оси - она ​​обрабатывала x и y независимо, что является Хорошо для круглых изображений, но немного не в порядке, если изображение представляет собой перекошенный эллипс. Для получения разумной оценки вы можете использовать следующее:

x c = sum (x n .f (x n )) / sum (f (x n ))

где x c - среднее значение, x n - это точка вдоль оси x, а f (x n ) - значение в точке x n . Итак, для этого:

          *
       *  *
       *  *
       *  *
       *  *
       *  *
       *  *  *
    *  *  *  *
    *  *  *  *
 *  *  *  *  *  *
------------------
 2  3  4  5  6  7 

дает:

sum (x n .f (x n )) = 1 * 2 + 3 * 3 + 4 * 9 + 5 * 10 + 6 * 4 + 7 * 1

сумма (f (x n )) = 1 + 3 + 9 + 10 + 4 + 1

x c = 128/28 = 4,57

и повторите для оси Y.

3
ответ дан 3 December 2019 в 20:06
поделиться

пробег 640 * 480 байт для поиска самого старшего байта должен выполняться в течение мс. Даже на медленных процессорах. Не нужно идти по пути шейдеров.

Я бы посоветовал оптимизировать ваш цикл. например: это действительно медленно (потому что оно выполняет умножение при каждом поиске в массиве):

byte highest=0;
foundX=-1, foundY=-1;
for(y=0; y<480; y++)
{
    for(x=0; x<640; x++)
    {
        if(myBytes[x][y] > highest)
        {
            highest = myBytes[x][y];
            foundX = x;
            foundY = y;
        }
    }
}

это намного быстрее:

byte [] myBytes = new byte[640*480];
//fill it with your image

byte highest=0;
int found=-1, foundX=-1, foundY=-1;
int len = 640*480;
for(i=0; i<len; i++)
{
    if(myBytes[i] > highest)
    {
        highest = myBytes[i];
        found = i;
    }
}
if(found!=-1)
{
    foundX = i%640;
    foundY = i/640;
}

Это не в моей голове, извините за ошибки; ^)

4
ответ дан 3 December 2019 в 20:06
поделиться

Брутфорс - это единственный реальный способ, однако ваша идея использования шейдера хороша - вы бы разгрузили проверку грубой силы с процессора, который может смотреть только на небольшой количество пикселей одновременно (примерно 1 на ядро) для графического процессора, который, вероятно, имеет более 100 немых ядер (конвейеров), которые могут одновременно сравнивать пиксели (ваш алгоритм может потребоваться немного изменить, чтобы он хорошо работал с ядрами с 1 инструкцией и многими ядрами расположение графического процессора).

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

3
ответ дан 3 December 2019 в 20:06
поделиться

Еще одна оптимизация, которую следует учитывать: если вы рисуете, то текущее положение указателя, вероятно, близко к последнему местоположению указателя. Запомните последнее записанное положение указателя между кадрами и сканируйте только область, близкую к этой позиции ... скажем, область размером 1 x 1. Только если указатель не найден в этой области, вы должны сканировать всю поверхность.

Очевидно, будет компромисс между тем, как быстро ваша программа может сканировать, и как быстро вы сможете перемещать указатель мыши до того, как камера «теряет» указатель и вынуждена перейти к медленному сканированию полного изображения. Небольшое экспериментирование, вероятно, покажет оптимальное значение.

Кстати, крутой проект.

2
ответ дан 3 December 2019 в 20:06
поделиться

Немного расфокусируйте камеру и сравните ее с нейтральным образцом. Вы можете быстро сканировать строки на предмет значений, отличных от 0. Также, если вы используете 8 бит и получаете 4 байта за раз, вы можете быстрее обрабатывать изображение. Как уже указывалось, вы можете уменьшить частоту кадров. Если у вас меньшая точность, чем получаемое изображение, нет особого смысла в высокой скорости сканирования.

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

1
ответ дан 3 December 2019 в 20:06
поделиться

Начать с черного буфера вывода. Забудьте пока о субпикселях. Каждый кадр, каждый пиксель делайте так:

outbuff = max (outbuff, inbuff);

Выполняйте субпиксельную фильтрацию для третьего «чистого» буфера, когда вы закончите с изображением. Или сделайте фрагмент или строку экрана за раз в реальном времени. Преимущество: «грубый» вид чертежа в реальном времени, очищаемый по мере продвижения.

Когда вы конвертируете из буфера грубого вывода в «чистый» третий буфер, вы можете очистить его до черного. Это позволяет вам рисовать вечно, не замедляясь.

Рисуя «чистый» поверх «грубого», может быть, немного другим цветом, вы получите лучшее из обоих миров.

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

Используйте сплайн Катмулла-Рома, который проходит через все контрольные точки.

1
ответ дан 3 December 2019 в 20:06
поделиться

Если под грубым форсированием вы имеете в виду независимый просмотр каждого пикселя, это, по сути, единственный способ сделать это. Вам придется сканировать все пиксели изображения, независимо от того, что вы хотите делать с изображением. Хотя вам может не понадобиться находить самые яркие пиксели, вы можете отфильтровать изображение по цвету (например, если вы используете красный лазер). Это легко сделать с помощью цветного изображения HSV. Если вы ищете более быстрые алгоритмы, попробуйте OpenCV. Он снова и снова оптимизировался для обработки изображений, и вы можете использовать его в C # через оболочку:

[ http://www.codeproject.com/KB/cs/Intel_OpenCV.aspx] [1]

OpenCV также может помочь вам легко найти центры точек и отслеживать каждую точку.

Является есть причина, по которой вы используете камеру со скоростью 120 кадров в секунду? вы знаете, что человеческий глаз может видеть только около 30 кадров в секунду, верно? Я предполагаю, что он должен следить за очень быстрыми движениями лазера ... Вы можете подумать о том, чтобы его отключить, потому что обработка в реальном времени 120 кадров в секунду будет очень трудной.

5
ответ дан 3 December 2019 в 20:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: