您的位置:首页 > 其它

图像处理——光效公式

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)));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图像处理