Лабы 2022-2023 / 1 сем / Baraeva_Elizaveta_lb2
.docМИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В. И. Ульянова (Ленина)
Кафедра МО ЭВМ
отчет
по лабораторной работе №2
по дисциплине «Информатика»
Тема: Введение в архитектуру компьютера
Студентка гр. 2383 |
|
Бараева Е. Н. |
Преподаватель |
|
Шевская Н. В. |
Санкт-Петербург
2022
Цель работы.
Научиться пользоваться библиотекой numpy и Pillow для редактирования изображений и создания новых.
Задание.
Вариант 4
Решить 3 подзадачи, используя библиотеки Pillow и numpy.
Задача 1: Рисование отрезка.
Необходимо реализовать функцию user_func(), рисующую на картинке отрезок. Она принимает на вход: изображение, координаты, начала (x0, y0), координаты конца (x1, y1), цвет, толщину.
Функция должна вернуть обработанное изображение.
Задача 2: Преобразовать в Ч/Б изображение (любым простым способом).
Нужно реализовать 2 функции:
check_coords(image, x0, y0, x1, y1) – проверяет координаты области (x0, y0, x1, y1) на корректность (они должны быть неотрицательными, не превышать размеров изображения, поскольку x0, y0 – координаты левого верхнего угла, x1, y1 - координаты правого нижнего угла, то x1 должен быть больше x0, а y1 должен быть больше y0);
set_black_white(image, x0, y0, x1, y1) – преобразовывает заданную область изображения в черно-белый. В этой функции должна вызываться функция проверки, и, если область некорректна, то должно быть возвращено исходное изображение без изменений. Примечание: поскольку черно-белый формат изображения (greyscale) является самостоятельным форматом, а не вариацией RGB-формата, для его получения необходимо использовать метод Image.convert.
Задача 3: Найти самый большой прямоугольник заданного цвета и перекрасить его в другой цвет.
Написать функцию find_rect_and_recolor(image, old_color, new_color), принимающую на вход изображение и кортежи RGB-компонент старого и нового цветов. Она выполняет задачу и возвращает изображение. При необходимости можно писать дополнительные функции.
Выполнение работы.
Задача 1:
На вход функции user_func() подается изображение image, координаты левого верхнего угла x0, y0 и правого нижнего угла x1, y1, цвет заливки отрезка fill и его ширина width. Затем с помощью класса ImageDraw и метода Draw создается изображение drawing, на котором уже можно будет рисовать отрезок. Метод line, которому передается два кортежа с координатами, цвет заливки и ширина, рисует отрезок. После этого функция возвращает изображение.
Задача 2:
На вход функции set_black_white() подается изображение image, координаты левого верхнего угла x0, y0 и правого нижнего угла x1, y1. Затем проверяются координаты на верность. Вызывается функция check_coords(), которой передаются те же данные. Методом size записываются, в переменные width и height, размеры изображения. Оператором if проверяются координаты и возвращается соответствующее True или False. Если функцией было возвращено False, то set_black_white() возвращает исходное изображение, если True, то методом crop вырезается нужная область изображение, методом convert эта область становится черно-белой, методом paste измененная область возвращается на то же место и возвращается измененное изображение.
Задача 3:
На вход функции set_black_white() подается изображение image, старый цвет old_color, новый цвет new_color. Объявляются переменные xy0, xy1, в которые запишутся координаты углов прямоугольника, width, height, в которые методом size записываются размеры изображения. С помощью np.array() создается матрица с цветами пикселей и записывается в pixels. Создается переменная max_area, которая будет нужна для записи площади наибольшего прямоугольника. Затем с помощью двух циклов for проходится по каждому пикселю. Оператор if сравнивает цвет текущего пикселя с нужным цветом. Если пиксель с нужным цветом и до него не было пикселя с нужным цветом, то в переменные x, y записываются его координаты, а в переменные h и l, обозначающие высоту и длину прямоугольника, записываются нули. Циклом while вычисляется длина прямоугольника, с помощью прибавления 1 к x. Т. к. прямоугольник может находиться у края изображение, то x проверяется на не превышение размера изображения. Затем из x вычитается 1, для того чтобы вернуться к пикселю с нужным цветом. Вторым циклом while вычисляется высота прямоугольника таким же способом. После этого из y вычитается 1 по таким же причинам, как и у x. В конце проверяется превысила ли площадь данного прямоугольника предыдущую площадь. Если превысила, то площадь перезаписывается и в xy0, xy1 записываются координаты углов прямоугольника. После выхода из циклов меняется цвет наибольшего прямоугольника с помощью метода rectangle и возвращается измененное изображение.
Разработанный программный код см. в приложении А.
Тестирование.
Результаты тестирования представлены в табл. 1.
Таблица 1 – Результаты тестирования
№ п/п |
Входные данные |
Выходные данные |
Комментарии |
1. |
image = Image.new("RGB", (300, 300), 'green') user_func(image, 20, 50, 100, 250, 'yellow', 5).show() |
|
Проверка функции user_func. Верно. |
2. |
image = Image.new("RGB", (300, 300), 'black') user_func(image, 62, 55, 246, 145, 'blue', 5).show() |
|
Проверка функции user_func. Верно. |
3. |
image = Image.new("RGB", (300, 300), 'blue') set_black_white(image, 87, 48, 274, 187).show() |
|
Проверка функции set_black_white. Верно. |
4. |
image = Image.new("RGB", (300, 300), 'pink') set_black_white(image, 0, 134, 268, 100).show |
|
Проверка функции set_black_white. Верно. |
5. |
image = Image.new("RGB", (300, 300), 'red') drawing = ImageDraw.Draw(image) drawing.rectangle((250, 250, 300, 300), 'black') drawing.rectangle((100, 100, 150, 200), 'black') drawing.rectangle((0, 0, 60, 60), 'black') find_rect_and_recolor(image, (0, 0, 0), (0, 200, 0)).show() |
|
Проверка функции find_rect_and_recolor. Верно. |
6. |
image = Image.new("RGB", (300, 300), 'red') drawing = ImageDraw.Draw(image) drawing.rectangle((250, 250, 300, 300), 'black') drawing.rectangle((40, 60, 100, 90), 'black') find_rect_and_recolor(image, (0, 0, 0), (0, 200, 0)).show() |
|
Проверка функции find_rect_and_recolor. Верно. |
Вывод.
Были изучены основы библиотек Pillow и numpy. Разработаны 4 функции, которые изменяли изображения в соответствии с заданиями.
ПРИЛОЖЕНИЕ А ИСХОДНЫЙ КОД ПРОГРАММЫ
Название файла: main_lb2.py
def user_func(image, x0, y0, x1, y1, fill, width):
drawing = ImageDraw.Draw(image)
drawing.line(((x0, y0), (x1, y1)), fill, width)
return image
def check_coords(image, x0, y0, x1, y1):
width, height = image.size
if 0 <= x0 < x1 <= width and 0 <= y0 < y1 <= height:
return True
else:
return False
def set_black_white(image, x0, y0, x1, y1):
if check_coords(image, x0, y0, x1, y1):
img = image.crop((x0, y0, x1, y1))
img = img.convert('1')
image.paste(img, (x0, y0))
return image
else:
return image
def find_rect_and_recolor(image, old_color, new_color):
global xy0, xy1
width, height = image.size
pixels = np.array(image)
max_area = 0
for j in range(height):
for i in range(width):
if tuple(pixels[j][i]) == old_color:
if i == 0 or i != 0 and tuple(pixels[j][i-1]) != old_color:
h, l = 0, 0
y, x = j, i
while tuple(pixels[y][x]) == old_color:
l += 1
x += 1
if x == width:
break
x -= 1
while tuple(pixels[y][x]) == old_color and tuple(pixels[y][i]) == old_color:
h += 1
y += 1
if y == height:
break
y -= 1
if max_area < (h - 1) * (l - 1):
max_area = (h - 1) * (l - 1)
xy0 = (i, j)
xy1 = (x, y)
drawing = ImageDraw.Draw(image)
drawing.rectangle((xy0, xy1), new_color)
return image
