📄 graytrans.cpp
字号:
m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);
//若有颜色表,输入图像的颜色表与输出图像颜色表相同
if(m_nColorTableLengthOut!=0){
m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
memcpy(m_lpColorTableOut,m_lpColorTable,
sizeof(RGBQUAD)*m_nColorTableLengthOut);
}
//输出图像的宽高,与输入图像相等
m_imgWidthOut=m_imgWidth;
m_imgHeightOut=m_imgHeight;
//输出图像每行像素所占的字节数
int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight];
if(m_nBitCount==8)//如果是灰度图像,则调用单通道数据线性拉伸函数
LinearStrechForSnglChannel(m_pImgData, m_pImgDataOut,
m_imgWidth, m_imgHeight,point);
else{
//若彩色图像,则把每个通道的数据进行分离,并线性拉伸,然后再合成为彩色图像
//单通道数据每行像素所占的字节数
int lineByteGray=(m_imgWidth+3)/4*4;
//临时缓冲区,存放单通道数据
unsigned char *bufIn=new unsigned char[m_imgHeight*lineByteGray];
//临时缓冲区,单通道数据拉伸的结果
unsigned char *bufOut=new unsigned char[m_imgHeight*lineByteGray];
//循环变量,图像坐标
int i, j;
//循环变量,遍历彩色图像的三个通道
int k;
for(k=0;k<3;k++){
//将每个通道数据提取出来,存入bufIn缓冲区
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth;j++)
bufIn[i*lineByteGray+j]=*(m_pImgData+i*lineByteOut+j*3+k);
}
//对bufIn缓冲区中的数据进行拉伸,拉伸结果存入bufOut中
LinearStrechForSnglChannel(bufIn,bufOut,m_imgWidth,m_imgHeight,point);
//将单通道拉伸的结果存入输出图像m_pImgDataOut对应通道中
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth;j++)
*(m_pImgDataOut+i*lineByteOut+j*3+k)=bufOut[i*lineByteGray+j];
}
}
//释放缓冲区
delete []bufIn;
delete []bufOut;
}
}
/***********************************************************************
* 函数名称:
* LinearStrechForSnglChannel()
*
*函数参数:
* unsigned char *pImgDataIn -待拉伸的位图数据指针
* unsigned char *pImgDataOut -拉伸后位图数据指针
* int imgWidth -位图宽,像素为单位
* int imgHeight -位图高,像素为单位
* CPoint point[2] -分段线性的两个转折点坐标
*
*返回值:
* 无
*
*说明:给定一个通道的数据,以及两个转折点坐标,做分段线性拉伸, 将结果
* 存入pImgDataOut所指向的缓冲区。
***********************************************************************/
void GrayTrans::LinearStrechForSnglChannel(unsigned char *pImgDataIn,
unsigned char *pImgDataOut, int imgWidth,int imgHeight,CPoint point[2])
{
//循环变量,图像坐标
int i,j;
//每行像素的字节数,单通道图像
int lineByte=(imgWidth+3)/4*4;
//(x1,y1)和(x2,y2)为两个分段点的坐标
double x1=point[0].x,y1=point[0].y,x2=point[1].x, y2=point[1].y;
//三个分段的直线斜率
double slop1=y1/x1,slop2=(y2-y1)/(x2-x1),slop3=(255-y2)/(255-x2);
//三个直线坐标的斜率
double dis1=0,dis2=y1-slop2*x1,dis3=y2-slop3*x2;
//映射表
int map[256];
//根据三个分段,对输入图像每个灰度级计算映射表
for(i=0;i<256;i++)
{
if(i<x1)
map[i]=(int)(slop1*i+dis1+0.5);
else if(i<x2)
map[i]=(int)(slop2*i+dis2+0.5);
else
map[i]=(int)(slop3*i+dis3+0.5);
}
//临时变量
int tmp;
//对每个像素,根据输入像素灰度级查找映射表,并为输出像素赋值
for(i=0;i<imgHeight;i++)
{
for(j=0;j<lineByte;j++)
{
//输入图像(i,j)像素的灰度级
tmp=*(pImgDataIn+i*lineByte+j);
//根据映射表为输出图像赋值
*(pImgDataOut+i*lineByte+j)=map[tmp];
}
}
}
/***********************************************************************
* 函数名称:
* DuiShuStrechForSnglChannel()
*
*函数参数:
* unsigned char *pImgDataIn -待拉伸的位图数据指针
* unsigned char *pImgDataOut -拉伸后位图数据指针
* int imgWidth -位图宽,像素为单位
* int imgHeight -位图高,像素为单位
* float a -对数函数非线性变换参数
* float b -对数函数非线性变换参数
* float c -对数函数非线性变换参数
*
*返回值:
* 无
*
*说明:给定一个通道的数据,及a、b、c三个对数拉伸所需要的参数,进行非线性
* 拉伸, 将结果存入pImgDataOut所指向的缓冲区。
***********************************************************************/
void GrayTrans::DuiShuStrechForSnglChannel(unsigned char *pImgDataIn,
unsigned char *pImgDataOut,int imgWidth,int imgHeight,
float a, float b, float c)
{
//循环变量,图像坐标
int i,j;
//每行像素的字节数,单通道图像
int lineByte=(imgWidth+3)/4*4;
//临时变量
float tmp1, tmp2, t;
//对数函数非线性变换
for(i=0;i<imgHeight;i++)
{
for(j=0;j<lineByte;j++)
{
//根据输入点像素灰度值,计算输出点像素灰度值
tmp1=log(*(pImgDataIn+i*lineByte+j)+1.0)/log(2.0);
tmp2=b*log(c)/log(2.0);
t=a+tmp1/tmp2;
if(t>255)
t=255;
else if(t<0)
t=0;
*(pImgDataOut+i*lineByte+j)=t;
}
}
}
/***********************************************************************
* 函数名称:
* DuiShuStrech()
*
*函数参数:
* float a -对数函数非线性变换参数
* float b -对数函数非线性变换参数
* float c -对数函数非线性变换参数
*
*返回值:
* 无
*
*说明:对数函数非线性拉伸,给定三个参数,对m_pImgData所指向缓冲区中的灰度
* 或彩色图像进行对数非线性拉伸,为m_pImgDataOut申请内存,存放拉伸结果。
***********************************************************************/
void GrayTrans::DuiShuStrech(float a, float b, float c)
{
//释放旧的输出图像缓冲区
if(m_pImgDataOut!=NULL){
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
if(m_lpColorTableOut!=NULL){
delete []m_lpColorTableOut;
m_lpColorTableOut=NULL;
}
//输出图像每像素位数与输入图像相同
m_nBitCountOut=m_nBitCount;
//计算颜色表长度
m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);
//若有颜色表,输入图像的颜色表与输出图像颜色表相同
if(m_nColorTableLengthOut!=0){
m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
memcpy(m_lpColorTableOut,m_lpColorTable,
sizeof(RGBQUAD)*m_nColorTableLengthOut);
}
//输出图像的宽高,与输入图像相等
m_imgWidthOut=m_imgWidth;
m_imgHeightOut=m_imgHeight;
//输出图像每行像素所占的字节数
int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight];
if(m_nBitCount==8)//如果是灰度图像,则调用单通道数据对数拉伸函数
DuiShuStrechForSnglChannel(m_pImgData, m_pImgDataOut,
m_imgWidth, m_imgHeight,a,b,c);
else{
//若彩色图像,则把每个通道的数据进行分离,并非线性拉伸,然后再合成为彩色图像
//单通道数据每行像素所占的字节数
int lineByteGray=(m_imgWidth+3)/4*4;
//临时缓冲区,存放单通道数据
unsigned char *bufIn=new unsigned char[m_imgHeight*lineByteGray];
//临时缓冲区,单通道数据拉伸的结果
unsigned char *bufOut=new unsigned char[m_imgHeight*lineByteGray];
//循环变量,图像坐标
int i, j;
//循环变量,遍历彩色图像的三个通道
int k;
for(k=0;k<3;k++){
//将每个通道数据提取出来,存入bufIn缓冲区
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth;j++)
bufIn[i*lineByteGray+j]=*(m_pImgData+i*lineByteOut+j*3+k);
}
//对bufIn缓冲区中的数据进行拉伸,拉伸结果存入bufOut中
DuiShuStrechForSnglChannel(bufIn,bufOut,m_imgWidth,m_imgHeight,a,b,c);
//将单通道拉伸的结果存入输出图像m_pImgDataOut对应通道中
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth;j++)
*(m_pImgDataOut+i*lineByteOut+j*3+k)=bufOut[i*lineByteGray+j];
}
}
//释放缓冲区
delete []bufIn;
delete []bufOut;
}
}
/***********************************************************************
* 函数名称:
* ZhiShuStrechForSnglChannel()
*
*函数参数:
* unsigned char *pImgDataIn -待拉伸的位图数据指针
* unsigned char *pImgDataOut -拉伸后位图数据指针
* int imgWidth -位图宽,像素为单位
* int imgHeight -位图高,像素为单位
* float a -指数函数非线性变换参数
* float b -指数函数非线性变换参数
* float c -指数函数非线性变换参数
*
*返回值:
* 无
*
*说明:给定一个通道的数据,及a、b、c三个指数拉伸所需要的参数,进行非线性
* 拉伸, 将结果存入pImgDataOut所指向的缓冲区。
***********************************************************************/
void GrayTrans::ZhiShuStrechForSnglChannel(unsigned char *pImgDataIn,
unsigned char *pImgDataOut,int imgWidth,int imgHeight,
float a, float b, float c)
{
//循环变量,图像坐标
int i,j;
//每行像素的字节数,单通道图像
int lineByte=(imgWidth+3)/4*4;
//临时变量
float t;
//对数函数非线性变换
for(i=0;i<imgHeight;i++)
{
for(j=0;j<lineByte;j++)
{
//根据输入点像素灰度值,计算输出点像素灰度值
t=c*(*(pImgDataIn+i*lineByte+j)-a);
t=pow(b,t)-1;
if(t>255)
t=255;
else if(t<0)
t=0;
*(pImgDataOut+i*lineByte+j)=t;
}
}
}
/***********************************************************************
* 函数名称:
* ZhiShuStrech()
*
*函数参数:
* float a -指数函数非线性变换参数
* float b -指数函数非线性变换参数
* float c -指数函数非线性变换参数
*
*返回值:
* 无
*
*说明:指数函数非线性拉伸分,给定指数拉伸参数,对m_pImgData所指向缓冲区中的灰度
* 或彩色图像进行指数非线性拉伸,为m_pImgDataOut申请内存,存放拉伸结果。
***********************************************************************/
void GrayTrans::ZhiShuStrech(float a, float b, float c)
{
//释放旧的输出图像缓冲区
if(m_pImgDataOut!=NULL){
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
if(m_lpColorTableOut!=NULL){
delete []m_lpColorTableOut;
m_lpColorTableOut=NULL;
}
//输出图像每像素位数与输入图像相同
m_nBitCountOut=m_nBitCount;
//计算颜色表长度
m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);
//若有颜色表,输入图像的颜色表与输出图像颜色表相同
if(m_nColorTableLengthOut!=0){
m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
memcpy(m_lpColorTableOut,m_lpColorTable,
sizeof(RGBQUAD)*m_nColorTableLengthOut);
}
//输出图像的宽高,与输入图像相等
m_imgWidthOut=m_imgWidth;
m_imgHeightOut=m_imgHeight;
//输出图像每行像素所占的字节数
int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight];
if(m_nBitCount==8)//如果是灰度图像,则调用单通道数据指数拉伸函数
ZhiShuStrechForSnglChannel(m_pImgData, m_pImgDataOut,
m_imgWidth, m_imgHeight,a,b,c);
else{
//若彩色图像,则把每个通道的数据进行分离,并非线性拉伸,然后再合成为彩色图像
//单通道数据每行像素所占的字节数
int lineByteGray=(m_imgWidth+3)/4*4;
//临时缓冲区,存放单通道数据
unsigned char *bufIn=new unsigned char[m_imgHeight*lineByteGray];
//临时缓冲区,单通道数据拉伸的结果
unsigned char *bufOut=new unsigned char[m_imgHeight*lineByteGray];
//循环变量,图像坐标
int i, j;
//循环变量,遍历彩色图像的三个通道
int k;
for(k=0;k<3;k++){
//将每个通道数据提取出来,存入bufIn缓冲区
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth;j++)
bufIn[i*lineByteGray+j]=*(m_pImgData+i*lineByteOut+j*3+k);
}
//对bufIn缓冲区中的数据进行拉伸,拉伸结果存入bufOut中
ZhiShuStrechForSnglChannel(bufIn,bufOut,m_imgWidth,m_imgHeight,a,b,c);
//将单通道拉伸的结果存入输出图像m_pImgDataOut对应通道中
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth;j++)
*(m_pImgDataOut+i*lineByteOut+j*3+k)=bufOut[i*lineByteGray+j];
}
}
//释放缓冲区
delete []bufIn;
delete []bufOut;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -