Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
convolution применяется для обработки изображения путем наложения на него нужного фильтра.
Принцип работы заключается в перемножение близлежащих цветов пикселей на соответствующую двухмерную матрицу.
Результаты складываются и делятся на количество перемноженных пикселей. Это и будет результативный цвет пикселя.
Каждый канал RGB рассчитывается отдельно.
От матрицы ядра свертки зависит получаемый эффект.
Подробнее Ядро свертки
С помощью фильтров можно получать контуры изображения, повышать резкость, размывать, тиснение и множество других эффектов.
CODE:convolution (0, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
CODE:convolution (0, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, -1);
CODE:win w=window ("Mozilla Firefox", "MozillaWindowClass", -1);
convolution (0, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, w);
Первый параметр = 0 или 1 или 2 или 3
0 - В результативное изображение будет записан полученный от расчетов цвет, не зависимо от того какой цвет был там записан до этого. Если ни один из каналов RGB расчетного цвета не превысил параметр 6, пиксель закрашивается черным цветом.
1 - Если рассчитанный цвет ниже ранее записанного там цвета, остается прежний цвет. Иначе работает как при 0. Применяется для добавления в результативное изображение если там уже что то есть.
2 - В результативное изображение будет записан исходный цвет изображения, не зависимо от того какой цвет был там записан до этого. Если ни один из каналов RGB расчетного цвета не превысил параметр 6, пиксель закрашивается черным цветом.
3 - Если рассчитанный цвет ниже ранее записанного там цвета, остается прежний цвет. Иначе работает как при 2. Применяется для добавления в результативное изображение если там уже что то есть.
Второй параметр - Указатель на двухмерный массив int или double. Этот массив содержит в себе ядро свертки. Фильтр.
Третий и четвертый параметры - Ширина и высота ядра свертки.
Пятый параметр - Указатель на двухмерный массив int для сохранения результативного изображения. Допускается использовать указатель на исходное изображение. В этом случае оно будет и исходным и результативным и будет перезаписано.
Шестой параметр - Число указывающее что если ни один из каналов рассчитанного цвета не превысил этот параметр, в данный пиксель запишется 0 (черный цвет).
Седьмой - десятый параметры - Обрабатываемая зона исходного изображения.
Восьмой параметр - Указатель на двухмерный массив int в котором содержится исходное изображение. Или -1, тогда будет сделан снимок всего экран, или указатель на окно.
Примеры:
Имеем исходное изображение
Пример как выделить все горизонтальные линии контура:
Результативное изображение будет содержать в себе рассчитанные цвета
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=-1;//Укажем что все цвета будут записаны
//Ядро
double M[3][3];
M[0][0]=-1; M[1][0]=-1; M[2][0]=-1;
M[0][1]=2; M[1][1]=2; M[2][1]=2;
M[0][2]=-1; M[1][2]=-1; M[2][2]=-1;
double K=3;//Множитель интенсивности фильтра
for (int x=0; x<3; x++){for (int y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (0, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
==========================================================
Результативное изображение будет содержать в себе исходные цвета, если результативный цвет равен или более параметру 6 Del_Col
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=50;//Закрашиваем черным цветом все пикселя в которых ни один из компонентов расчетного цвета не превысил 50
//Ядро
double M[3][3];
M[0][0]=-1; M[1][0]=-1; M[2][0]=-1;
M[0][1]=2; M[1][1]=2; M[2][1]=2;
M[0][2]=-1; M[1][2]=-1; M[2][2]=-1;
double K=3;//Множитель интенсивности фильтра
for (int x=0; x<3; x++){for (int y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (2, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
==========================================================
Пример как выделить все вертикальные линии контура:
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=50;
//Ядро
double M[3][3];
M[0][0]=-1; M[1][0]=2; M[2][0]=-1;
M[0][1]=-1; M[1][1]=2; M[2][1]=-1;
M[0][2]=-1; M[1][2]=2; M[2][2]=-1;
double K=3;//Множитель интенсивности фильтра
for (int x=0; x<3; x++){for (int y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (2, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
==========================================================
Пример как применить два фильтра и результат записать в результативное изображение:
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=50;
//Ядро
double M[3][3];
M[0][0]=-1; M[1][0]=-1; M[2][0]=-1;
M[0][1]=2; M[1][1]=2; M[2][1]=2;
M[0][2]=-1; M[1][2]=-1; M[2][2]=-1;
double K=3;//Множитель интенсивности фильтра
for (int x=0; x<3; x++){for (int y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (2, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
M[0][0]=-1; M[1][0]=2; M[2][0]=-1;
M[0][1]=-1; M[1][1]=2; M[2][1]=-1;
M[0][2]=-1; M[1][2]=2; M[2][2]=-1;
K=3;//Множитель интенсивности фильтра
for (x=0; x<3; x++){for (y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (3, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
==========================================================
Пример получение контура одним фильтром:
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=60;
//Ядро
double M[3][3];
M[0][0]=0; M[1][0]=-3; M[2][0]=0;
M[0][1]=-3; M[1][1]=12; M[2][1]=-3;
M[0][2]=0; M[1][2]=-3; M[2][2]=0;
double K=3;//Множитель интенсивности фильтра
for (int x=0; x<3; x++){for (int y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (2, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
==========================================================
Пример увеличения резкости:
Имеем изображение
Получим
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=-1;
//Ядро
double M[3][3];
M[0][0]=0; M[1][0]=-1; M[2][0]=0;
M[0][1]=-1; M[1][1]=7; M[2][1]=-1;
M[0][2]=0; M[1][2]=-1; M[2][2]=0;
double K=3;//Множитель интенсивности фильтра
for (int x=0; x<3; x++){for (int y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (0, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
==========================================================
Пример размытия:
Имеем изображение
Получим
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=-1;
//Ядро
double M[5][5];
///////////////////------------------
M[0][0]=0.000789; M[1][0]=0.006581; M[2][0]=0.013347; M[3][0]=0.006581; M[4][0]=0.000789;
M[0][1]=0.006581; M[1][1]=0.054901; M[2][1]=0.111345; M[3][1]=0.0549011; M[4][1]=0.006581;
M[0][2]=0.013347; M[1][2]=0.111345; M[2][2]=0.225821; M[3][2]=0.111345; M[4][2]=0.013347;
M[0][3]=0.006581; M[1][3]=0.054901; M[2][3]=0.111345; M[3][3]=0.054901; M[4][3]=0.006581;
M[0][4]=0.000789; M[1][4]=0.006581; M[2][4]=0.013347; M[3][4]=0.006581; M[4][4]=0.000789;
double K=25;//Множитель интенсивности фильтра
for (int x=0; x<5; x++){for (int y=0; y<5; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (0, #M[0][0], 5, 5, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
==========================================================
Пример тиснения:
Имеем изображение
Получим
CODE:int Screen[2000][2000];//Исходное изображение
int Rez[2000][2000];//Результативное изображение
int Col, Ex, Ey;
getdisplay(Col, Ex, Ey);
screen (#Screen[0][0], 0, 0, Ex, Ey, -1);//Делаем скрин экрана
int Del_Col=-1;
//Ядро
double M[3][3];
M[0][0]=9; M[1][0]=2; M[2][0]=9;
M[0][1]=2; M[1][1]=9; M[2][1]=-20;
M[0][2]=9; M[1][2]=-20; M[2][2]=9;
double K=1;//Множитель интенсивности фильтра
for (int x=0; x<3; x++){for (int y=0; y<3; y++){
M[x][y]=M[x][y]*K;}}
//Применяем фильтр
convolution (0, #M[0][0], 3, 3, #Rez[0][0], Del_Col, 0, 0, Ex, Ey, #Screen[0][0]);
//Сохраняем результат в файл
saveimage(#Rez[0][0], "D:\Rez.bmp");
|