图像处理——光效公式
2015-08-04 11:32
260 查看
#include "stdafx.h" #include <graphics.h> #include <windows.h> #include <conio.h> #include <math.h> #include <stdio.h> #define GRP(x, y) GetRValue(getpixel(x, y)) #define GGP(x, y) GetGValue(getpixel(x, y)) #define GBP(x, y) GetBValue(getpixel(x, y)) #define #define PI 3.1415926535 //圆周率 #define WIDTH 504 //屏幕宽 #define HEIGHT 600 //屏幕高 #define MODE 0 //为零,灰度高斯模糊;为1, 彩色高斯模糊 #define S 2 //锐化系数,百分制 #define R 2 //搜索半径 #define GRAYSV 30 //灰度阈值 int main(void) { void Sepia(); //怀旧风格,老照片 void Comic(); //连环画风格 void GBlur(); //模糊,高斯模糊的特例 void Screen(); //叠加模式:屏幕、滤色模式,需要复制图层 void SoftLight(); //叠加模式:柔光,需要复制图层 void Multiply(); //叠加模式:正片叠底模式,需要复制图层 void ColorDodge(); //叠加模式:颜色减淡模式,需要复制图层 void MaxFilter(); //滤镜,最大化,需要复制图层 void MinFilter(); //滤镜,最小化,需要复制图层 void WoodCarving(); //木雕效果,需要复制图层 void Pencil(); //铅笔画效果,需要复制图层 void Sharpen(); //锐化,需要复制图层 void Soften(); //柔化,需要复制图层 void BgR(); //交换蓝色和红色 void Diffuse(); //扩散,需要复制图层 void CarveLR(); //雕刻:自左向右,需要复制图层 void ColortoGRay(); //彩色转灰度 void Invert(); //反相 void CopyLayer(); //图层复制 void LR(); //左右颠倒,需要复制图层 initgraph(WIDTH, HEIGHT); //初始化600×600的绘图窗口 setbkcolor(WHITE); //设置背景色 cleardevice(); //清空屏幕 loadimage(NULL, "F:beauty.jpg"); CopyLayer(); // ColortoGRay(); // Invert(); // ColorDodge(); // MinFilter(); // SoftLight(); // Screen(); // Multiply(); // WoodCarving(); // Pencil(); // Sharpen(); // BgR(); // Soften(); // Diffuse(); // CarveLR(); // LR(); // GBlur(); // Comic(); Sepia(); /* 打印高斯变换矩阵 for(int i = 0; i <2 * N + 1; i++){ for(int j = 0; j <2 * N + 1; j++) printf("%.8lf ", GaussT[i][j] ); putchar('\n'); } */ getch(); closegraph(); return 0; } //怀旧,老照片风格 void Sepia() { int br, bg, bb; int mr, mg, mb; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = GRP(x, y); bg = GGP(x, y); bb = GBP(x, y); mr = (101 * br + 197 * bg + 48 * bb) >> 8; mg = (89 * br + 176 * bg + 43 * bb) >> 8; mb = (70 * br + 137 * bg + 34 * bb) >> 8; putpixel(x, y, RGB(mr > 255? 255 : mr, mg > 255? 255 : mg, mb > 255? 255 : mb )); } } //连环画风格,与灰度相似,但增大了对比度,整体明暗效果更强 void Comic() { void ColortoGRay(); int br, bg, bb; int mr, mg, mb; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = GRP(x, y); bg = GGP(x, y); bb = GBP(x, y); mr = (abs(bg - bb + bg + br) * br) >> 8; mg = (abs(bb - bg + bb + br) * br) >> 8; mb = (abs(bb - bg + bb + br) * bg) >> 8; putpixel(x, y, RGB(mr > 255? 255 : mr, mg > 255? 255 : mg, mb > 255? 255 : mb )); } ColortoGRay(); } //模糊, 其实这是高斯模糊的一个特例而已。任意SIGMA的模糊,计算量太多,我就不写了 //因为SIGMA太小,所以不仔细看效果不明显,就不截图了 void GBlur() { int br, bg, bb; int tem[3][3] = {1, 2, 1, 2, 4, 2, 1, 2, 1}; //变换阵 * 16 for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = bg = bb = 0; for(int i = -1; i <= 1; i++) for(int j = -1; j <= 1; j++){ br += GRP(x + i, y + i) * tem[i + 1][j + 1]; bg += GGP(x + i, y + i) * tem[i + 1][j + 1]; bb += GBP(x + i, y + i) * tem[i + 1][j + 1]; } putpixel(x, y, RGB(br >>4, bg >> 4, bb >> 4)); //右移4位比除以16快多了 } } //左右替换, 图片不要太大,仿此可写其它函数 void LR() { for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ) putpixel(x, y, getpixel(WIDTH + WIDTH - x, y)); } //柔光模式 void SoftLight() { int br, bg, bb; int mr, mg, mb; int cdr, cdg, cdb; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = GRP(x, y); bg = GGP(x, y); bb = GBP(x, y); mr = GRP(x + WIDTH, y); mg = GGP(x + WIDTH, y); mb = GBP(x + WIDTH, y); cdr = (int)(mr > 127.5? br + (255 - br) * (mr - 127.5) / 127.5 * (0.5 - fabs(br - 127.5) / 255) : br - br * (127.5 - mr) / 127.5 * (0.5 - fabs(br - 127.5) / 255)); cdg = (int)(mg > 127.5? bg + (255 - bg) * (mg - 127.5) / 127.5 * (0.5 - fabs(bg - 127.5) / 255) : bg - bg * (127.5 - mg) / 127.5 * (0.5 - fabs(bg - 127.5) / 255)); cdb = (int)(mb > 127.5? bb + (255 - bb) * (mb - 127.5) / 127.5 * (0.5 - fabs(bb - 127.5) / 255) : bb - bb * (127.5 - mb) / 127.5 * (0.5 - fabs(bb - 127.5) / 255)); putpixel(x, y, RGB(cdr, cdg, cdb)); } } //叠加模式 void OverLay() { int br, bg, bb; int mr, mg, mb; int cdr, cdg, cdb; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = GRP(x, y); bg = GGP(x, y); bb = GBP(x, y); mr = GRP(x + WIDTH, y); mg = GGP(x + WIDTH, y); mb = GBP(x + WIDTH, y); cdr = (int)(br + (mr - 127.5) * (1 - fabs(br - 127.5) / 127.5)); cdg = (int)(bg + (mg - 127.5) * (1 - fabs(bg - 127.5) / 127.5)); cdb = (int)(bb + (mb - 127.5) * (1 - fabs(bb - 127.5) / 127.5)); putpixel(x, y, RGB(cdr, cdg, cdb)); } } //屏幕、滤色模式 void Screen() { int br, bg, bb; int mr, mg, mb; int cdr, cdg, cdb; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = GRP(x, y); bg = GGP(x, y); bb = GBP(x, y); mr = GRP(x + WIDTH, y); mg = GGP(x + WIDTH, y); mb = GBP(x + WIDTH, y); cdr = br + mr - br * mr / 255; cdg = bg + mg - bg * mg / 255; cdb = bb + mb - bb * mb / 255; putpixel(x, y, RGB(cdr, cdg, cdb)); } } //正片叠底模式 void Multiply() { int br, bg, bb; int mr, mg, mb; int cdr, cdg, cdb; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = GRP(x, y); bg = GGP(x, y); bb = GBP(x, y); mr = GRP(x + WIDTH, y); mg = GGP(x + WIDTH, y); mb = GBP(x + WIDTH, y); cdr = br * mr / 255; cdg = bg * mg / 255; cdb = bb * mb / 255; putpixel(x, y, RGB(cdr, cdg, cdb)); } } //颜色减淡 本点 = 基色 + 基色*混合色/(255 - 混合色) void ColorDodge() { int br, bg, bb; int mr, mg, mb; int cdr, cdg, cdb; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ br = GRP(x, y); bg = GGP(x, y); bb = GBP(x, y); //基础色 mr = GRP(x + WIDTH, y); mg = GGP(x + WIDTH, y); mb = GBP(x + WIDTH, y); //混合色 cdr = (br + (br * mr) / (256 - mr)) > 255? 255 : (br + (br * mr) / (256 - mr)); cdg = (bg + (bg * mg) / (256 - mg)) > 255? 255 : (bg + (bg * mg) / (256 - mg)); cdb = (bb + (bb * mb) / (256 - mb)) > 255? 255 : (bg + (bg * mg) / (256 - mg)); //结果色 putpixel(x, y, RGB(cdr, cdg, cdb)); } } //滤镜·最大化。 //滤镜·最大化。搜索周围的点,取最大值替代本像素 void MaxFilter() { int r, g, b; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ r = GRP(x, y); g = GGP(x, y); b = GBP(x, y); for(int i = -1 * R; i <= R; i++) for(int j = -1 * R; j <= R; j++){ r = (r < GRP(x + i + WIDTH, y + i)? GRP(x + i + WIDTH, y + i) : r); g = (g < GGP(x + i + WIDTH, y + i)? GGP(x + i + WIDTH, y + i) : g); b = (b < GBP(x + i + WIDTH, y + i)? GBP(x + i + WIDTH, y + i) : b); } putpixel(x, y, RGB(r, g, b)); } } //滤镜·最小化。 //滤镜·最小化。搜索周围的点,取最小值替代本像素 void MinFilter() { int r, g, b; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ r = GRP(x, y); g = GGP(x, y); b = GBP(x, y); for(int i = -1 * R; i <= R; i++) for(int j = -1 * R; j <= R; j++){ r = (r > GRP(x + i + WIDTH, y + i)? GRP(x + i + WIDTH, y + i) : r); g = (g > GGP(x + i + WIDTH, y + i)? GGP(x + i + WIDTH, y + i) : g); b = (b > GBP(x + i + WIDTH, y + i)? GBP(x + i + WIDTH, y + i) : b); } putpixel(x, y, RGB(r, g, b)); } } //木雕 //如果本点灰度与临近点灰度大于阈值,置白色;否则,置黑色 void WoodCarving() { for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ if((abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y + 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y - 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y - 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y + 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y - 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y + 1)) > GRAYSV)) putpixel(x, y, WHITE); else putpixel(x, y, BLACK); } } //铅笔画 //如果本点灰度与临近点灰度大于阈值,置黑色;否则,置白色 void Pencil() { void ColortoGRay(); ColortoGRay(); for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ if((abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y + 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y - 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y - 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y + 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y - 1)) > GRAYSV) || (abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y + 1)) > GRAYSV)) putpixel(x, y, BLACK); else putpixel(x, y, WHITE); } } //锐化,搜索周围半径为R范围内的点, //差值 = 本点 - 周围点的平均值 //本点 = 本点 + 差值 * 锐化系数S void Sharpen() { int r, g, b; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ r = g = b = 0; for(int i = -1 * R; i <= R; i++) for(int j = -1 * R; j <= R; j++){ if(i == 0 && j == 0) continue; r += GRP(x + i + WIDTH, y + j); g += GGP(x + i + WIDTH, y + j); b += GBP(x + i + WIDTH, y + j); } r = GRP(x + WIDTH, y) * (1 + S) - r * S / (4 * R * R + 4 * R); g = GGP(x + WIDTH, y) * (1 + S) - g * S / (4 * R * R + 4 * R); b = GBP(x + WIDTH, y) * (1 + S) - b * S / (4 * R * R + 4 * R); r = r > 255? 255 : r; g = g > 255? 255 : g; b = b > 255? 255 : b; r = r < 0? 0 : r; g = g < 0? 0 : g; b = b < 0? 0 : b; putpixel(x, y, RGB(r, g, b)); } } //柔化,搜索周围半径为R范围内的点, //本点 = 本点及周围点的平均值 void Soften() { int r, g, b; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ r = g = b = 0; for(int i = -1 * R; i <= R; i++) for(int j = -1 * R; j <= R; j++){ r += GRP(x + i + WIDTH, y + j); g += GGP(x + i + WIDTH, y + j); b += GBP(x + i + WIDTH, y + j); } r /= (4 * R * R + 4 * R + 1); g /= (4 * R * R + 4 * R + 1); b /= (4 * R * R + 4 * R + 1); putpixel(x, y, RGB(r, g, b)); } } //扩散,随机用周围R的一个点代替本点 void Diffuse() { int x0, y0; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ x0 = abs(rand()) % (2 * R + 1) - R; y0 = abs(rand()) % (2 * R + 1) - R; putpixel(x, y, getpixel(x + x0 + WIDTH, y + y0)); } } //雕刻,自左向右,本点 = 本点 - 右点 +127 void CarveLR() { int r, g, b; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ r = GRP(x, y) - GRP(x + 1, y) + 127; g = GGP(x, y) - GGP(x + 1, y) + 127; b = GBP(x, y) - GBP(x + 1, y) + 127; //127为调整后的亮度,可调 putpixel(x, y, RGB(r, g, b)); } } //图层复制 void CopyLayer() { Resize(NULL, WIDTH + WIDTH, HEIGHT); for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ putpixel(x + WIDTH, y, getpixel(x, y)); } } //彩色转变为灰度,将彩色点由计算出的灰度替代 //覆盖法 void ColortoGRay() { for(int x = 0; x < 2 * WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ int gRay = RGBtoGRAY(getpixel(x, y)); putpixel(x, y, RGB(gRay, gRay, gRay)); } } //反相,本点 = 255 -本点, 即互补 void Invert() { int IR, IG, IB; for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ){ IR = 255 - GRP(x, y); IG = 255 - GGP(x, y); IB = 255 - GBP(x, y); putpixel(x, y, RGB(IR, IG, IB)); } } //交换颜色中的红色和蓝色值 void BgR() { for(int x = 0; x < WIDTH; x++) for(int y = 0; y < HEIGHT; y++ ) putpixel(x, y, BGR(getpixel(x, y))); }
相关文章推荐
- PHP GD 图像处理组件的常用函数总结
- PHP图像处理之imagecreate、imagedestroy函数介绍
- jsvascript图像处理―(计算机视觉应用)图像金字塔
- Javascript图像处理思路及实现代码
- PHP图像处理之使用imagecolorallocate()函数设置颜色例子
- java数字图像处理基础使用imageio写图像文件示例
- javascript图像处理―边缘梯度计算函数
- Javascript图像处理―阈值函数实例应用
- Javascript图像处理―虚拟边缘介绍及使用方法
- PHP图像处理类库及演示分享
- php图像处理函数大全(推荐收藏)
- Javascript图像处理―图像形态学(膨胀与腐蚀)
- Javascript图像处理―平滑处理实现原理
- VTK学习笔记之图像处理
- vtk 图像处理 多种 操作
- 05-VTK在图像处理中的应用(2)
- 新手上路之图像处理学习心得
- 数字图像处理的基础
- 数字图像处理的基础
- 图像的放大与缩小(1)——等距采样法