Учитывая, что никто не упомянул об этом ...
Некоторые языки высокого уровня, такие как Python и Java, поставляются с инструментами для преодоления ограничений двоичной с плавающей запятой. Например:
decimal
Python [и g0] и класс BigDecimal
Java [], которые представляют числа внутри с десятичной нотацией (в отличие от двоичная запись). Оба имеют ограниченную точность, поэтому они все еще подвержены ошибкам, однако они решают наиболее распространенные проблемы с бинарной арифметикой с плавающей запятой. Десятичные числа очень хороши при работе с деньгами: десять центов плюс двадцать центов всегда ровно тридцать центов: >>> 0.1 + 0.2 == 0.3
False
>>> Decimal('0.1') + Decimal('0.2') == Decimal('0.3')
True
Модуль decimal
Python основан на стандарте IEEE стандарта 802.118 . fractions
модуль и класс Apache Common BigFraction
. Оба представляют собой рациональные числа как пары (numerator, denominator)
, и они могут давать более точные результаты, чем десятичная арифметика с плавающей запятой. Ни одно из этих решений не идеально (особенно, если мы смотрим на выступления, или если мы требуют очень высокой точности), но все же они решают большое количество проблем с двоичной арифметикой с плавающей запятой.
Вот математическое объяснение аффинного преобразования: это матрица размера 3x3, которая применяет преобразования foolowing на 2D-векторе: масштаб по оси X, scaleY, вращение, перекос, перевод по оси x и y. Это 6 преобразований, и поэтому у вас есть шесть элементов в вашей матрице 3x3. Нижняя строка всегда [0 0 1]. Зачем? потому что нижняя строка представляет собой перспективное преобразование по оси x и y, а аффинное преобразование не включает перспективное преобразование. (Если вы хотите применить перспективное деформирование, используйте гомографию: также матрица 3x3)
Какова связь между 6 значениями, которые вы вставляете в аффинную матрицу и с помощью 6 преобразований, которые она делает? Посмотрим на эту матрицу 3x3, такую как
e*Zx*cos(a), -q1*sin(a) , dx,
e*q2*sin(a), Z y*cos(a), dy,
0 , 0 , 1
Приведенное выше объяснение математическое. Предполагается, что вы умножаете матрицу на вектор столбца справа. Насколько я помню, Matlab использует обратное умножение (вектор строки слева), поэтому вам придется транспонировать эту матрицу. Я уверен, что openCV использует регулярное умножение, но вам нужно его проверить. Просто введите только матрицу перевода (x сдвинуто на 10 пикселей, y на 1).
1,0,10
0,1,1
0,0,1
Если вы видите нормальный сдвиг, чем все в порядке, но если появляется дерьмо, чем транспонирование матрицы:
1,0,0
0,1,0
10,1,1