📄 globalfunc.cpp
字号:
#include "stdafx.h"
#include <math.h>
#include <complex>
using namespace std;
#define pai 3.1415926535898
void CustomModel(LPBYTE lpIn,LPBYTE lpOut,int imgWidth,int imgHeight,int *mask,int displmt)
{
int i,j,k,l;
int lineByte=imgWidth;//(imgWidth+3)/4*4;
double tmp,sum;
for(i=2;i<imgHeight-2;i++)
{
for(j=2;j<imgWidth-2;j++)
{
sum=0;
for(k=-2;k<3;k++)
{
for(l=-2;l<3;l++)
{
if(mask[5*(2+k)+l+2])
{
tmp=*(lpIn+(i+k)*lineByte+j+l)*mask[5*(2+k)+l+2];
sum+=tmp;
}
}
}
sum+=displmt;
if(sum>255)
sum=255;
else if(sum<0)
sum=0;
*(lpOut+i*lineByte+j)=(int)(sum+0.5);
}
}
}
void maskProcess(unsigned char *imgBuf, int width, int height, int biBitCount, int *mask)
{
int i, j, k;
unsigned char *buf=new unsigned char[width*height];
unsigned char *outBuf=new unsigned char[width*height];
for(k=0;k<biBitCount;k++){
for(i=0;i<width*height;i++)
buf[i]=*(imgBuf+i*k);
CustomModel(buf,outBuf,width,height, mask,0);
for(i=0;i<width*height;i++)
*(imgBuf+i*k)=outBuf[i];
}
delete []outBuf;
delete []buf;
}
void Roberts(LPBYTE lpIn,LPBYTE lpOut,int imgWidth,int imgHeight)
//边缘检测,Roberts算子
{
int i,j;
int linewidth=(imgWidth+3)/4*4;
int sum1,sum2,sum;
for(i=0;i<imgHeight-1;i++)
{
for(j=0;j<imgWidth-1;j++)
{
sum1=*(lpIn+i*linewidth+j)-*(lpIn+(i+1)*linewidth+j+1);
sum2=*(lpIn+i*linewidth+j+1)-*(lpIn+(i+1)*linewidth+j);
sum=(int)sqrt(sum1*sum1+sum2*sum2);
if(sum>255)
sum=255;
*(lpOut+i*linewidth+j)=sum;
}
}
}
void Kirch(LPBYTE lpIn,LPBYTE lpOut,int imgWidth,int imgHeight)
//边缘检测,Kirch算子
{
int i,j,k;
int linewidth=(imgWidth+3)/4*4;
int gray[8],sum1,sum2,sum,result;
for(i=1;i<imgHeight-1;i++)
{
for(j=1;j<imgWidth-1;j++)
{
gray[0]=*(lpIn+(i-1)*linewidth+j-1);
gray[1]=*(lpIn+(i-1)*linewidth+j);
gray[2]=*(lpIn+(i-1)*linewidth+j+1);
gray[3]=*(lpIn+i*linewidth+j+1);
gray[4]=*(lpIn+(i+1)*linewidth+j+1);
gray[5]=*(lpIn+(i+1)*linewidth+j);
gray[6]=*(lpIn+(i+1)*linewidth+j-1);
gray[7]=*(lpIn+i*linewidth+j-1);
result=0;
for(k=0;k<8;k++)
{
sum1=gray[k]+gray[(k+1)%8]+gray[(k+2)%8];
sum2=gray[(k+3)%8]+gray[(k+4)%8]+gray[(k+5)%8]+gray[(k+6)%8]+gray[(k+7)%8];
sum=5*sum1-3*sum2;
if(sum>result)
result=sum;
}
if(result>255)
result=255;
*(lpOut+i*linewidth+j)=result;
}
}
}
void GaussSmth(LPBYTE lpIn,LPBYTE lpOut,int imgWidth,int imgHeight,int size)
{
int i,j,k,l;
int linewidth=(imgWidth+3)/4*4;
int sum;
int dis=(size-1)/2,si=size*size;
for(i=dis;i<imgHeight-dis;i++)
{
for(j=dis;j<imgWidth-dis;j++)
{
sum=0;
for(k=-dis;k<=dis;k++)
{
for(l=-dis;l<=dis;l++)
{
sum+=*(lpIn+(i+k)*linewidth+j+l);
}
}
*(lpOut+i*linewidth+j)=sum/si;
}
}
}
void FakeColor1(LPBYTE lpIn,LPBYTE lpOut,int imgWidth,int imgHeight)
//灰度——>彩图,8位——>24位
{
int i,j;
int red[256],green[256],blue[256],gray;
int linewidthnew=(imgWidth*3+3)/4*4,
linewidth=(imgWidth+3)/4*4;
for(i=0;i<255;i++)//计算颜色映射表
{
if(i<64)
{
red[i]=0;
green[i]=(int)(((float)i)/64*255+0.5);
blue[i]=255;
}else if(i<128)
{
red[i]=0;
green[i]=255;
blue[i]=(int)(((float)(127-i))/64*255+0.5);
}
else if(i<192)
{
red[i]=(int)(((float)(i-127))/64*255+0.5);
green[i]=255;
blue[i]=0;
}else
{
red[i]=255;
green[i]=(int)(((float)(255-i))/64*255+0.5);
blue[i]=0;
}
}
for(i=0;i<imgHeight;i++)//重新赋值
{
for(j=0;j<linewidth;j++)
{
gray=*(lpIn+i*linewidth+j);
*(lpOut+i*linewidthnew+3*j)=blue[gray];
*(lpOut+i*linewidthnew+3*j+1)=green[gray];
*(lpOut+i*linewidthnew+3*j+2)=red[gray];
}
}
}
void FakeColor2(LPRGBQUAD lpPalette)
//灰度——>伪彩图,8位——>8位
{
int i;
for(i=0;i<255;i++)//修改调色板
{
/* if(i<64)
{
(lpPalette+i)->rgbRed=0;
(lpPalette+i)->rgbGreen=(int)(((float)i)/64*255);
(lpPalette+i)->rgbBlue=255;
}else if(i<128)
{
(lpPalette+i)->rgbRed=0;
(lpPalette+i)->rgbGreen=255;
(lpPalette+i)->rgbBlue=(int)(((float)(127-i))/64*255);
}
else if(i<192)
{
(lpPalette+i)->rgbRed=(int)(((float)(i-127))/64*255);
(lpPalette+i)->rgbGreen=255;
(lpPalette+i)->rgbBlue=0;
}else
{
(lpPalette+i)->rgbRed=255;
(lpPalette+i)->rgbGreen=(int)(((float)(255-i))/64*255);
(lpPalette+i)->rgbBlue=0;
}*/
if(i<128)//使用升余弦函数代替直线
{
(lpPalette+i)->rgbRed=0;
(lpPalette+i)->rgbGreen=(int)(255*(1+cos((2*(float)i/255-1)*pai))+0.5);
(lpPalette+i)->rgbBlue=(int)(255*(1+cos((2*(float)i/255)*pai))+0.5);
}else
{
(lpPalette+i)->rgbRed=(int)(255*(1+cos((2*(float)i/255)*pai))+0.5);
(lpPalette+i)->rgbGreen=(int)(255*(1+cos((2*(float)i/255-1)*pai))+0.5);
(lpPalette+i)->rgbBlue=0;
}
}
}
void DistortionSphere(LPBYTE lpIn,LPBYTE lpOut,int imgWidth,int imgHeight,int *data)
//球面变形
{
int i,j,k,count;
int radius=data[0],deep=data[1],x=data[2],y=data[3],clrNum=data[4];//输入参量
int lineByte=(imgWidth*clrNum+3)/4*4;
int dis0=radius*radius-deep*deep,dis,org;
unsigned char *lpTmp=new unsigned char [imgHeight*lineByte];
double radtmp,tmp,sita,arcLen;
double *dDis=new double [2*radius];
for(i=0;i<imgHeight;i++)//全图copy
{
for(j=0;j<lineByte;j++)
{
*(lpTmp+i*lineByte+j)=*(lpIn+i*lineByte+j);
}
}
//先做x方向的变形,再做y方向的变形
for(i=y-radius;i<y+radius;i++)
{
count=0;
if(i<0||i>=imgHeight)
{
continue;
}
for(j=x-radius;j<x+radius;j++)
{
dis=(i-y)*(i-y)+(j-x)*(j-x);
if(dis<=dis0) //如果像素在球冠底面内部
{
if(count==0)//记住初始位置
org=j;
count++;
}
}
if(count>2)
{
tmp=(double)count/2; //半弦长
radtmp=sqrt(tmp*tmp+deep*deep); //切面的半径
sita=acos(tmp/radtmp); //初始角
arcLen=2*(pai-2*sita); //*radtmp=弧长
for(k=0;k<count;k++)
{
if(k+org>=0&&k+org<imgWidth)
{
dDis[k]=2*(acos((tmp-k)/radtmp)-sita)*count/arcLen+0.5;
//计算映射表
if(clrNum==1)
{
*(lpTmp+i*lineByte+org+k)=*(lpIn+i*lineByte+org+
(int)dDis[k]);
}else
{
*(lpTmp+i*lineByte+3*(org+k))=*(lpIn+i*lineByte+
3*(org+(int)dDis[k]));
*(lpTmp+i*lineByte+3*(org+k)+1)=*(lpIn+i*lineByte+
3*(org+(int)dDis[k])+1);
*(lpTmp+i*lineByte+3*(org+k)+2)=*(lpIn+i*lineByte+
3*(org+(int)dDis[k])+2);
}
//修改相应的像素值
}
}
}
}
//x方向的变形完成,下面做y方向的变形
for(i=0;i<imgHeight;i++)//全图copy
{
for(j=0;j<lineByte;j++)
{
*(lpOut+i*lineByte+j)=*(lpTmp+i*lineByte+j);
}
}
for(i=x-radius;i<x+radius;i++)
{
count=0;
if(i<0||i>=imgHeight)
{
continue;
}
for(j=y-radius;j<y+radius;j++)
{
dis=(i-x)*(i-x)+(j-y)*(j-y);
if(dis<=dis0) //如果像素在球冠底面内部
{
if(count==0)//记住初始位置
org=j;
count++;
}
}
if(count>2)
{
tmp=(double)count/2; //半弦长
radtmp=sqrt(tmp*tmp+deep*deep); //切面的半径
sita=acos(tmp/radtmp); //初始角
arcLen=2*(pai-2*sita); //*radtmp=弧长
for(k=0;k<count;k++)
{
if(k+org>=0&&k+org<imgHeight)
{
dDis[k]=2*(acos((tmp-k)/radtmp)-sita)*count/arcLen+0.5;
//计算映射表
if(clrNum==1)
{
*(lpOut+(org+k)*lineByte+i)=*(lpTmp+
(org+(int)dDis[k])*lineByte+i);
}else
{
*(lpOut+(org+k)*lineByte+3*i)=*(lpTmp+
(org+(int)dDis[k])*lineByte+3*i);
*(lpOut+(org+k)*lineByte+3*i+1)=*(lpTmp+
(org+(int)dDis[k])*lineByte+3*i+1);
*(lpOut+(org+k)*lineByte+3*i+2)=*(lpTmp+
(org+(int)dDis[k])*lineByte+3*i+2);
}
//修改相应的像素值
}
}
}
}
}
void RestoreSphere(LPBYTE lpIn,LPBYTE lpOut,int imgWidth,int imgHeight,int *data)
//恢复球面变形的图像
{
int i,j,k,count;
int radius=data[0],deep=data[1],x=data[2],y=data[3],clrNum=data[4];//输入参量
int lineByte=(imgWidth*clrNum+3)/4*4;
int dis0=radius*radius-deep*deep,dis,org;
unsigned char *lpTmp=new unsigned char[imgHeight*lineByte];
double radtmp,tmp,sita,bowLen,mAngle,judge,delta;
double *dDis=new double [2*radius];
//先做y方向的变形,再做x方向的变形
for(i=0;i<imgHeight;i++)//全图copy
{
for(j=0;j<lineByte;j++)
{
*(lpTmp+i*lineByte+j)=*(lpIn+i*lineByte+j);
}
}
for(i=x-radius;i<x+radius;i++)
{
count=0;
if(i<0||i>=imgHeight)
{
continue;
}
tmp=(i-x)*(i-x);
for(j=y-radius;j<y+radius;j++)
{
dis=(int)tmp+(j-y)*(j-y);
if(dis<=dis0) //如果像素在球冠底面内部
{
if(count==0)//记住初始位置
org=j;
count++;
}
}
radtmp=sqrt(radius*radius-tmp); //切面的半径
sita=asin((double)deep/radtmp); //初始角
delta=(1-count/radtmp/2); //初始位置的偏移量
mAngle=(pai-2*sita)/((double)count-1); //等分的角度
bowLen=2*cos(sita); //*radtmp=弦长
if(count>2)
{
for(k=0;k<count;k++)
{
if(k+org>=0&&k+org<imgHeight)
{tmp=sin((k*mAngle+sita)/2);
judge=2*tmp*tmp-delta;
dDis[k]=judge/bowLen*count+0.5;
//计算映射表
if(clrNum==1)
{
if(org+dDis[k]<0||org+dDis[k]>imgHeight)
*(lpTmp+(org+k)*lineByte+i)=0;
else
*(lpTmp+(org+k)*lineByte+i)=*(lpIn+
(org+(int)dDis[k])*lineByte+i);
}else
{
if(org+dDis[k]<0||org+dDis[k]>imgHeight)
{
*(lpTmp+(org+k)*lineByte+3*i)=0;
*(lpTmp+(org+k)*lineByte+3*i+1)=0;
*(lpTmp+(org+k)*lineByte+3*i+2)=0;
}else
{
*(lpTmp+(org+k)*lineByte+3*i)=*(lpIn+
(org+(int)dDis[k])*lineByte+3*i);
*(lpTmp+(org+k)*lineByte+3*i+1)=*(lpIn+
(org+(int)dDis[k])*lineByte+3*i+1);
*(lpTmp+(org+k)*lineByte+3*i+2)=*(lpIn+
(org+(int)dDis[k])*lineByte+3*i+2);
}
}
//修改相应的像素值
}
}
}
}
//上面已经做好了y方向的变形,下面做x方向的变形
for(i=0;i<imgHeight;i++)//全图copy
{
for(j=0;j<lineByte;j++)
{
*(lpOut+i*lineByte+j)=*(lpTmp+i*lineByte+j);
}
}
for(i=y-radius;i<y+radius;i++)
{
count=0;
if(i<0||i>=imgHeight)
{
continue;
}
tmp=(i-y)*(i-y);
for(j=x-radius;j<x+radius;j++)
{
dis=(int)tmp+(j-x)*(j-x);
if(dis<=dis0) //如果像素在球冠底面内部
{
if(count==0)//记住初始位置
org=j;
count++;
}
}
radtmp=sqrt(radius*radius-tmp); //切面的半径
sita=asin((double)deep/radtmp); //初始角
delta=(1-count/radtmp/2); //初始位置的偏移量
mAngle=(pai-2*sita)/((double)count-1); //等分的角度
bowLen=2*cos(sita); //*radtmp=弦长
if(count>2)
{
for(k=0;k<count;k++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -