Программа для поворота изображения на любой угол: Rotation Pilot — Rotation Pilot 1.00

Прецизионный поворот растрового изображения на произвольный угол / ХабрПоворот растрового изображения на углы, кратные 90°, относительно геометрического центра изображения – задача тривиальная и решается без потери качества простым преобразованием координат каждого пикселя.

Для поворота растрового изображения на произвольный угол разработаны быстрые но не оптимальные алгоритмы, дающие приемлемую для практических целей аппроксимацию с потерей качества (например, этот).
Довольно давно, из чисто спортивного интереса, меня заинтересовала задача максимально точного поворота растрового изображения на произвольный угол. К сожалению, мне нигде не удалось найти готовый алгоритм, поэтому пришлось делать его собственноручно. Даже если в итоге я «изобрёл велосипед», результат, как мне кажется, получился достаточно интересным, чтобы им можно было поделиться.

Ниже мы рассмотрим алгоритм прецизионного поворота растрового изображения на произвольный угол относительно произвольного центра с минимальными потерями.

Выражаю благодарность Харченко Владиславу Владимировичу за оказанную помощь.

Содержание

Алгоритм


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

В качестве модели пикселя исходного изображения мы будем использовать квадрат со стороной = 1, с такими обозначениями углов:

i1 — самый правый угол;
i2 — самый нижний угол;
i3 — самый левый угол;
i4 — самый верхний угол.

Моделью итогового изображения будет сетка из параллельных горизонтальных и вертикальных линий с расстоянием между линиями = 1.

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

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

Поворот растрового изображения можно разделить на две части:
1. Поворот квадрата каждого пикселя исходного изображения относительно центра этого квадрата на заданный угол.
2. Смещение центра квадрата пикселя в соответствии с углом поворота изображения относительно центра поворота изображения таким образом, чтобы квадрат занял своё итоговое положение на сетке итогового изображения.
При этом сетка итогового изображения рассекает квадрат каждого пикселя исходного изображения на «осколки» в количестве 4, 5 или 6 штук.

Чтобы систематизировать разнообразие получающихся вариантов мне пришлось составить таксономию всевозможных пересечений квадрата пикселя исходного изображения с сеткой итогового изображения. Существенно разных вариантов оказалось всего 23:


Условные обозначения здесь следующие:
— цифры в ячейках обозначают номера углов квадрата пикселя, которые попали в данную ячейку сетки итогового изображения после поворота изображения;
— зелёным цветом обозначены ячейки, в которые попали участки пикселя и гарантированно оставили там по «осколку»;
— жёлтым цветом обозначены ячейки, в которые, в зависимости от условий,

могут попасть (а могут и не попасть) «осколки» квадрата пикселя, образованные не углами квадрата, а сторонами квадрата.

Для наглядности приведу одну из возможных вариаций варианта №3:

Как видим, верхняя правая ячейка не содержит в себе «осколка» пикселя, хотя при других условиях поворота могла бы содержать.
Чтобы не нагружать читателя детальными геометрическими выкладками, скажу сразу, что во всех этих 23-х вариантах пиксель исходного изображения рассекается на «осколки», площадь которых легко вычисляется комбинированием 4-х формул. Ниже приведены эти формулы с иллюстрациями. Красным цветом обозначены линии сетки итогового изображения, которые рассекают квадрат пикселя. Жёлтым цветом закрашена область, площадь которой вычисляется формулой.

Формула 1

Эта формула не используется для расчёта окончательной площади «осколка», но её удобно использовать для быстрого расчёта вспомогательных промежуточных площадей, поскольку нам заведомо известно, что площадь всего пикселя = 1.
В качестве входных переменных во всех формулах используются высоты, опущенные из углов квадрата на сетку итогового изображения, по той простой причине, что расчёт этих высот сводится к мгновенному выделению дробной части числового значения координаты соответствующего угла квадрата пикселя.
Формула 2


Данная формула используется только в вариантах 1 и 2.
Формула 3

Часто используемая формула — очень хорошо, что она быстро вычисляется. Поскольку угол поворота одинаков для каждого пикселя — все тригонометрические функции можно посчитать один раз, перед обработкой всех пикселей, и далее использовать эти значения в цикле как константы.
Формула 4

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

С учётом всего вышесказанного, в общем виде алгоритм будет выглядеть так:
1. Загружаем в память ЭВМ исходное изображение.
2. Рассчитываем размеры итогового изображения в пикселях.

3. Создаём промежуточный двумерный массив, каждый элемент которого содержит 3 составляющие цвета RGB в формате числа с плавающей запятой. Размеры массива равны размерам итогового изображения.
4. Последовательно перебираем все пиксели исходного изображения; поворачиваем каждый из них на заданный угол и располагаем на сетке итогового изображения, рассчитав 4 координаты углов квадрата пикселя; классифицируем пиксель по 23 вариантам и считаем площади «осколков»; добавляем в соответствующие элементы промежуточного массива цвета полученных «осколков» пропорционально площади этих «осколков».
5. После обработки всех пикселей исходного изображения округляем значения RGB в промежуточном массиве до целого значения для каждого элемента и создаём на базе этих целых значений итоговое изображение в формате BMP.

Программа


На основании приведённого алгоритма была написана программа для Windows. Исходные коды на Object Pascal и скомпилированный исполняемый файл можно скачать здесь.

Интерфейс программы.
По нажатию на кнопку «Open…» открывается диалог выбора BMP-файла. Поддерживаются битмапы только с 24-битной палитрой. Открытое изображение отображается в окне. В заголовке окна выводится полный путь к файлу и размеры изображения.

В поле «Angle» задаётся угол поворота в градусах – любое положительное число.

В качестве десятичного разделителя при вводе дробных чисел может быть использована как точка, так и запятая.

Радиокнопками «CW» и «CCW» задаётся направление вращения: «по часовой стрелке» и «против часовой стрелки», соответственно.

В блоке «Background color» можно задать цвет фона, с которым будут смешиваться граничные пиксели изображения. По умолчанию цвет фона – чёрный.

В полях «Centre X» и «Centre Y» задаются координаты центра поворота. При этом следует учитывать, что начало координат находится в левом верхнем углу изображения и Y увеличивается вниз. По умолчанию центр поворота устанавливается в геометрическом центре загруженного изображения.

По нажатию на кнопку «Rotate» либо по нажатию на клавишу Enter изображение поворачивается на заданный угол относительно заданного центра поворота и отображается в окне. Поворот изображения на углы, кратные 90°, реализован по упрощённой схеме, путём простого преобразования координат пикселей исходного изображения, при этом значения «Centre X» и «Centre Y» игнорируются.

