Photoshop图像算法(十)(代码在每个原理后面)
八方向浮雕算法
在 Photoshop 中,八方向浮雕效果(Emboss)主要是通过对图像进行高度图的处理,以模拟三维效果。其基本原理和算法可以归纳为以下几个步骤:
原理
-
高度图生成:将图像的亮度信息转化为高度。通常,亮部会被视为“高”,而暗部会被视为“低”。
-
法线计算:计算每个像素点的法线向量。通过对相邻像素的高度差进行比较,来确定表面在x和y方向的斜率。
-
光照模拟:根据法线向量和指定的光照方向计算每个像素的光照强度,以产生阴影和高光效果。
-
最终效果合成:将得到的光照信息与原始图像结合,形成浮雕效果。
算法步骤
-
灰度化:将输入图像转换为灰度图像,以便于进行高度处理。
-
获取邻域像素值:对每个像素,获取其周围邻域(通常是3x3或5x5)像素的值。
-
计算法线:
- 使用如下公式计算x和y方向的梯度(假设以 (i, j) 为中心像素):
- 使用如下公式计算x和y方向的梯度(假设以 (i, j) 为中心像素):
-
计算浮雕效果:
- 使用以下公式来生成浮雕效果:
- 其中,(\text{sign}(x)) 返回 x 的符号(正为 1,负为 -1,零为 0)。
- 使用以下公式来生成浮雕效果:
-
应用光照模型:
- 假设光源方向为 (Lx, Ly, Lz),则每个像素的亮度可以由法线 (Nx, Ny, Nz) 与光源方向的点积来决定:
- 假设光源方向为 (Lx, Ly, Lz),则每个像素的亮度可以由法线 (Nx, Ny, Nz) 与光源方向的点积来决定:
-
对像素值进行归一化:将浮雕效果的值限制在0到255之间,使其符合图像的像素值范围。
注意事项
- 光源方向的选择会影响突出的效果。
- 在实际应用过程中,可能会结合其他图像处理技术,如模糊和锐化,以增强浮雕效果。
- 调整参数(如光照强度、浮雕深度等)可以产生不同的视觉效果。
这些步骤和公式概述了八方向浮雕效果的基本实现方法,可以在 Photoshop 或其他图像处理软件中进行类似的操作。
//8方向浮雕
enum DIR
{N,NE,E,SE,S,SW,W,NW
};Mat DiamondEmboss(Mat src, DIR dir = SE, int offset = 127) {int row = src.rows;int col = src.cols;int ioffset = 0;int joffset = 0;switch (dir){case N:ioffset = -1;joffset = 0;break;case NE:ioffset = -1;joffset = 1;break;case E:ioffset = 0;joffset = 1;break;case SE:ioffset = 1;joffset = 1;break;case S:ioffset = 1;joffset = -1;break;case SW:ioffset = 0;joffset = -1;break;case W:ioffset = 0;joffset = -1;break;case NW:ioffset = 1;joffset = 1;break;default:break;}Mat dst(row, col, CV_8UC3);int border = 1;for (int i = border; i < row - border; i++) {for (int j = border; j < col - border; j++) {for (int k = 0; k < 3; k++) {int sum = src.at<Vec3b>(i, j)[k] - src.at<Vec3b>(i - ioffset, j - joffset)[k] + offset;if (sum < 0) sum = -sum;if (sum < 64) sum = 64;if (sum > 255) sum = 255;dst.at<Vec3b>(i, j)[k] = sum;}}}return dst;
}
其他色彩特效
Mat ColorTrans(Mat src, int op) {//op=1 呈现碧绿效果,就是要使色彩呈暗绿色,给人诡异的感觉int row = src.rows;int col = src.cols;Mat dst(row, col, CV_8UC3);if (op == 1) {for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int R = (g - b) * (g - b) / 128;int G = (r - b) * (r - b) / 128;int B = (r - g) * (r - g) / 128;if (R > 255) R = 255;if (R < 0) R = 0;if (G > 255) G = 255;if (G < 0) G = 0;if (B > 255) B = 255;if (B < 0) B = 0;dst.at<Vec3b>(i, j)[0] = B;dst.at<Vec3b>(i, j)[1] = G;dst.at<Vec3b>(i, j)[2] = R;}}}else if (op == 2) {//op=2 棕褐色效果就是要实现那种图像模糊、略带发黄的老照片的感觉,别具风情for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int R = 0.393 * r + 0.769 * g + 0.189 * b;int G = 0.349 * r + 0.686 * g + 0.168 * b;int B = 0.272 * r + 0.534 * g + 0.131 * b;if (R > 255) R = 255;if (R < 0) R = 0;if (G > 255) G = 255;if (G < 0) G = 0;if (B > 255) B = 255;if (B < 0) B = 0;dst.at<Vec3b>(i, j)[0] = B;dst.at<Vec3b>(i, j)[1] = G;dst.at<Vec3b>(i, j)[2] = R;}}}else if (op == 3) {//op=3 冰冻效果就是使图像呈现一种晶莹的淡蓝色for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int R = abs(r - g - b) * 3 / 2;int G = abs(g - b - r) * 3 / 2;int B = abs(b - r - g) * 3 / 2;if (R > 255) R = 255;if (R < 0) R = 0;if (G > 255) G = 255;if (G < 0) G = 0;if (B > 255) B = 255;if (B < 0) B = 0;dst.at<Vec3b>(i, j)[0] = B;dst.at<Vec3b>(i, j)[1] = G;dst.at<Vec3b>(i, j)[2] = R;}}}else if (op == 4) {//op=4 熔铸效果类似打铁的场景for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int R = r * 128 / (g + b + 1);int G = g * 128 / (b + r + 1);int B = b * 128 / (r + g + 1);if (R > 255) R = 255;if (R < 0) R = 0;if (G > 255) G = 255;if (G < 0) G = 0;if (B > 255) B = 255;if (B < 0) B = 0;dst.at<Vec3b>(i, j)[0] = B;dst.at<Vec3b>(i, j)[1] = G;dst.at<Vec3b>(i, j)[2] = R;}}}else if (op == 5) {//op=5 暗调效果是通过降低色彩的各个分量,使整幅图像变得深谙for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int R = r * r / 255;int G = g * g / 255;int B = b * b / 255;/*if (R > 255) R = 255;if (R < 0) R = 0;if (G > 255) G = 255;if (G < 0) G = 0;if (B > 255) B = 255;if (B < 0) B = 0;*/dst.at<Vec3b>(i, j)[0] = B;dst.at<Vec3b>(i, j)[1] = G;dst.at<Vec3b>(i, j)[2] = R;}}}else if (op == 6) {//op=6 对调效果通过对彩色分量进行轮换的方式重新组合得到新的色彩for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int R = g * b / 255;int G = b * r / 255;int B = r * g / 255;/*if (R > 255) R = 255;if (R < 0) R = 0;if (G > 255) G = 255;if (G < 0) G = 0;if (B > 255) B = 255;if (B < 0) B = 0;*/dst.at<Vec3b>(i, j)[0] = B;dst.at<Vec3b>(i, j)[1] = G;dst.at<Vec3b>(i, j)[2] = R;}}}return dst;
}
更多PS代码请关注我上传的资源文件。
https://download.csdn.net/download/m0_44975814/89896121