Урок 4: разбор проблем прошлого задания, морфология (как поправить тексты ошибок если квакозябры)
КАК СДЕЛАТЬ ОШИБКИ КОМПИЛЯЦИИ НА РУССКОМ (если сейчас квакозябры)
File->Settings->Editor->General->Console: Default Encoding = IBM866
Если вы все сделали
1) Реализуйте морфологическое расширение картинки dilate
(как функцию которая принимает на вход маску + радиус расширения, и выдает на выход маску).
2) Реализуйте морфологическое сжатие картинки erode
.
3) На их базе придумайте как сглаживать маску “пиксель является фоном или не является фоном” так чтобы границы хорошо отмаскированного фона не сместились, а лишь загладились шумные пиксели?
4) Что будет если сначала сжать маску, а затем расширить (erode -> dilate
)? Что будет если сделать наоборот (dilate -> erode
)?
5) Добавьте на фон вместо статического фона - какую-нибудь анимацию. К сожалению та версия opencv которую мы используем (т.к. ее легко установить) не умеет открывать mp4
файлы, поэтому если хочется считывать видео - предварительно разбейте его на кадры названные 0.jpg, 1.jpg, 2.jpg и т.д. и считывайте их. Да, костыль, но это самое простое решение.
6) Попробуйте придумать а как можно было бы рисовать на фоне процедурно генерирующиеся случайные взрывы/салют/полет сквозь звезды?
Несколько советов по прошлой домашке
0) Если картинка не считывается (размера 0х0
) - проверьте путь к картинке (включая папки, название картинки и расширение картинки - png/jpg/jpeg/JPG
?), проверьте что working directory выставлен.
0) Как отлаживать программу кроме вывода в коноль и запуска под отладчиком - постарайтесь делать микро изменения программы и проверять что она работает. Тогда если вдруг она перестанет работать - будет ясно какие строчки виноваты, и где искать багу. Поэтому золотое правило - двигаться по мини шажкам, и после каждого шажка осматриваться вокруг чтобы понять где вы оказались и работает ли программа так как ожидалось.
1) Как создавать пустую картинку? Допустим мы определились с размером и хотим сделать цветную (BGR) картинку с восьми битными каналами (т.е. яркость в каждом канале от 0 до 255):
Достаточно легко нагуглить по запросу opencv cpp new image
:
int width = 1024;
int height = 768;
Scalar color(0, 0, 0);
Mat myNewImage(height, width, CV_8UC3, color); // обратите внимание что сначала идет высота (т.к. сначала идет число строчек, т.е. число рядов матрицы)
// третьим аргументом в конструктор передается описание типа каждого пикселя:
// - CV - OpenCV ()
// - 8 - это число бит = размер каждого канала (поэтому от 0 до 255)
// - UC = unsigned char = неотрицательное целое число
// - color = Scalar(0, 0, 0) - цвет которым изначально будет заполнена вся картинка
А что если мы хотим создать одноканальную картинку где в каждом пикселе - вещественное число (float
)? Гуглим opencv cpp new float image
и находим ключевое слово описывающее подходящий тип - CV_32FC1
- 32 бита, F = float
, C1 = 1 channel = один канал, вместо трех каналов в случае BGR
:
Mat myFloatingPointImage(height, width, CV_32FC1, Scalar(1.5f)); // в этом примере мы решили изначально заполнить картинку числом 1.5
2) Как увеличить картинку в размере?
Пусть есть картинка размером a x b
и надо ее преобразовать в картинку c x d
.
Пробежимся по каждому пикселю пока пустой картинки размером c x d
(т.е. мы создали новую пустую картинку и теперь ее хотим заполнить).
Внутри вложенного цикла у нас есть координаты пикселя-цели y, x
, осталось лишь рассчитать координаты пикселя-донора (т.е. откуда перенести цвет).
Это можно сделать с помощью пропорции навроде x = x / c * d
.
Обратите внимание что все числа здесь целые, а значит при делении выполняется округление вниз, но x
всегда меньше c
, тогда какой будет результат деления?
Чтобы это поправить надо либо сначала домножать а потом делить, либо выполнять деление в вещественных числах, например банально домножив на 1.0
перед тем как проводить деление, и тогда оно будет в вещественных числах, т.е. без округления вниз.
3) Как понять в каком пикселе вебкамеры фон, а в каком - человек?
Пусть есть фотографии А и Б с одинаковым фоном. Пусть на фотографии А кроме фона есть еще и объект (ваше лицо).
Тогда для каждого пикселя картинки А можно проверить - похож ли он по цвету (в каждом канале из BGR) на пиксель с такими же координатами в картинке Б?
Если похож - это скорее-всего фон и его надо сделать прозрачным (заменить на цвет пикселя из нового фона который хочется подложить под объект), иначе - это объект (ваше лицо) и его надо оставить как есть.
4) Как отлаживать подкладывание фона по вебкамере?
Удобно тестировать на одних и тех же фотографиях - поэтому для отладки и улучшения алгоритма очень удобно сохранить пару кадров с вебкамеры и тестироваться на них (вместо живого потока с вебкамеры каждый раз).
Тогда от запуска к запуску поведение программы будет совпадать, а это очень удобно для того чтобы найти ошибки или просто улучшить алгоритм.
Проблемы при компиляции
1) Если видите ошибку вроде is not able to compile a simple test program.
- то вероятно проект находится на диске по пути содержащем русские буквы, чаще всего это из-за того что у вас имя пользователя на русском.
Поможет перенести папку проекта целиком по новому пути (например создайте на диске C папку CPPSchool
и перенесите проект туда), и затем открыть его из CLion по этому новому пути через File->Open.
2) Если видите ошибку и там встречается слово mingw
- откройте File->Settings->Toolchain и с помощью стрелочки поднимите Visual Studio выше MinGW, заодно убедитесь что выбрано Architecture: amd64
3) Если видите ошибку “fatal error LNK1120” - откройте File->Settings->Toolchain - поправьте Architecture с х86 на amd64