Время работы алгоритма в секундах отображается под кнопкой «Rotate».

Через кнопку «Save…» повёрнутое изображение можно сохранить в BMP-файл.

Если итоговое изображение не помещается в окне – оно подгоняется к границам окна API-функцией StretchBlt – поэтому оценить реальное качество больших картинок можно только по сохранённому BMP-файлу.
Для поворота изображения на другой угол его не нужно загружать повторно — поворачивается изображение из выбранного файла, а не отображённое в данный момент в окне.

Изображение с размерами 1024 х 768 на машине с четырёхядерным процессором 2,67 ГГц поворачивается данной программой на произвольный угол, в среднем, приблизительно, за 0,5 секунды. Изображение с размерами 4000 х 4000 — примерно за 10 секунд. Время работы алгоритма для разных углов может отличаться в связи с тем, что изображение при разных углах дробится на разное количество «осколков», на вычисление площадей которых суммарно тратится, соответственно, разное время.

Промежуточный массив, содержащий информацию о цвете пикселей итогового изображения в формате числа с плавающей запятой, реализован на типе extended (10 байт), поэтому обработка больших изображений (примерно более 5000 х 5000 пикселей) может вызвать ошибку переполнения памяти. Улучшить ситуацию возможно, применив менее точный тип данных и сохраняя целую часть числа сразу в итоговый битмап, оставляя во вспомогательном массиве только дробную часть.

Результаты


Проведём сравнительный анализ работы прецизионного алгоритма и алгоритма поворота изображений, реализованного в программе Photoshop.
Тест 1

Для первого теста я взял очень простое изображение — горизонтальную линию чёрного цвета толщиной 1 пиксель и длиной 10 пикселей, смещённую относительно центра белого квадрата с размерами 100 х 100 пикселей:

После чего я повернул данное изображение относительно точки с координатами (0, 0) на 3° по часовой стрелке. Точка (0, 0) выбрана потому, что, судя по моим экспериментам, Photoshop поворачивает изображение относительно именно этой точки. Вот сравнительный результат (увеличено в 24 раза):

Прецизионный алгоритм

Photoshop 7.0.1

Photoshop CS6 (64 Bit)
Алгоритм Photoshop даёт более контрастную картинку, прецизионный алгоритм несколько «размывает» изображение. Но в целом, при визуальной оценке, результат получается почти одинаковым. Попутно отметим, что алгоритм поворота, реализованный в Photoshop, не претерпел за 10 лет существенных изменений.

Тест 2

Для второго теста я выбрал тюльпан из стандартного дистрибутива Win7:

После поворота данного изображения на 5° по часовой стрелке относительно геометрического центра я суммировал цвет всех пикселей в разрезе каналов RGB. Вот результат для прецизионного алгоритма и алгоритма Photoshop:

Оригинал
Прецизионный поворот
(до округления)
Прецизионный поворот
(после округления)
Photoshop CS6
R = 33381406
G = 27933900
B = 11239213
R = 33381406,0000004 (~0)
G = 27933899,9999997 (~0)
B = 11239212,9999999 (~0)
R = 33382786 (1380)
G = 27933920 (20)
B = 11238086 (-1127)
R = 33387726 (6320)
G = 27950823 (16923)
B = 11245937 (6724)
Числа в скобках показывают абсолютное отклонение данного показателя от оригинала.
Цвет изображения после прецизионного поворота и до округления практически не поменялся — чего и следовало ожидать.
Самое большое отклонение, в данном конкретном случае, мы обнаруживаем по каналу G для алгоритма Photoshop. В процентном отношении это отклонение составляет всего 0,06%, поэтому «на глаз» оно не заметно, но из соображений перфекционизма результат у Photoshop получается хуже, чем у прецизионного алгоритма.
Важно отметить, что округление цвета каждого пикселя в прецизионном алгоритме до целочисленного значения, необходимого для формата BMP, необратимо уничтожает часть информации о цвете.

Для визуального сравнения двух алгоритмов приведу увеличенный фрагмент изображения,

повёрнутого на 5° по часовой стрелке, соответственно, Photoshop’ом:

и прецизионным алгоритмом:

Сравнительный анализ показывает, что Photoshop лучше сохраняет контрастные элементы изображения, но при этом создаёт «ореолы» искажённого цвета. Прецизионный алгоритм не искажает цвет но при этом несколько «размывает» изображение.

Выводы


1. Прецизионный и при этом сравнительно быстрый поворот растрового изображения на произвольный угол — возможен. Для меня остаётся загадкой вопрос, почему в профессиональных графических редакторах нет опции, позволяющей пользователю повернуть изображение предельно точно за чуть большее время.

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

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

UPD: Для практического использования написал программу, реализующую упрощённый алгоритм, в котором для каждого пикселя итогового изображения все необходимые кусочки пикселей исходного изображения рассчитываются последовательно и округление цвета происходит немедленно. Только после этого рассчитывается следующий пиксель итогового изображения. При этом к отдельному пикселю исходного изображения программа обращается несколько раз. Время расчётов, таким образом, увеличилось, в среднем, в 1,7 раз, но память в этой версии алгоритма расходуется только на хранение битмапов, что позволяет работать с изображениями больших размеров. Скачать программу и исходники можно здесь.

Как повернуть снятое видео на любой угол и сохранить его на ПК

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

В инструкции ниже мы расскажем, как быстро повернуть видео на 90 градусов или на любой другой угол – в зависимости от того, как вы держали камеру во время съёмки. Мы также покажем, как применить эффект вращения, если вы хотите, чтобы видео плавно поворачивалось по часовой или против часовой стрелки во время проигрывания.

Чтобы повторить всё описанное в инструкции, вам необходимо скачать и установить видеоредактор VSDC на свой компьютер. Это абсолютно бесплатная программа для Windows ПК, и если вы нередко нуждаетесь в инструменте для корректировки отснятых материалов, VSDC пригодится вам ещё не раз.

Cкачать видеоредактор VSDC

Как повернуть видео на 90 градусов и сохранить его на компьютере

Итак, в VSDC доступны 2 опции: стандартный поворот видео на 90 градусов по часовой и против часовой стрелки, а также «эффект вращения». Начнём с первого.

Запустите программу и импортируйте нужный видеофайл. В верхнем меню «Удаление и разбивка» вы увидите две кнопки для поворота видео на 90 градусов. Щелкните по той, что соответствует необходимому направлению, и вы моментально увидите желаемый результат.

Как повернуть видео на заданный угол

