- •Об авторе
- •О научных редакторах
- •Благодарности
- •От издательства
- •Введение
- •Для кого эта книга?
- •Почему Python?
- •План книги
- •Версия Python, платформа и IDE
- •Установка Python
- •Запуск Python
- •Использование виртуальной среды
- •Вперед!
- •Глава 1. Спасение моряков с помощью теоремы Байеса
- •Теорема Байеса
- •Проект #1. Поиск и спасение
- •Стратегия
- •Установка библиотек Python
- •Код для теоремы Байеса
- •Время сыграть
- •Итоги
- •Дополнительная литература
- •Усложняем проект. Более грамотный поиск
- •Усложняем проект. Поиск лучшей стратегии с помощью MCS
- •Усложняем проект. Вычисление вероятности обнаружения
- •Глава 2. Установление авторства с помощью стилометрии
- •Проект #2: «Собака Баскервилей», «Война миров» и «Затерянный мир»
- •Стратегия
- •Установка NLTK
- •Корпусы текстов
- •Код стилометрии
- •Итоги
- •Дополнительная литература
- •Практический проект: охота на собаку Баскервилей с помощью распределения
- •Практический проект: тепловая карта пунктуации
- •Усложняем проект: фиксирование частотности
- •Глава 3. Суммаризация текста с помощью обработки естественного языка
- •Стратегия
- •Веб-скрапинг
- •Код для «У меня есть мечта»
- •Установка gensim
- •Код для суммаризации речи «Заправляйте свою кровать»
- •Проект #5. Суммаризация речи с помощью облака слов
- •Модули Word Cloud и PIL
- •Код для создания облака слов
- •Итоги
- •Дополнительная литература
- •Усложняем проект: ночные игры
- •Усложняем проект: суммаризация суммаризаций
- •Глава 4. Отправка суперсекретных сообщений с помощью книжного шифра
- •Одноразовый блокнот
- •Шифр «Ребекка»
- •Проект #6. Цифровой ключ к «Ребекке»
- •Стратегия
- •Код для шифрования
- •Отправка сообщений
- •Итоги
- •Дополнительная литература
- •Глава 5. Поиск Плутона
- •Проект #7. Воссоздание блинк-компаратора
- •Стратегия
- •Данные
- •Код блинк-компаратора
- •Использование блинк-компаратора
- •Проект #8. Обнаружение астрономических транзиентов путем дифференцирования изображений
- •Стратегия
- •Код для детектора транзиентов
- •Использование детектора транзиентов
- •Итоги
- •Дополнительная литература
- •Практический проект: представление орбитальной траектории
- •Практический проект: найди отличия
- •Усложняем проект: сосчитаем звезды
- •Глава 6. Победа в лунной гонке с помощью «Аполлона-8»
- •Цель миссии «Аполлон-8»
- •Траектория свободного возврата
- •Задача трех тел
- •Проект #9. На Луну с «Аполлоном-8»!
- •Использование модуля turtle
- •Стратегия
- •Код программы для расчета свободного возврата «Аполлона-8»
- •Выполнение симуляции
- •Итоги
- •Дополнительная литература
- •Практический проект: симуляция шаблона поисков
- •Практический проект: запусти меня!
- •Практический проект: останови меня!
- •Усложняем проект: симуляция в истинном масштабе
- •Усложняем проект: реальный «Аполлон-8»
- •Глава 7. Выбор мест высадки на Марсе
- •Посадка на Марс
- •Карта MOLA
- •Проект #10. Выбор посадочных мест на Марсе
- •Стратегия
- •Код для выбора мест посадки
- •Результаты
- •Итоги
- •Дополнительная литература
- •Практический проект: убедимся, что рисунки становятся частью изображения
- •Практический проект: визуализация профиля высот
- •Практический проект: отображение в 3D
- •Практический проект: совмещение карт
- •Усложняем проект: три в одном
- •Усложняем проект: перенос прямоугольников
- •Глава 8. Обнаружение далеких экзопланет
- •Транзитная фотометрия
- •Проект #11. Симуляция транзита экзопланеты
- •Стратегия
- •Код для транзита
- •Эксперименты с транзитной фотометрией
- •Проект #12. Получение изображений экзопланет
- •Стратегия
- •Код для пикселизатора
- •Итоги
- •Дополнительная литература
- •Практический проект: обнаружение инопланетных мегаструктур
- •Практический проект: обнаружение транзита астероидов
- •Практический проект: добавление эффекта потемнения к краю
- •Практический проект: обнаружение пятен на звездах
- •Практический проект: обнаружение инопланетной армады
- •Практический проект: обнаружение планеты с луной
- •Практический проект: измерение продолжительности экзопланетного дня
- •Усложняем проект: генерация динамической кривой блеска
- •Глава 9. Как различить своих и чужих
- •Обнаружение лиц на фотографиях
- •Проект #13. Программирование робота-часового
- •Стратегия
- •Результаты
- •Обнаружение лиц в видеопотоке
- •Итоги
- •Дополнительная литература
- •Практический проект: размытие лиц
- •Усложняем проект: обнаружение кошачьих мордочек
- •Глава 10. Ограничение доступа по принципу распознавания лиц
- •Распознавание лиц с помощью LBPH
- •Схема распознавания лиц
- •Извлечение гистограмм локальных бинарных шаблонов
- •Проект #14. Ограничение доступа к инопланетному артефакту
- •Стратегия
- •Поддержка модулей и файлов
- •Код для захвата видео
- •Код для обучения алгоритма распознавания лиц
- •Код для прогнозирования лиц
- •Результаты
- •Итоги
- •Дополнительная литература
- •Усложняем проект: добавление пароля и видеозахвата
- •Усложняем проект: похожие лица и близнецы
- •Усложняем проект: машина времени
- •Глава 11. Создание интерактивной карты побега от зомби
- •Проект #15. Визуализация плотности населения с помощью хороплетной карты
- •Стратегия
- •Библиотека анализа данных
- •Библиотеки bokeh и holoviews
- •Установка pandas, bokeh и holoviews
- •Работа с данными по уровню безработицы и плотности населения в округах и штатах
- •Разбираем код holoviews
- •Код для отрисовки хороплетной карты
- •Планирование маршрута
- •Итоги
- •Дополнительная литература
- •Усложняем проект: отображение на карте изменения численности населения США
- •Глава 12. Находимся ли мы в компьютерной симуляции?
- •Проект #16. Жизнь, Вселенная и пруд черепахи Йертл
- •Код симуляции пруда
- •Следствия симуляции пруда
- •Измерение затрат на пересечение строк или столбцов сетки
- •Результаты
- •Стратегия
- •Итоги
- •Дополнительная литература
- •Дополнение
- •Усложняем проект: поиск безопасного места в космосе
- •Усложняем проект: а вот и Солнце
- •Усложняем проект: взгляд глазами собаки
- •Усложняем проект: кастомизированный поиск слов
- •Усложняем проект: что за сложную паутину мы плетем
- •Усложняем проект: идем вещать с горы
- •Решения для практических проектов
- •Глава 2. Определение авторства с помощью стилометрии
- •Охота на собаку Баскервилей с помощью распределения
- •Тепловая карта пунктуации
- •Глава 4. Отправка суперсекретных сообщений с помощью книжного шифра
- •Составление графика символов
- •Отправка секретов шифром времен Второй мировой войны
- •Глава 5. Поиск Плутона
- •Представление орбитальной траектории
- •Глава 6. Победа в лунной гонке с помощью «Аполлона-8»
- •Симуляция шаблона поисков
- •Заведи меня!
- •Останови меня!
- •Глава 7. Выбор мест высадки на Марсе
- •Убеждаемся, что рисунки становятся частью изображения
- •Визуализация профиля высоты
- •Отображение в 3D
- •Совмещение карт
- •Глава 8. Обнаружение далеких экзопланет
- •Обнаружение инопланетных мегаструктур
- •Обнаружение транзита астероидов
- •Добавление эффекта потемнения к краю
- •Обнаружение инопланетной армады
- •Обнаружение планеты с луной
- •Измерение продолжительности экзопланетного дня
- •Глава 9. Как различить своих и чужих
- •Размытие лиц
- •Глава 10. Ограничение доступа по принципу распознавания лиц
- •Усложняем проект: добавление пароля и видеозахвата
Глава 5. Поиск Плутона 359
indexes = [s.replace(',', '').replace('[', '').replace(']', '') for s in message.split()]
for count, i in enumerate(indexes): plaintextList.append(word_list[int(i) - shift])
return ' '.join(plaintextList)
def check_for_fail(ciphertext):
"""Возвращаем True, если криптограмма содержит повторы ключей.""" check = [k for k, v in Counter(ciphertext).items() if v > 1]
if len(check) > 0: print(check) return True
if __name__ == '__main__': main()
Глава 5. Поиск Плутона
Представление орбитальной траектории
practice_orbital_path.py
import os
from pathlib import Path import cv2 as cv
PAD = 5 # Игнорировать пиксели на таком расстоянии от края изображения.
def find_transient(image, diff_image, pad):
"""Получает изображение, изображение отличий и значение отступа
в пикселях, на что возвращает булево значение и расположение maxVal на изображении отличий, исключая отступ по краям.
Обводит на изображении кругом maxVal.""" transient = False
height, width = diff_image.shape
cv.rectangle(image, (PAD, PAD), (width - PAD, height - PAD), 255, 1) minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc(diff_image)
if pad < maxLoc[0] < width - pad and pad < maxLoc[1] < height - pad: cv.circle(image, maxLoc, 10, 255, 0)
transient = True return transient, maxLoc
def main():
night1_files = sorted(os.listdir('night_1_registered_transients')) night2_files = sorted(os.listdir('night_2'))
path1 = Path.cwd() / 'night_1_registered_transients' path2 = Path.cwd() / 'night_2'
path3 = Path.cwd() / 'night_1_2_transients'
#Все изображения должны быть сделаны с похожей экспозицией и иметь одинаковый размер.
for i, _ in enumerate(night1_files[:-1]): # Убрать негативное изображение img1 = cv.imread(str(path1 / night1_files[i]), cv.IMREAD_GRAYSCALE) img2 = cv.imread(str(path2 / night2_files[i]), cv.IMREAD_GRAYSCALE)
360 Решения для практических проектов
#Получаем абсолютную разницу между изображениями. diff_imgs1_2 = cv.absdiff(img1, img2) cv.imshow('Difference', diff_imgs1_2) cv.waitKey(2000)
#Копируем изображение отличий, после чего находим и обводим самый яркий пиксель.
temp = diff_imgs1_2.copy()
transient1, transient_loc1 = find_transient(img1, temp, PAD)
#Рисуем черный круг на временном изображении, чтобы скрыть самое яркое пятно.
cv.circle(temp, transient_loc1, 10, 0, -1)
#Получаем положение самого яркого пикселя и обводим его на входном изображении.
transient2, transient_loc2 = find_transient(img1, temp, PAD)
if transient1 or transient2:
print('\nTRANSIENT DETECTED between {} and {}\n'
.format(night1_files[i], night2_files[i])) font = cv.FONT_HERSHEY_COMPLEX_SMALL cv.putText(img1, night1_files[i], (10, 25),
font, 1, (255, 255, 255), 1, cv.LINE_AA) cv.putText(img1, night2_files[i], (10, 55),
font, 1, (255, 255, 255), 1, cv.LINE_AA) if transient1 and transient2:
cv.line(img1, transient_loc1, transient_loc2, (255, 255, 255), 1, lineType=cv.LINE_AA)
blended = cv.addWeighted(img1, 1, diff_imgs1_2, 1, 0) cv.imshow('Исследовано', blended)
cv.waitKey(2500) # Удерживает окно открытым в течение 2.5 секунды.
out_filename = '{}_DECTECTED.png'.format(night1_files[i][:-4]) cv.imwrite(str(path3 / out_filename), blended) # Будет
перезаписано!
else:
print('\nNo transient detected between {} and {}\n'
.format(night1_files[i], night2_files[i]))
if __name__ == '__main__': main()
Вчем разница?
Вэтом практическом проекте используются две программы, Practice_montage_
aligner.py и practice_montage_difference_finder.py. Выполнять их нужно в предложенном порядке.
Глава 5. Поиск Плутона 361
practice_montage_aligner.py
practice_montage_aligner.py
import numpy as np import cv2 as cv
MIN_NUM_KEYPOINT_MATCHES = 150
img1 = cv.imread('montage_left.JPG', cv.IMREAD_COLOR) # queryImage img2 = cv.imread('montage_right.JPG', cv.IMREAD_COLOR) # trainImage img1 = cv.cvtColor(img1, cv.COLOR_BGR2GRAY) # Преобразуем в полутона. img2 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
orb = cv.ORB_create(nfeatures=700)
#Находим ключевые точки и описания с помощью #ORB. kp1, desc1 = orb.detectAndCompute(img1, None)
kp2, desc2 = orb.detectAndCompute(img2, None)
#Находим совпадения ключевых точек с помощью Brute #Force Matcher. bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
matches = bf.match(desc1, desc2, None)
#Сортируем совпадения в порядке увеличения расстояния.
matches = sorted(matches, key=lambda x: x.distance)
# Отрисовываем лучшие совпадения.
img3 = cv.drawMatches(img1, kp1, img2, kp2, matches[:MIN_NUM_KEYPOINT_MATCHES], None)
cv.namedWindow('Matches', cv.WINDOW_NORMAL) img3_resize = cv.resize(img3, (699, 700)) cv.imshow('Matches', img3_resize) cv.waitKey(7000) # Keeps window open 7 seconds. cv.destroyWindow('Matches')
# Оставляем только лучшие совпадения. best_matches = matches[:MIN_NUM_KEYPOINT_MATCHES]
if len(best_matches) >= MIN_NUM_KEYPOINT_MATCHES:
src_pts = np.zeros((len(best_matches), 2), dtype=np.float32) dst_pts = np.zeros((len(best_matches), 2), dtype=np.float32)
for i, match in enumerate(best_matches): src_pts[i, :] = kp1[match.queryIdx].pt dst_pts[i, :] = kp2[match.trainIdx].pt
M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC)
# Получаем размеры изображения 2. height, width = img2.shape
img1_warped = cv.warpPerspective(img1, M, (width, height))
cv.imwrite('montage_left_registered.JPG', img1_warped) cv.imwrite('montage_right_gray.JPG', img2)
else:
print("\n{}\n".format('WARNING: Number of keypoint matches < 10!'))