SCARA-Laser. Часть 3. Начинаем обрабатывать изображение
Пролог
Всем привет! Как и обещал, начинаем разбирать часть машинного зрения в данном проекте. Для начала разберемся, что мы имеем и что хотим в итоге получить. Имеем мы цветное изображение человеческого лица. Пусть пока оно у нас просто будет, потому что получение изображение с камеры на Raspberry Pi — тема вполне известная , отдельно на ней акцентировать внимание не буду.
Предположим вот. Теперь вы можете меня найти и побить за кривой код)
Нам нужно:
Сделать так, чтобы лазер отличал одни пиксели от других
Почистить всё лишнее
Иными словами — переводим цвет в чб и векторизуем растр. Получить надо что-то похожее на карандашный рисунок.
Завязка
Для начала установим библиотеку 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
Поэтапно 2
Результат)
Четкость можно регулировать прямоугольником блюра и разрешением камеры.
Завязка
Давайте на последок для новичков ещё покажу как брать изображение с камеры в 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()
Эпилог
Ну вроде всё рассказал, что хотел) Буду очень рад комментариям. Читайте предыдущие части)