Иногда вам может понадобиться повернуть снятое видео на угол, отличный от 90 и 180 градусов. Это может быть вызвано как небольшим наклоном камеры во время съёмки, так и желанием создать эффект видео, снятого под наклоном. Вот как сделать это в VSDC:

  1. Добавьте видео на сцену привычным способом.
  2. Перейдите во вкладку Видеоэффекты —> Трансформация —> Вращение.
  3. Как только вы выберете этот эффект, на экране появится всплывающее окно с параметрами позиции объекта. Нажмите ОК.
  4. На временной шкале вы заметите новую вкладку, на которой будет размещён слой под названием «Вращение 1».
  5. Правой кнопкой мышки щёлкните по нему и выберите Свойства.
  6. В Окне свойств, прокрутите бегунок вниз до поля «Угол поворота» и задайте желаемые параметры, как это показано на иллюстрации ниже.

Как повернуть кадр в видео в определённый момент времени во время проигрывания

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

  1. Разместите курсор на временной шкале непосредственно в тот момент, в который вы планируете применить эффект вращения.
  2. Перейдите во вкладку Видеоэффекты —> Трансформация —> Вращение.
  3. В этот раз, однако, когда на экране появится всплывающее окно с параметрами позиции объекта, выберите «От позиции курсора».
  4. Затем откройте Окно свойств и настройте угол поворота.

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

Как применить усложнённый эффект вращения к видео

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

Для того, чтобы начать, снова примените видеоэффект Трансформация —> Вращение и откройте Окно свойств. В Окне свойств щёлкните на иконку “…”, расположенную напротив параметра «Угол поворота». На шкале времени откроется новая вкладка – в ней вы будете строить траекторию вращения объекта, а также сможете задать темп и направление.

В первую очередь вам необходимо выбрать тип траектории. Чтобы сделать это, нажмите на иконку в виде горизонтальной черты. Она расположена между полем “Угол поворота” и кнопкой “…”. После нажатия на шкале времени вы заметите ровную линию – это текущая траектория вращения. Чтобы изменить её, вам необходимо добавить направляющие точки – это делается двойным щелчком мыши по пространству над или под траекторией. Размещая новую точку над траекторией, вы задаёте направление вращения по часовой стрелке, а под траекторией – против. Выбрав любую из уже добавленных точек, вы также можете перетаскивать их в нужные позиции, а чтобы удалить одну из них – используйте иконку «Удалить выбранное значение параметра» в меню инструментов над шкалой времени.

Как обычно, проверять результат удобнее всего с помощью функции предпросмотра.

Теперь вы знаете, как повернуть видео на 90 градусов, перевернуть снятое видео на 180 градусов, а также на любой другой угол единым действием или постепенно.

Мы подобрали ещё три инструкции по работе с VSDC, которые могут вас заинтересовать:

Subscribe to our YouTube channel and message us on Facebook if you have any questions!


ориентация в EXIF / Хабр

Я много писал о проектах компьютерного зрения и машинного обучения, таких как системы распознавания объектов и проекты распознавания лиц. У меня также есть опенсорсная библиотека распознавания лиц на Python, которая как-то вошла в топ-10 самых популярных библиотек машинного обучения на Github. Всё это привело к тому, что новички в Python и машинном зрении задают мне много вопросов.

По опыту, есть одна конкретная техническая проблема, которая чаще всего ставит людей в тупик. Нет, это не сложный теоретический вопрос или проблема с дорогими GPU. Дело в том, что почти все загружают в память изображения повёрнутыми, даже не подозревая об этом. А компьютеры не очень хорошо обнаруживают объекты или распознают лица в повёрнутых изображениях.


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

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

Это уже забота программы для просмотра — правильно повернуть картинку, прежде чем отобразить её на экране. Наряду с данными самого изображения, камера также сохраняет метаданные — настройки объектива, данные о местоположении и, конечно, угол поворота камеры. Программа просмотра должна использовать эту информацию для правильного отображения.

Наиболее распространённый формат метаданных изображений называется EXIF (сокращение от Exchangeable Image File Format). Метаданные в формате EXIF внедряются в каждый файл jpeg. Вы не можете их видеть на экране, но они читаются любой программой, которая знает, где искать.

Вот метаданные EXIF внутри JPEG-изображения нашего гуся из инструмента exiftool:

Видите элемент ‘Orientation’? Он говорит программе просмотра, что перед отображением на экране картинку следует повернуть на 90 градусов по часовой стрелке. Если программа забудет это сделать, изображение будет на боку!


Метаданные EXIF изначально не были частью формата JPEG. Их внедрили гораздо позже, позаимствовав идею из формата TIFF. Для обратной совместимости эти метаданные не обязательны, а некоторые программы не утруждают себя их разбором.

Большинство библиотек Python для работы с изображениями, такие как numpy, scipy, TensorFlow, Keras и т. д., считают себя научными инструментами для серьёзных людей, работающих с общими массивами данных. Они не заботятся о проблемах потребительского уровня, таких как автоматический поворот изображений, хотя это требуется практически для всех фотографий в мире, снятых с помощью современных камер.

Это означает, что при обработке изображения практически любой питоновской библиотекой вы получаете исходные данные изображения без поворота. И угадайте, что происходит, когда вы пытаетесь загрузить в модель обнаружения лиц или объектов фотографию на боку или вверх ногами? Детектор не срабатывает, потому что вы дали ему плохие данные.

Вы можете подумать, что проблемы возникают только в программах новичков и студентов, но это не так! Даже демо-версия флагманского Vision API от Google не обрабатывает правильно ориентацию EXIF:


Демонстрация Google Vision API не умеет поворачивать портретно-ориентированное изображение, снятое со стандартного мобильного телефона

И хотя Google Vision распознаёт каких-то животных на боку, но помечает их общей меткой «животное», потому что модели машинного зрения гораздо сложнее распознать гуся на боку, чем вертикального гуся. Вот результат, если правильно повернуть изображение перед подачей в модель:

При корректной ориентации Google обнаруживает птиц с более конкретной меткой «гусь» и более высоким показателем уверенности. Гораздо лучше!

Это суперочевидная проблема, когда вы явно видите, что изображение на боку, как в этой демонстрации. Но именно здесь все становится коварным — обычно вы этого не видите! Все нормальные программы на вашем компьютере отобразят изображение в правильной ориентации, а не как оно на самом деле хранится на диске. Поэтому, когда вы пытаетесь просмотреть изображение, чтобы увидеть, почему ваша модель не работает, оно будет отображаться правильно, и вы не поймёте, почему же модель не работает!


Finder на Mac всегда отображает фотографии с корректным поворотом из EXIF. Там никак не увидеть, чтобы изображение на самом деле хранится на боку

