图像处理——光效公式

图像处理部分光效公式

#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))); 
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值