Пролог
Всем привет! Как и обещал, начинаем разбирать часть машинного зрения в данном проекте. Для начала разберемся, что мы имеем и что хотим в итоге получить. Имеем мы цветное изображение человеческого лица. Пусть пока оно у нас просто будет, потому что получение изображение с камеры на Raspberry Pi - тема вполне известная ,отдельно на ней акцентировать внимание не буду.
![Предположим вот. Теперь вы можете меня найти и побить за кривой код) Предположим вот. Теперь вы можете меня найти и побить за кривой код)](https://habrastorage.org/getpro/habr/upload_files/ffa/160/82e/ffa16082e153d2ba634cf1272c62ba06.jpg)
Нам нужно:
Сделать так, чтобы лазер отличал одни пиксели от других
Почистить всё лишнее
Иными словами - переводим цвет в чб и векторизуем растр. Получить надо что-то похожее на карандашный рисунок.
Завязка
Для начала установим библиотеку openCV для python. Для этого открываем терминал и прописываем:
pip install opencv-python
Таким легким движением мы установили openCV для всех наших python-проектов. Меня такой расклад устраивает, но если что вы всегда можете отступить от гайда и рабоать с виртуальной машиной) Теперь открываем любимый редактор, в моём случае VS code, и создаем проект.
Развитие
Следующее, что мы сделаем - импортируем cv2 и откроем изображение.
import cv2 as cv
orig = cv.imread('me.jpg')
Вместо me,jpg пропишите название изображения, находящегося в папке проекта. По религиозным причинам патента на RGB-модель openCV для хранения и обработки использует BGR-модель. Давайте наше цветное изображение конвертируем в ЧБ-формат, как будто делали фото на фотоаппарат бабули. Делается это следующим образом:
gray = cv.cvtColor(orig, cv.COLOR_BGR2GRAY)
Разберём подробно cv.cvtColor(orig, cv.COLOR_BGR2GRAY).
Данная функция конвертирует изображение и возвращает результат. Первым аргументом является уже считанное изображение, а вторым - профиль конвертации. В cv2 их много, для всех нужд хватит, нам нужен один из самых простых.
Далее нам надо как-то почистить изображение от лишних пикселей, чтобы не было каши. Лучше всего с эти справится блюр короля математики (Гаусса), однако он размоет не пустоты (светлое), а наоборот, темное. То есть то, что нам необходимо выразить, поэтому предварительно мы инвертируем изображение, а после применения GaussianBlur вернём обратно.
inv_gray = 255 - gray
blur_img = cv.GaussianBlur(inv_gray, (11, 11), 0)
inv_blur = 255 - blur_img
cv.GaussianBlur(inv_gray, (11, 11), 0)
принимает на вход три параметра: исходное изображения, размеры прямоугольника, откуда берется среднее показание для определения яркости текущего пикселя и так называемая sigma. Пока она нам не нужна, оставим 0.
Осталось только наложить на наше серое изображение замыленное в с яркостью белого 255 и готово. делаем это так:
sketch_img = cv.divide(gray, inv_blur, scale=255.0)
Кульминация
Давайте добавим еще просмотр каждого этапа до нажатия по кнопке. Тут я думаю объяснения излишни:
cv.imshow("orig", orig)
cv.waitKey()
cv.imshow("gray", gray)
cv.waitKey()
cv.imshow("inv_gray", inv_gray)
cv.waitKey()
cv.imshow("blur_img", blur_img)
cv.waitKey()
cv.imshow("inv_blur", inv_blur)
cv.waitKey()
cv.imshow("sketch_img", sketch_img)
cv.waitKey()
cv.imwrite("sketch.jpg", sketch_img)
cv.destroyAllWindows()
В конце я ещё сохраняю результат. Собираем проект и смотрим, что у нас получилось.
![Поэтапно 1 Поэтапно 1](https://habrastorage.org/getpro/habr/upload_files/8d8/df5/ce9/8d8df5ce91a9e395950319768a393310.png)
![Поэтапно 2 Поэтапно 2](https://habrastorage.org/getpro/habr/upload_files/2ee/690/75e/2ee69075e7d654575b5acb2bbf325f7f.png)
![Результат) Результат)](https://habrastorage.org/getpro/habr/upload_files/898/327/cc2/898327cc2d705973c5ea60ace2420eff.jpg)
Четкость можно регулировать прямоугольником блюра и разрешением камеры.
Завязка
Давайте на последок для новичков ещё покажу как брать изображение с камеры в openCV.
Для этого сначала инициализируем нашу камеру, затем будем получать с нее фрейм до нажатия на кнопку. последний полученный кадр будет нашим изображением.
cam = cv.VideoCapture(0)
while True:
_, frame = cam.read()
cv.imshow("monit", frame)
k = cv.waitKey(5)
if k == ord("q"):
cv.imwrite("me.jpg", frame)
break
Ну а всё вместе выглядит так:
import cv2 as cv
cam = cv.VideoCapture(0)
while True:
_, frame = cam.read()
cv.imshow("monit", frame)
k = cv.waitKey(5)
if k == ord("q"):
cv.imwrite("me.jpg", frame)
break
orig = cv.imread('me.jpg')
gray = cv.cvtColor(orig, cv.COLOR_BGR2GRAY)
inv_gray = 255 - gray
blur_img = cv.GaussianBlur(inv_gray, (11, 11), 0)
inv_blur = 255 - blur_img
sketch_img = cv.divide(gray, inv_blur, scale=255.0)
cv.imshow("orig", orig)
cv.waitKey()
cv.imshow("gray", gray)
cv.waitKey()
cv.imshow("inv_gray", inv_gray)
cv.waitKey()
cv.imshow("blur_img", blur_img)
cv.waitKey()
cv.imshow("inv_blur", inv_blur)
cv.waitKey()
cv.imshow("sketch_img", sketch_img)
cv.waitKey()
cv.imwrite("sketch.jpg", sketch_img)
cv.destroyAllWindows()
Эпилог
Ну вроде всё рассказал, что хотел) Буду очень рад комментариям. Читайте предыдущие части)