КАК СДЕЛАТЬ ОШИБКИ КОМПИЛЯЦИИ НА РУССКОМ (если сейчас квакозябры)

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