Это неизбежно приводит к массе открытых тикетов на Github: люди жалуются, что проекты с открытым исходным кодом сломаны, а модели не очень точны. Но проблема гораздо проще — они просто подают на вход повёрнутые или перевёрнутые фотографии!


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

Вот код для загрузки любого изображения в массив numpy с правильной ориентацией:

import PIL.Image
import PIL.ImageOps
import numpy as np


def exif_transpose(img):
    if not img:
        return img

    exif_orientation_tag = 274

    # Check for EXIF data (only present on some files)
    if hasattr(img, "_getexif") and isinstance(img._getexif(), dict) and exif_orientation_tag in img._getexif():
        exif_data = img._getexif()
        orientation = exif_data[exif_orientation_tag]

        # Handle EXIF Orientation
        if orientation == 1:
            # Normal image - nothing to do!
            pass
        elif orientation == 2:
            # Mirrored left to right
            img = img.transpose(PIL.Image.FLIP_LEFT_RIGHT)
        elif orientation == 3:
            # Rotated 180 degrees
            img = img.rotate(180)
        elif orientation == 4:
            # Mirrored top to bottom
            img = img.rotate(180).transpose(PIL.Image.FLIP_LEFT_RIGHT)
        elif orientation == 5:
            # Mirrored along top-left diagonal
            img = img.rotate(-90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT)
        elif orientation == 6:
            # Rotated 90 degrees
            img = img.rotate(-90, expand=True)
        elif orientation == 7:
            # Mirrored along top-right diagonal
            img = img.rotate(90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT)
        elif orientation == 8:
            # Rotated 270 degrees
            img = img.rotate(90, expand=True)

    return img


def load_image_file(file, mode='RGB'):
    # Load the image with PIL
    img = PIL.Image.open(file)

    if hasattr(PIL.ImageOps, 'exif_transpose'):
        # Very recent versions of PIL can do exit transpose internally
        img = PIL.ImageOps.exif_transpose(img)
    else:
        # Otherwise, do the exif transpose ourselves
        img = exif_transpose(img)

    img = img.convert(mode)

    return np.array(img)

Отсюда вы можете передать массив данных изображения в любую стандартную библиотеку машинного зрения Python, которая ожидает массив на входе: например, Keras или TensorFlow.

Поскольку проблема повсеместная, я опубликовал эту функцию в качестве pip-библиотеки под названием image_to_numpy. Можете установить её следующим образом:

pip3 install image_to_numpy

Она работает с любой программой Python, исправляя загрузку изображения, например:
import matplotlib.pyplot as plt
import image_to_numpy
# Load your image file
img = image_to_numpy.load_image_file("my_file.jpg")
# Show it on the screen (or whatever you want to do)
plt.imshow(img)
plt.show()

См. файл readme для более подробной информации.

Наслаждайтесь!

Программа для поворота видео на 90, 180 и 270 градусов

Автор статьи: Алина Лихачёва 29 января 2019

Мы всё реже пользуемся видеокамерой, для того чтобы снять какое-то событие. Обычно под рукой оказывается смартфон или фотоаппарат. Но ролик, отснятый таким образом, зачастую отображается неправильно – видео получается перевернутым.

В этой статье расскажем об уникальном современном софте, который сделает любое изображение корректным. Это удобная программа для поворота видео «ВидеоМАСТЕР». Вы узнаете о том, как перевернуть любое видео на 90, 180 и 270 градусов, сможете улучшить качество изображения и даже оформить его зрелищными спецэффектами.

Шаг 1. Установка программы и добавление видео-файлов

Зайдите на сайт компании-производителя: https://video-converter.ru/ и скачайте программный дистрибутив. После загрузки архива установите софт на свой компьютер, используя «Мастер установки». Добавьте на монтажный стол необходимые файлы, которые можно выбрать с ПК или скачать из интернета.

Программа для поворота видео Видео доступно для предпросмотра на экране справа

Шаг 2. Поворот видео

В левом углу экрана находится панель инструментов. Выберите вкладку «Эффекты» и перед вами откроется встроенный редактор видеозаписей. Нажмите кнопку «Поворот видео». Вы можете задать сторону (вправо или влево) и угол поворота (от 90 до 270 градусов). Установив нужные настройки, нажмите «Применить».

Поворот видео Видео можно поворачивать прямо во время воспроизведения

Шаг 3. Улучшение качества видеоролика

Программа для поворота видео имеет множество функций. Улучшите качество изображения автоматически при помощи функции «Комплексное улучшение». Также можно установить необходимые параметры яркости, контраста, насыщенности и цветовой тон, вручную, передвигая маркер по шкале настройки.

Шаг 4. Оформление клипа спецэффектами

Украсьте видео зрелищными спецэффектами. Каталог программы насчитывает более 10 различных вариантов. Сделайте ролик ярким и сочным, используя эффект насыщенности, или, напротив, создайте кино в стиле «нуар» с эффектами затемнения и оттенками серого. Используйте спецэффекты как отдельно друг от друга, так и комплексно, подбирая наиболее удачные сочетания.

Спецэффекты для видео Эффект «Старое кино» накладывает на ролик оттенок сепии

Шаг 5. И еще несколько трюков

Функционал программы имеет различные возможности для редактирования и обработки клипа. Вы можете обрезать видео и разделить его на части, соединить несколько файлов (включая аудио) в один, кадрировать изображение, добавлять любой текст и графику. Единственное ограничение – ваша фантазия.

Кадрирование видео Помимо стандартных пропорций 4:3 и 16:9, вы также можете задать произвольные

Шаг 6. Экспорт готового видео

Программа для переворота видео предлагает несколько вариантов экспорта файла:

  • конвертация готового видео в различные расширения;
  • подготовка ролика для публикации в сети Интернет;
  • запись видео-файла на DVD-диск.

Данный софт позволит навсегда забыть о проблемах, связанных с неправильно отснятым видео. Теперь вам не придется думать, в каком положении держать телефон или фотоаппарат для грамотной съемки. Благодаря программе «ВидеоМАСТЕР», вы знаете, как повернуть видео на 90 градусов и более, умеете за считанные минуты улучшать качество ролика и украшать его различными надписями и спецэффектами.

Скачать сейчасВсего 56 mb

Универсальный видео конвертер

Всё ещё не знаете, какой программой перевернуть видео, а затем преобразовать его в MPEG, AVI или какой-нибудь другой формат? На помощь вновь придет «ВидеоМАСТЕР». Ведь это еще и компактный конвертер видео и аудио файлов, позволяющий с легкостью переводить их из одного формата в другой.

