假设有一幅图,由于成象时光照不足,使得整幅图偏暗(例如,灰度范围从0到63);或者成象时光照过强,使得整幅图偏亮(例如,灰度范围从200到255),我们称这些情况为低对比度,即灰度都挤在一起,没有拉开。灰度扩展的意思就是把你所感性趣的灰度范围拉开,使得该范围内的象素,亮的越亮,暗的越暗,从而达到了增强对比度的目的。

我们可以用下图来说明对比度扩展(contrast stretching)的原理:

图中的横坐标gold表示原图的灰度值,纵坐标gnew表示gold经过对比度扩展后得到了新的灰度值。a,b,c为三段直线的斜率,因为是对比度扩展,所以斜率b>1。g1old和g2old表示原图中要进行对比度扩展的范围,g1new和g2new表示对应的新值。用公式表示为:

实现代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma pack(1)   //全紧凑模式typedef struct {unsigned char bfType[2];unsigned int bfSize;unsigned short bfReserved1;unsigned short bfReserved2;unsigned int bfOffBits;
}bitmapFileHeader;typedef struct {unsigned int biSize;unsigned int biWidth;unsigned int biHeight;unsigned short biPlanes;unsigned short biBitCount;unsigned int biCompression;unsigned int biSizeImage;unsigned int biXPixPerMeter;unsigned int biYPixPerMeter;unsigned int biClrUsed;unsigned int biClrImportant;
}bitmapInfoHeader;typedef struct{unsigned char rgbBlue;unsigned char rgbGreen;unsigned char rgbRed;unsigned char rgbReserved;}rgbQUAD;typedef struct{bitmapFileHeader bfHeader;bitmapInfoHeader biHeader;rgbQUAD palette[256];unsigned char *imgData;
}bmp;int main(){FILE *fp;if((fp=fopen("d:\Temp\\test_gray.bmp","rb"))==NULL){perror("can not open file!");return -1;}//读入彩色bmp图像文件头,信息头和图像数据bitmapFileHeader bfHeader;fread(&bfHeader,14,1,fp);bitmapInfoHeader biHeader;fread(&biHeader,40,1,fp);int imSize=biHeader.biSizeImage;int width=biHeader.biWidth;int height=biHeader.biHeight;int bitCount=biHeader.biBitCount;int lineBytes=(width*bitCount+31)/32*4;fseek(fp,bfHeader.bfOffBits,SEEK_SET);unsigned char*imageData=(unsigned char*)malloc(imSize*sizeof(unsigned char));fread(imageData,imSize*sizeof(unsigned char),1,fp); fclose(fp);bmp b;memcpy(&(b.bfHeader),&bfHeader,sizeof(bfHeader));memcpy(&(b.biHeader),&biHeader,sizeof(biHeader));b.imgData=(unsigned char*)malloc(sizeof(unsigned char)*imSize);memset(b.imgData,0,sizeof(unsigned char)*imSize);for(int i=0;i<256;i++){b.palette[i].rgbBlue=i;b.palette[i].rgbGreen=i;b.palette[i].rgbRed=i;}int i,j,temp;double m=1.5,g1=100.0,g2=200.0; //m在这里对应斜率b,因为“b”这个符号被bmp图像结构名占了double a=(255.0-m*(g2-g1))/(255.0-(g2-g1));for(i=0;i<height;i++){for(j=0;j<width;j++){temp=imageData[lineBytes*i+j];if(temp<g1)b.imgData[lineBytes*i+j]=(unsigned char)(a*temp);else if(temp<g2)b.imgData[lineBytes*i+j]=(unsigned char)(g1+m*(temp-g1));else b.imgData[lineBytes*i+j]=(unsigned char)(g2+a*(temp-g2));}}char savePath[]="D:\Temp\\save_test.bmp";FILE *f_save=fopen(savePath,"wb");if(f_save==NULL){perror("can not open file!");return -2;}fwrite(&b.bfHeader,sizeof(bitmapFileHeader),1,f_save);fwrite(&b.biHeader,sizeof(bitmapInfoHeader),1,f_save);fwrite(&b.palette,1024,1,f_save);fwrite(b.imgData,sizeof(unsigned char)*b.biHeader.biSizeImage,1,f_save);fclose(f_save);free(imageData);free(b.imgData);getchar();return 0;
}

代码效果:

原图像:

灰度(100-200)扩展图像:

