Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Воган Ли - Python для хакеров (Библиотека программиста) - 2023.pdf
Скачиваний:
5
Добавлен:
07.04.2024
Размер:
14.76 Mб
Скачать

Глава 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!'))