Поддерживаемые форматы видео В программе доступны практически все известные форматы

В базе программы хранится внушительный арсенал кодеков и контейнеров для конвертации, начиная от самых востребованных и заканчивая самыми редкими. К примеру, вам требуется сменить расширение скачанного аудио. В этом случае приложение позволит всего за один клик сделать из WAV MP3 и наоборот.

Для видеороликов выбор возможностей ещё больше. Их можно конвертировать не только в стандартные и нестандартные форматы типа AVI или SWF, но и адаптировать для любой модели смартфона/планшета/консоли/плеера. Также конвертер оснащен функцией мгновенной публикации ролика на YouTube, MySpace, Вконтакте или другом известном сайте. А если вам необходимо избавиться от видеоряда и оставить только звук – достаточно просто выбрать в списке интересующее аудиорасширение.

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

Автоматический поворот изображения на мониторе / ХабрИсторически сложилось так, что у меня нет монитора. Вместо него я использую телевизор. Тридцати двух дюймовый телевизор. И нет, я еще не окосоглазил. Вполне комфортно за ним работается, заменяет мне сразу 2 монитора. Но есть у него одна неприятная особенность. Когда я открываю свой любимый редактор, код представляет собой узкий столбец с левой стороны экрана. Почти две трети экрана остаются пустыми и ничем не задействованными.

Я долго с этим мирился, пока не вспомнил про вертикальные мониторы. А почему нет? Чем я хуже? Вот тогда я и решил немного переоборудовать свое рабочее место. Можно было бы сделать крепеж и навсегда перевести монитор в вертикальное положение, но меня это не устраивало по той причине, что на моем «мониторе» я часто смотрю фильмы. А вертикальные фильмы, слава богу, пока еще не снимают. В этот момент появилась идея приобрести поворотный кронштейн и повесить телевизор на стену, чтобы при необходимости его вертеть. Именно так я и поступил.


Так лучше, не правда ли?

Жить стало намного удобнее. Надо поработать? Встал со стула, повернул монитор, сел обратно, ввел в терминале команду
xrandr -o left и работай себе с комфортом. Хочешь посмотреть фильмец? Сделай тоже самое, только введи уже xrandr -o normal и расслабляйся.

Все это меня полностью устраивало, пока мне просто не надоело. Надоело вводить эти команды. Вставать и переворачивать эту махину, мне, правда, тоже надоело, но не моторчик же приделывать к ней, верно? А вот ввод команд я мог автоматизировать без особых затрат. Но как объяснить компьютеру, что монитор был перевернут? Можно было бы заморочиться как, например, вот этот парень, но это никому не нужные сложности. В качестве интрфейса взаимодействия я сразу решил использовать последовательный порт (если нет встроенного, можно прикупить адаптер usb-to-serial). Но как быть с датчиком? А тут дело обстоит еще проще. Я отыскал никому не нужный тюбик от губной помады, вытащил металлический шарик из подшипника и соорудил это:

Тюбик, с одной стороны которого размещены 2 контакта, подключенные к пинам TxD и RxD последовательного порта.

Внутри тюбика катается металический шарик. Если он скатывается к контактам, то замыкает их, тем самым соединяя пины передачи и приема последовательного порта. Тюбик вешается позади «монитора» под углом в 45 градусов таким образом, что при горизонтальном положении шарик находится в бесконтактном конце тюбика, а при переводе монитора в вертикальный режим, шарик скатывается и замыкает собой контакты.

Осталось написать программную часть. Принцип работы очень прост: в серийный порт пишется слово и сразу же читается. Если программа хоть что-нибудь прочитала, то контакты замкнуты, а значит монитор находится в вертикальном положении. В результате чего выполняется команда xrandr -o left. При повороте обратно в горизонтальное положение происходит аналогичное действие, но с командой xrandr -o normal.

Первый раз я написал скрипт на моем любимом питоне. Это был двухпоточный монстр, который жрал, если верить top, 120% CPU. Почему так происходило, для меня до сих пор остается загадкой. В конце концов я решил переписать программу на С, что помогло не загружать так сильно процессор.

Вот, в принципе, и все. Осталось лишь добавить программу в автозагрузку.

Решил поделиться этим небольшим лайфхаком с хабросообществом. Вдруг кому пригодится.

Код можно найти на гитхабе.

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

UPD:
А вот как это выглядит в жизни (прошу прощения за качество):

Как повернуть видео | Программа для поворота видео

Как повернуть видео на 90 градусов или на любой другой угол

Никому не нравится смотреть «повернутое набок» видео. Однако то, что камеру во время съемки держали неправильно, часто обнаруживается уже постфактум. Что делать в таком случае? Не стоит спешить удалять полученное видео, ведь все можно легко исправить, если у вас под рукой есть нужная программа.

Movavi Video Editor – это не просто программа для поворота видео, это полнофункциональный видеоредактор, при помощи которого можно сделать свой фильм. Благодаря интуитивно понятному интерфейсу на русском языке разобраться в программе не составит труда даже для новичка.

Чтобы узнать, как развернуть видео, скачайте программу и следуйте инструкции ниже.

Скачать бесплатно Скачать бесплатно
  1. Установите Видеоредактор Movavi

    Скачайте и запустите установочный файл программы Movavi Video Editor. Процесс установки займет всего пару минут.

  2. Добавьте видео в программу

    Откройте программу и выберите Создать проект в расширенном режиме. Затем нажмите кнопку Добавить файлы, выберите нужный видеоклип и нажмите кнопку Открыть. Видео будет автоматически добавлено на Шкалу времени, расположенную в нижней части окна программы.

  3. Вырежьте фрагмент видео, который хотите повернуть (по желанию)

    Если вам необходимо повернуть только фрагмент ролика, вам нужно предварительно вырезать его. Установите маркер в начало фрагмента, с которым вы хотите работать, кликните правой кнопкой мыши по видео на Шкале времени и щелкните по кнопке Разрезать. Теперь установите маркер в конец фрагмента и повторите ваши действия. Ваш фрагмент отделен с обеих сторон, и вы можете повернуть его необходимым образом.

  4. Поверните видео

    Есть два способа повернуть ваше видео. Чтобы повернуть клип на 90, 180 или 360 градусов по часовой стрелке, выберите его на Шкале времени и нажмите кнопку Поворот столько раз, сколько потребуется.

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

  5. Сохраните готовое видео

    Нажмите кнопку Сохранить и выберите одну из доступных опций экспорта. Movavi Video Editor поддерживает все популярные видеоформаты, так что вы можете сохранить готовое видео в AVI, MP4, 3GP, MOV или в любом другом формате. Вы также можете сохранить видео для просмотра на персональном компьютере, ноутбуке или мобильном устройстве. Чтобы начать экспорт видео, нажмите Старт. Вот и все! Теперь вы знаете, какой программой проще и эффективнее всего повернуть видео.