C语言实现bmp图像对比度扩展相关推荐

  1. C语言实现bmp图像几何变换(移动,旋转,镜像,转置,缩放)

    C语言实现bmp图像几何变换(移动,旋转,镜像,转置,缩放) 移动 旋转 镜像 转置 缩放 自定义结构及函数如下: #define pi 3.1415926 typedef struct {unsig ...

  2. C语言读取bmp图像并做简单显示

    C语言读取bmp图像并做简单显示) bmp文件格式 读取bmp文件信息并展示 bmp文件格式 bmp文件大体上分为四个部分: bmp文件构成 位图文件头BITMAPFILEHEADER 位图信息头BI ...

  3. C语言实现bmp图像锐化

    锐化(sharpening)和平滑恰恰相反,它是通过增强高频分量来减少图象中的模糊,因此又称为高通滤波(high pass filter).锐化处理在增强图象边缘的同时增加了图象的噪声. 常用的锐化模 ...

  4. C语言读取bmp图像

    BMP图像编码 BMP即bitmap,也就是位图,一般由4部分组成:文件头信息块.图像描述信息块.颜色表(在真彩色模式无颜色表)和图像数据区. 在图像数据之前,如图所示,共有54位数据 其中,0x42 ...

  5. 【图像处理作业】用C语言对bmp图像使用中值滤波、Prewitt算子进行平滑、锐化操作

    相关原理 使用C语言打开8bit灰度图bmp文件并读出相应的每个像素亮度值,因为任何一个图像都可看成单个像素的组合.程序实现了1×1的图像和一个3×3的图像做卷积,并将结果输出成为新的bmp文件 平滑 ...

  6. C语言黑白bmp转字节流,纯C语言对BMP图像的灰度化二值化

    #include "Windows.h" #include #include //using namespace std; // 这个动态申请二维内存(指针数组)的函数很有意思 t ...

  7. c语言怎么计算bmp图像大小,C语言如何取出一张256色位的bmp图像的某个像素的颜色...

    C语言怎么取出一张256色位的bmp图像的某个像素的颜色 我想实现的是:将一张256色位图的bmp图像(1.bmp)上下左右移动N个像素(比如向右移5个像素,最左边的5个像素全涂成黑色)生成另一张图像 ...

  8. C语言实现将彩色bmp图像转化为灰图、灰度图像反色

    彩色图像转灰度图像 彩色(24位)bmp图像结构: typedef struct{bitmapFileHeader bfHeader;bitmapInfoHeader biHeader;unsigne ...

  9. C语言(二)BMP图像 文本数据保存为图像

    BMP图像数据处理 申请空间读取像素数据 读取TXT文本数据,并保存为图像 读取图片,并将数据存入数组 参考 申请空间读取像素数据 使用VS2015连续读取TXT文本数据时,如果申请数组过大时,会导致 ...

最新文章

  1. 线上出现死锁怎么解决?
  2. python conda虚拟环境
  3. 华人小哥控诉机器学习四大 Boring!CS 博士:深有同感,正打算退学
  4. 感冒了,头晕晕沉沉的,什么时候能好啊!
  5. 人工智能-机器学习=深度学习-其他
  6. php类精确验证身份证号码
  7. artdialog5 bug
  8. html导出pdf实例,jsPDF导出pdf示例
  9. B树与B+树【转载】
  10. extmail html文件丢失,extmail/extman登录界面无法显示的故障解决
  11. virtualbox 网络配置
  12. socket.io php 聊天室,WebSocket学习(一)——基于socket.io实现简单多人聊天室
  13. Java经典编程题,你学废了吗?
  14. python反转一个三位数_反转Python整数的位
  15. 斯坦福和伯克利都在用的线性代数教材,现在可以免费下载了
  16. 硕士android毕业答辩ppt,硕士研究生毕业答辩ppt全攻略
  17. php中in array函数_php中in_array函数的用法
  18. EDKII Build Process:EDKII项目源码的配置、编译流程[3]
  19. 为啥扫描服务器端口无响应,服务器端口扫描工具
  20. 图片云存储服务商在阿里云和又拍云之间如何选择?

热门文章

  1. Android AnimationUtils (动画)的使用
  2. Android app 启动页尺寸大小 忘记了怎么办
  3. error: unbound prefix. Message{kind=ERROR, text=error: unbound prefix., sources=[E:\work\me\fragment
  4. 警告 '_'用作标识符, JavaSE8 之后的发行版中可能不支持使用'_'作为标识符
  5. Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现
  6. 面试题----中断的一些知识
  7. Redis 命令整理
  8. Go 学习笔记(40)— Go 标准库之 log
  9. 修改withdraw 方法
  10. 重新mysql-server