Видеоредактор Movavi

Создавать видео – проще простого!

  • Редактируйте видео, фото и аудио на монтажном столе

  • Добавляйте переходы, фильтры и титры

  • Применяйте спецэффекты – например, Хромакей и Замедленное движение

  • Сохраняйте видео в любом популярном формате

Другие полезные инструкции

Остались вопросы?

Мы также рекомендуем

90000 Rotate images (correctly) with OpenCV and Python 90001 90002 90003 90004 90002 Let me tell you an embarrassing story of 90006 how I 90007 wasted 90008 three weeks of research time 90009 during graduate school six years ago. 90004 90002 It was the end of my second semester of coursework. 90004 90002 I had taken all of my exams early and all my projects for the semester had been submitted. 90004 90002 Since my school obligations were essentially nil, I started experimenting with (automatically) identifying prescription pills in images, something I know a thing or two about (but back then I was just getting started with my research).90004 90002 At the time, my research goal was to find and identify methods to reliably quantify pills in a 90007 rotation invariant 90008 manner. Regardless of how the pill was rotated, I wanted the output feature vector to be (approximately) the same (the feature vectors will never be to 90007 completely identical 90008 in a real-world application due to lighting conditions, camera sensors, floating point errors , etc.). 90004 90002 After the first week I was making fantastic progress. 90004 90002 I was able to extract features from my dataset of pills, index them, and then 90007 identify 90008 my test set of pills regardless of how they were oriented … 90004 90002 … however, there was a problem: 90004 90002 90006 My method was only working with 90007 round, circular pills 90008 — I was getting completely nonsensical results for 90007 oblong pills.90008 90009 90004 90002 How could that be? 90004 90002 I racked my brain for the explanation. 90004 90002 Was there a flaw in the logic of my feature extraction algorithm? 90004 90002 Was I not matching the features correctly? 90004 90002 Or was it something else entirely … 90006 90007 like a problem with my image preprocessing. 90008 90009 90004 90002 While I might have been ashamed to admit this as a graduate student, the problem was the latter: 90004 90002 90006 I goofed up.90009 90004 90002 It turns out that during the image preprocessing phase, I was rotating my images incorrectly. 90004 90002 Since round pills have are approximately square in their aspect ratio, the rotation bug was not a problem for them. Here you can see a round pill being rotated a full 360 degrees without an issue: 90004 90063 90006 Figure 1: 90009 Rotating a circular pill does not reveal any obvious problems. 90002 But for oblong pills, they would be «cut off» in the rotation process, like this: 90004 90068 90006 Figure 2: 90009 However, rotating oblong pills using the OpenCV’s standard 90007 cv2.getRotationMatrix2D 90008 and 90007 cv2.warpAffine 90008 functions caused me some problems that were not immediately obvious. 90002 In essence, I was only quantifying 90007 part 90008 of the rotated, oblong pills; hence my strange results. 90004 90002 I spent 90007 three weeks 90008 and 90007 part of my Christmas vacation 90008 banging my head against the wall trying to diagnose the bug — only to feel quite embarrassed when I realized it was due to me being negligent with the 90084 cv2.rotate 90085 function. 90004 90002 You see, the size of the output image needs to be 90007 adjusted 90008, otherwise, the corners of my image would be cut off. 90004 90002 How did I accomplish this and squash the bug for good? 90004 90002 90006 To learn how to rotate images with OpenCV such that the 90007 entire 90008 image is included and 90007 none 90008 of the image is cut off, 90007 just keep reading. 90008 90009 90004 90103 Rotate images (correctly) with OpenCV and Python 90104 90002 In the remainder of this blog post I’ll discuss common issues that you may run into when rotating images with OpenCV and Python.90004 90002 Specifically, we’ll be examining the problem of what happens when the corners of an image are «cut off» during the rotation process. 90004 90002 To make sure we all understand this rotation issue with OpenCV and Python I will: 90004 90111 90112 Start with a simple example demonstrating the rotation problem. 90113 90112 Provide a rotation function that ensures images are not cut off in the rotation process. 90113 90112 Discuss how I resolved my pill identification issue using this method.90113 90118 90119 A simple rotation problem with OpenCV 90120 90002 Let’s get this blog post started with an example script. 90004 90002 Open up a new file, name it 90084 rotate_simple.py 90085, and insert the following code: 90004 90127 # import the necessary packages import numpy as np import argparse import imutils import cv2 # Construct the argument parse and parse the arguments ap = argparse.ArgumentParser () ap.add_argument ( «- i», «—image», required = True, help = «path to the image file») args = vars (ap.parse_args ()) 90128 90002 90006 Lines 2-5 90009 start by importing our required Python packages. 90004 90002 If you do not already have imutils, my series of OpenCV convenience functions installed, you’ll want to do that now: 90004 90135 $ pip install imutils 90128 90002 If you 90007 already 90008 have 90084 imutils 90085 installed, make sure you have upgraded to the latest version: 90004 90143 $ pip install —upgrade imutils 90128 90002 From there, 90006 Lines 8-10 90009 parse our command line arguments.We only need a single switch here, 90084 —image 90085, which is the path to where our image resides on disk. 90004 90002 Let’s move on to actually rotating our image: 90004 90153 # load the image from disk image = cv2.imread (args [ «image»]) # Loop over the rotation angles for angle in np.arange (0, 360, 15): rotated = imutils.rotate (image, angle) cv2.imshow ( «Rotated (Problematic)», rotated) cv2.waitKey (0) # Loop over the rotation angles again, this time ensuring # No part of the image is cut off for angle in np.arange (0, 360, 15): rotated = imutils.rotate_bound (image, angle) cv2.imshow ( «Rotated (Correct)», rotated) cv2.waitKey (0) 90128 90002 90006 Line 14 90009 loads the image we want to rotate from disk. 90004 90002 We then loop over various angles in the range 90007 [0, 360] 90008 in 15 degree increments (90006 Line 17 90009). 90004 90002 For each of these angles we call 90084 imutils.rotate 90085, which rotates our 90084 image 90085 the specified number of 90084 angle 90085 degrees about the center of the image.We then display the rotated image to our screen. 90004 90002 90006 Lines 24-27 90009 perform an identical process, but this time we call 90084 imutils.rotate_bound 90085 (I’ll provide the implementation of this function in the next section). 90004 90002 As the name of this method suggests, we are going to ensure the 90007 entire image 90008 is bound inside the window and none is cut off. 90004 90002 To see this script in action, be sure to download the source code using the 90006 90007 «Downloads» 90008 90009 section of this blog post, followed by executing the command below: 90004 90189 $ python rotate_simple.py —image images / saratoga.jpg 90128 90002 The output of using the 90084 imutils.rotate 90085 function on a non-square image can be seen below: 90004 90195 90006 Figure 3: 90009 An example of corners being cut off when rotating an image using OpenCV and Python. 90002 As you can see, the image is «cut off» when it’s rotated — the entire image is not kept in the field of view. 90004 90002 But if we use 90084 imutils.rotate_bound 90085 we can resolve this issue: 90004 90204 90006 Figure 4: 90009 We can ensure the entire image is kept in the field of view by modifying the matrix returned by 90007 cv2.getRotationMatrix2D 90008. 90002 Awesome, we fixed the problem! 90004 90002 So does this mean that we should 90007 always 90008 use 90084 .rotate_bound 90085 over the 90084 .rotate 90085 method? 90004 90002 What makes it so special? 90004 90002 And what’s going on under the hood? 90004 90002 I’ll answer these questions in the next section. 90004 90119 Implementing a rotation function that 90007 does not 90008 cut off your images 90120 90002 Let me start off by saying there is 90007 nothing 90008 wrong with the 90084 cv2.getRotationMatrix2D 90085 and 90084 cv2.warpAffine 90085 functions that are used to rotate images inside OpenCV. 90004 90002 In reality, these functions give us more freedom than perhaps we are comfortable with (sort of like comparing manual memory management with C versus automatic garbage collection with Java). 90004 90002 The 90084 cv2.getRotationMatrix2D 90085 function 90006 90007 does not care 90008 90009 if we would like the entire rotated image to kept. 90004 90002 It 90006 90007 does not care 90008 90009 if the image is cut off.90004 90002 And it 90006 90007 will not help you 90008 90009 if you shoot yourself in the foot when using this function (I found this out the hard way and it took 3 weeks to stop the bleeding). 90004 90002 Instead, what you need to do is understand 90007 what 90008 the rotation matrix is ​​and 90007 how 90008 it’s constructed. 90004 90002 You see, when you rotate an image with OpenCV you call 90084 cv2.getRotationMatrix2D 90085 which returns a matrix 90007 M 90008 that looks something like this: 90004 90271 90006 Figure 5: 90009 The structure of the matrix 90007 M 90008 returned by 90007 cv2.getRotationMatrix2D 90008. 90002 This matrix looks scary, but I promise you: it’s not. 90004 90002 To understand it, let’s assume we want to rotate our image 90281 degrees about some center 90282 coordinates at some 90007 scale 90008 (i.e., smaller or larger). 90004 90002 We can then plug in values ​​for 90287 and 90288: 90004 90002 90291 and 90292 90004 90002 That’s all fine and good for simple rotation — but it does not take into account what happens if an image is cut off along the borders.How do we remedy this? 90004 90002 The answer is inside the 90084 rotate_bound 90085 function in convenience.py of imutils: 90004 90300 def rotate_bound (image, angle): # Grab the dimensions of the image and then determine the # center (H, w) = image.shape [: 2] (CX, cY) = (w // 2, h // 2) # Grab the rotation matrix (applying the negative of the # Angle to rotate clockwise), then grab the sine and cosine # (I.e., the rotation components of the matrix) M = cv2.getRotationMatrix2D ((cX, cY), -angle, 1.0) cos = np.abs (M [0, 0]) sin = np.abs (M [0, 1]) # Compute the new bounding dimensions of the image nW = int ((h * sin) + (w * cos)) nH = int ((h * cos) + (w * sin)) # Adjust the rotation matrix to take into account translation M [0, 2] + = (nW / 2) — cX M [1, 2] + = (nH / 2) — cY # Perform the actual rotation and return the image return cv2.warpAffine (image, M, (nW, nH)) 90128 90002 On 90006 Line 41 90009 we define our 90084 rotate_bound 90085 function.90004 90002 This method accepts an input 90084 image 90085 and an 90084 angle 90085 to rotate it by. 90004 90002 We assume we’ll be rotating our image about its center 90007 (x, y) 90008 -coordinates, so we determine these values ​​on 90006 lines 44 and 45 90009. 90004 90002 Given these coordinates, we can call 90084 cv2.getRotationMatrix2D 90085 to obtain our rotation matrix 90007 M 90008 (90006 Line 50 90009). 90004 90002 However, to adjust for any image border cut off issues, we need to apply some manual calculations of our own.90004 90002 We start by grabbing the cosine and sine values ​​from our rotation matrix 90007 M 90008 (90006 Lines 51 and 52 90009). 90004 90002 This enables us to compute the new width and height of the rotated image, ensuring no part of the image is cut off. 90004 90002 Once we know the new width and height, we can adjust for translation on 90006 Lines 59 and 60 90009 by modifying our rotation matrix once again. 90004 90002 Finally, 90084 cv2.warpAffine 90085 is called on 90006 Line 63 90009 to rotate the actual image using OpenCV while ensuring none of the image is cut off.90004 90002 For some other interesting solutions (some better than others) to the rotation cut off problem when using OpenCV, be sure to refer to this StackOverflow thread and this one too. 90004 90119 Fixing the rotated image «cut off» problem with OpenCV and Python 90120 90002 Let’s get back to my original problem of rotating oblong pills and how I used 90084 .rotate_bound 90085 to solve the issue (although back then I had not created the 90084 imutils 90085 Python package — it was simply a utility function in a helper file) .90004 90002 We’ll be using the following pill as our example image: 90004 90360 90006 Figure 6: 90009 The example oblong pill we will be rotating with OpenCV. 90002 To start, open up a new file and name it 90084 rotate_pills.py 90085. Then, insert the following code: 90004 90367 # import the necessary packages import numpy as np import argparse import imutils import cv2 # Construct the argument parse and parse the arguments ap = argparse.ArgumentParser () ap.add_argument ( «- i», «—image», required = True, help = «path to the image file») args = vars (ap.parse_args ()) 90128 90002 90006 Lines 2-5 90009 import our required Python packages. Again, make sure you have installed and / or upgraded the imutils Python package before continuing. 90004 90002 We then parse our command line arguments on 90006 Lines 8-11 90009. Just like in the example at the beginning of the blog post, we only need one switch: 90084 —image 90085, the path to our input image. 90004 90002 Next, we load our pill image from disk and preprocess it by converting it to grayscale, blurring it, and detecting edges: 90004 90381 # load the image from disk, convert it to grayscale, blur it, # And apply edge detection to reveal the outline of the pill image = cv2.imread (args [ «image»]) gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur (gray, (3, 3), 0) edged = cv2.Canny (gray, 20, 100) 90128 90002 After executing these preprocessing functions our pill image now looks like this: 90004 90385 90006 Figure 7: 90009 Detecting edges in the pill. 90002 The outline of the pill is clearly visible, so let’s apply contour detection to find the outline of the pill: 90004 90390 # find contours in the edge map cnts = cv2.findContours (edged.copy (), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) 90128 90002 We are now ready to extract the pill ROI from the image: 90004 90394 # ensure at least one contour was found if len (cnts)> 0: # Grab the largest contour, then draw a mask for the pill c = max (cnts, key = cv2.contourArea) mask = np.zeros (gray.shape, dtype = «uint8») cv2.drawContours (mask, [c], -1, 255, -1) # Compute its bounding box of pill, then extract the ROI, # And apply the mask (X, y, w, h) = cv2.boundingRect (c) imageROI = image [y: y + h, x: x + w] maskROI = mask [y: y + h, x: x + w] imageROI = cv2.bitwise_and (imageROI, imageROI, mask = maskROI) 90128 90002 First, we ensure that at least 90007 one 90008 contour was found in the edge map (90006 Line 26 90009). 90004 90002 Provided we have at least one contour, we construct a 90084 mask 90085 for the largest contour region on 90006 Lines 29 and 30 90009. 90004 90002 Our 90084 mask 90085 looks like this: 90004 90412 90006 Figure 8: 90009 The mask representing the entire pill region in the image.90002 Given the contour region, we can compute the 90007 (x, y) 90008 -coordinates of the bounding box of the region (90006 Line 34 90009). 90004 90002 Using both the bounding box and 90084 mask 90085, we can extract the actual pill region ROI (90006 Lines 35-38 90009). 90004 90002 Now, let’s go ahead and apply both the 90084 imutils.rotate 90085 and 90084 imutils.rotate_bound 90085 functions to the 90084 imageROI 90085, just like we did in the simple examples above: 90004 90435 # loop over the rotation angles for angle in np.arange (0, 360, 15): rotated = imutils.rotate (imageROI, angle) cv2.imshow ( «Rotated (Problematic)», rotated) cv2.waitKey (0) # Loop over the rotation angles again, this time ensure the # Entire pill is still within the ROI after rotation for angle in np.arange (0, 360, 15): rotated = imutils.rotate_bound (imageROI, angle) cv2.imshow ( «Rotated (Correct)», rotated) cv2.waitKey (0) 90128 90002 After downloading the source code to this tutorial using the 90006 90007 «Downloads» 90008 90009 section below, you can execute the following command to see the output: 90004 90443 $ python rotate_pills.py —image images / pill_01.png 90128 90002 The output of 90084 imutils.rotate 90085 will look like: 90004 90449 90006 Figure 9: 90009 Incorrectly rotating an image with OpenCV causes parts of the image to be cut off. 90002 Notice how the pill is cut off during the rotation process — we need to 90453 explicitly 90454 compute the new dimensions of the rotated image to ensure the borders are not cut off. 90004 90002 By using 90084 imutils.rotate_bound 90085, we can ensure that no part of the image is cut off when using OpenCV: 90004 90460 90006 Figure 10: 90009 By modifying OpenCV’s rotation matrix we can resolve the issue and ensure the entire image is visible.90002 Using this function I was 90007 finally 90008 able to finish my research for the winter break — but not before I felt quite embarrassed about my rookie mistake. 90004 90103 Summary 90104 90002 In today’s blog post I discussed how image borders can be cut off when rotating images with OpenCV and 90084 cv2.warpAffine 90085. 90004 90002 The fact that image borders can be cut off is 90007 not 90008 a bug in OpenCV — in fact, it’s how 90084 cv2.getRotationMatrix2D 90085 and 90084 cv2.warpAffine 90085 are designed. 90004 90002 While it may seem frustrating and cumbersome to compute new image dimensions to ensure you do not lose your borders, it’s actually a blessing in disguise. 90004 90002 OpenCV gives us 90007 so much control 90008 that we can modify our rotation matrix to make it do 90007 exactly 90008 what we want. 90004 90002 Of course, this requires us to know how our rotation matrix 90007 M 90008 is formed and what each of its components represents (discussed earlier in this tutorial).Provided we understand this, the math falls out naturally. 90004 90002 To learn more about image processing and computer vision, be sure to take a look at the PyImageSearch Gurus course where I discuss these topics in more detail. 90004 90002 90007 90006 Otherwise, I encourage you to enter your email address in the form below to be notified when future blog posts are published. 90009 90008 90004 90501 90002 90503 Download the Source Code and FREE 17-page Resource Guide 90504 90004 90002 Enter your email address below to get a.zip of the code and a 90006 FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. 90009 Inside you’ll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL! 90004 .90000 python — Is there a way i can detect the image orientation and rotate the image to the right angle? 90001 Stack Overflow 90002 90003 Products 90004 90003 Customers 90004 90003 Use cases 90004 90009 90010 90003 Stack Overflow Public questions and answers 90004 90003 Teams Private questions and answers for your team 90004 90003 Enterprise Private self-hosted questions and answers for your enterprise 90004 90003 Jobs Programming and related technical career opportunities 90004 90003 Talent Hire technical talent 90004 90003 Advertising Reach developers worldwide 90004 90009.90000 c # — How to rotate a BitmapSource by any angle? 90001 Stack Overflow 90002 90003 Products 90004 90003 Customers 90004 90003 Use cases 90004 90009 90010 90003 Stack Overflow Public questions and answers 90004 90003 Teams Private questions and answers for your team 90004 90003 Enterprise Private self-hosted questions and answers for your enterprise 90004 90003 Jobs Programming and related technical career opportunities 90004 90003 Talent Hire technical talent 90004 90003 Advertising Reach developers worldwide 90004 90009 .90000 How to rotate a 3D image by a random angle in python 90001 Stack Overflow 90002 90003 Products 90004 90003 Customers 90004 90003 Use cases 90004 90009 90010 90003 Stack Overflow Public questions and answers 90004 90003 Teams Private questions and answers for your team 90004 90003 Enterprise Private self-hosted questions and answers for your enterprise 90004 90003 Jobs Programming and related technical career opportunities 90004 90003 Talent Hire technical talent 90004 90003 Advertising Reach developers worldwide 90004 90009 .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *