?? imageprocessing.cpp
字號:
#include "stdafx.h"
#include <windows.h>
#include <math.h>
#include <malloc.h>
#include "resource.h"
void HorzMirror(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int x,y;
int nByteWidth=nWidth*3;
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
for(y=0;y<nHeight;y++)
{
for(x=0;x<nWidth;x++)
{
lpOutput[x*3+y*nByteWidth]=lpInput[(nWidth-1-x)*3+y*nByteWidth];
lpOutput[x*3+1+y*nByteWidth]=lpInput[(nWidth-1-x)*3+1+y*nByteWidth];
lpOutput[x*3+2+y*nByteWidth]=lpInput[(nWidth-1-x)*3+2+y*nByteWidth];
}
Progress(y);
}
}
void VertMirror(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int x,y;
int nByteWidth=nWidth*3;
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
for(y=0;y<nHeight;y++)
{
for(x=0;x<nByteWidth;x++)
{
lpOutput[x+y*nByteWidth]=lpInput[x+(nHeight-y-1)*nByteWidth];
}
Progress(y);
}
}
void CornerMirror(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int x,y;
int nByteWidth=nWidth*3;
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
for(y=0;y<nHeight;y++)
{
for(x=0;x<nWidth;x++)
{
lpOutput[x*3+y*nByteWidth]=lpInput[(nWidth-1-x)*3+(nHeight-y-1)*nByteWidth];
lpOutput[x*3+1+y*nByteWidth]=lpInput[(nWidth-1-x)*3+1+(nHeight-y-1)*nByteWidth];
lpOutput[x*3+2+y*nByteWidth]=lpInput[(nWidth-1-x)*3+2+(nHeight-y-1)*nByteWidth];
}
Progress(y);
}
}
#define Point(x,y) lpPoints[(x)+(y)*nWidth]
#define Point1(x,y) lpPoints1[(x)+(y)*nWidth]
//get the pixels from lbBits to lpPoints
BYTE GetPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints)
{
int Gmax=0;
int Gmin=0;
int x,y,p;
int nByteWidth=nWidth*3;
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
for(y=0;y<nHeight;y++)
{
for(x=0;x<nWidth;x++)
{
p=x*3+y*nByteWidth;
lpPoints[x+y*nWidth]=(BYTE)(0.299*(float)lpBits[p+2]+0.587*(float)lpBits[p+1]+0.114*(float)lpBits[p]+0.1);
if(lpPoints[x+y*nWidth]>Gmax)
Gmax=lpPoints[x+y*nWidth];
if(lpPoints[x+y*nWidth]<Gmin)
Gmin=lpPoints[x+y*nWidth];
}
}
return Gmax-2*(Gmax-Gmin)/3;
}
void PutPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints)
{
int nByteWidth=nWidth*3;
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
int x,y,p,p1;
for(y=0;y<nHeight;y++)
{
for(x=0;x<nWidth;x++)
{
p=x*3+y*nByteWidth;
p1=x+y*nWidth;
lpBits[p]=lpPoints[p1];
lpBits[p+1]=lpPoints[p1];
lpBits[p+2]=lpPoints[p1];
}
}
}
void HistogramEq1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput)
{
int x,y;
BYTE *lpPoints=new BYTE[nWidth*nHeight];
GetPoints(nWidth,nHeight,lpInput,lpPoints);
int r[256],s[256];
ZeroMemory(r,1024);
ZeroMemory(s,1024);
for(y=0;y<nHeight;y++){
for(x=0;x<nWidth;x++){
r[Point(x,y)]++;
}
}
s[0]=r[0];
for(y=1;y<256;y++)
{
s[y]=s[y-1];
s[y]+=r[y];
}
for(y=0;y<nHeight;y++){
for(x=0;x<nWidth;x++){
Point(x,y)=s[Point(x,y)]*255/nWidth/nHeight;
}
}
PutPoints(nWidth,nHeight,lpOutput,lpPoints);
delete lpPoints;
}
//3x3中值濾波
void Med1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int x,y;
int nByteWidth=nWidth*3;
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
BYTE p[9],s;
int i,j;
for(y=1;y<nHeight-1;y++)
{
for(x=3;x<nWidth*3-3;x++)
{
p[0]=lpInput[x-3+(y-1)*nByteWidth];
p[1]=lpInput[x+(y-1)*nByteWidth];
p[2]=lpInput[x+3+(y-1)*nByteWidth];
p[3]=lpInput[x-3+y*nByteWidth];
p[4]=lpInput[x+y*nByteWidth];
p[5]=lpInput[x+3+y*nByteWidth];
p[6]=lpInput[x-3+(y+1)*nByteWidth];
p[7]=lpInput[x+(y+1)*nByteWidth];
p[8]=lpInput[x+3+(y+1)*nByteWidth];
for(j=0;j<5;j++)
{
for(i=j+1;i<9;i++)
{
if (p[j]>p[i])
{
s=p[j];
p[j]=p[i];
p[i]=s;
}
}
}
lpOutput[x+y*nByteWidth]=p[4];
}
Progress(y);
}
}
void Mean1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int x,y,x1,y1,p;
// BYTE *lpPoints=new BYTE[nWidth*nHeight];
// GetPoints(nWidth,nHeight,lpInput,lpPoints);
int sr,sg,sb;
int nByteWidth=nWidth*3;
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
for(y=1;y<nHeight-1;y++)
{
for(x=1;x<nWidth-1;x++)
{
p=x*3+y*nByteWidth;
sb=0;
sg=0;
sr=0;
for(y1=-1;y1<=1;y1++)
for(x1=-1;x1<=1;x1++)
{
sb+=lpInput[(y+y1)*nByteWidth+(x+x1)*3];
sg+=lpInput[(y+y1)*nByteWidth+(x+x1)*3+1];
sr+=lpInput[(y+y1)*nByteWidth+(x+x1)*3+2];
}
lpOutput[p+2]=sr/9;
lpOutput[p+1]=sg/9;
lpOutput[p]=sb/9;
}
Progress(y);
}
// PutPoints(nWidth,nHeight,lpOutput,lpPoints);
// delete lpPoints;
}
#define pi (double)3.14159265359
/*復數定義*/
typedef struct
{
double re;
double im;
}COMPLEX;
/*復數加運算*/
COMPLEX Add(COMPLEX c1, COMPLEX c2)
{
COMPLEX c;
c.re=c1.re+c2.re;
c.im=c1.im+c2.im;
return c;
}
/*復數減運算*/
COMPLEX Sub(COMPLEX c1, COMPLEX c2)
{
COMPLEX c;
c.re=c1.re-c2.re;
c.im=c1.im-c2.im;
return c;
}
/*復數乘運算*/
COMPLEX Mul(COMPLEX c1, COMPLEX c2)
{
COMPLEX c;
c.re=c1.re*c2.re-c1.im*c2.im;
c.im=c1.re*c2.im+c2.re*c1.im;
return c;
}
/*快速付里哀變換
TD為時域值,FD為頻域值,power為2的冪數*/
void FFT(COMPLEX * TD, COMPLEX * FD, int power)
{
int count;
int i,j,k,bfsize,p;
double angle;
COMPLEX *W,*X1,*X2,*X;
/*計算付里哀變換點數*/
count=1<<power;
/*分配運算所需存儲器*/
W=(COMPLEX *)malloc(sizeof(COMPLEX)*count/2);
X1=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
X2=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
/*計算加權系數*/
for(i=0;i<count/2;i++)
{
angle=-i*pi*2/count;
W[i].re=cos(angle);
W[i].im=sin(angle);
}
/*將時域點寫入存儲器*/
memcpy(X1,TD,sizeof(COMPLEX)*count);
/*蝶形運算*/
for(k=0;k<power;k++)
{
for(j=0;j<1<<k;j++)
{
bfsize=1<<(power-k);
for(i=0;i<bfsize/2;i++)
{
p=j*bfsize;
X2[i+p]=Add(X1[i+p],X1[i+p+bfsize/2]);
X2[i+p+bfsize/2]=Mul(Sub(X1[i+p],X1[i+p+bfsize/2]),W[i*(1<<k)]);
}
}
X=X1;
X1=X2;
X2=X;
}
/*重新排序*/
for(j=0;j<count;j++)
{
p=0;
for(i=0;i<power;i++)
{
if (j&(1<<i)) p+=1<<(power-i-1);
}
FD[j]=X1[p];
}
/*釋放存儲器*/
free(W);
free(X1);
free(X2);
}
/*快速離散余弦變換,利用快速付里哀變換
f為時域值,F為變換域值,power為2的冪數*/
void DCT(double *f, double *F, int power)
{
int i,count;
COMPLEX *X;
double s;
/*計算離散余弦變換點數*/
count=1<<power;
/*分配運算所需存儲器*/
X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
/*延拓*/
memset(X,0,sizeof(COMPLEX)*count*2);
/*將時域點寫入存儲器*/
for(i=0;i<count;i++)
{
X[i].re=f[i];
}
/*調用快速付里哀變換*/
FFT(X,X,power+1);
/*調整系數*/
s=1/sqrt((double)count);
F[0]=X[0].re*s;
s*=sqrt((double)2);
for(i=1;i<count;i++)
{
F[i]=(X[i].re*cos(i*pi/(count*2))+X[i].im*sin(i*pi/(count*2)))*s;
}
/*釋放存儲器*/
free(X);
}
/*快速沃爾什-哈達瑪變換
f為時域值,F為變換域值,power為2的冪數*/
void WALh(double *f, double *W, int power)
{
int count;
int i,j,k,bfsize,p;
double *X1,*X2,*X;
/*計算快速沃爾什變換點數*/
count=1<<power;
/*分配運算所需存儲器*/
X1=(double *)malloc(sizeof(double)*count);
X2=(double *)malloc(sizeof(double)*count);
/*將時域點寫入存儲器*/
memcpy(X1,f,sizeof(double)*count);
/*蝶形運算*/
for(k=0;k<power;k++)
{
for(j=0;j<1<<k;j++)
{
bfsize=1<<(power-k);
for(i=0;i<bfsize/2;i++)
{
p=j*bfsize;
X2[i+p]=X1[i+p]+X1[i+p+bfsize/2];
X2[i+p+bfsize/2]=X1[i+p]-X1[i+p+bfsize/2];
}
}
X=X1;
X1=X2;
X2=X;
}
/*調整系數*/
// for(i=0;i<count;i++)
// {
// W[i]=X1[i]/count;
// }
for(j=0;j<count;j++)
{
p=0;
for(i=0;i<power;i++)
{
if (j&(1<<i)) p+=1<<(power-i-1);
}
W[j]=X1[p]/count;
}
/*釋放存儲器*/
free(X1);
free(X2);
}
void Fourier1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int w=1,h=1,wp=0,hp=0;
while(w*2<=nWidth)
{
w*=2;
wp++;
}
while(h*2<=nHeight)
{
h*=2;
hp++;
}
int x,y;
BYTE *lpPoints=new BYTE[nWidth*nHeight];
GetPoints(nWidth,nHeight,lpInput,lpPoints);
COMPLEX *TD=new COMPLEX[w*h];
COMPLEX *FD=new COMPLEX[w*h];
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
TD[x+w*y].re=Point(x,y);
TD[x+w*y].im=0;
}
}
for(y=0;y<h;y++)
{
FFT(&TD[w*y],&FD[w*y],wp);
Progress(y*nHeight/2/h);
}
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
TD[y+h*x]=FD[x+w*y];
// TD[x+w*y]=FD[x*h+y];
}
}
for(x=0;x<w;x++)
{
FFT(&TD[x*h],&FD[x*h],hp);
Progress(x*nHeight/2/w+nHeight/2);
}
memset(lpPoints,0,nWidth*nHeight);
double m;
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
m=sqrt(FD[x*h+y].re*FD[x*h+y].re+FD[x*h+y].im*FD[x*h+y].im)/100;
if (m>255) m=255;
Point((x<w/2?x+w/2:x-w/2),nHeight-1-(y<h/2?y+h/2:y-h/2))=(BYTE)(m);
}
}
delete TD;
delete FD;
PutPoints(nWidth,nHeight,lpOutput,lpPoints);
delete lpPoints;
}
void Walsh1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int w=1,h=1,wp=0,hp=0;
while(w*2<=nWidth)
{
w*=2;
wp++;
}
while(h*2<=nHeight)
{
h*=2;
hp++;
}
int x,y;
BYTE *lpPoints=new BYTE[nWidth*nHeight];
GetPoints(nWidth,nHeight,lpInput,lpPoints);
double *f=new double[w*h];
double *W=new double[w*h];
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
f[x+y*w]=Point(x,y);
}
}
for(y=0;y<h;y++)
{
WALh(f+w*y,W+w*y,wp);
Progress(y*nHeight/2/h);
}
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
f[x*h+y]=W[x+w*y];
}
}
for(x=0;x<w;x++)
{
WALh(f+x*h,W+x*h,hp);
Progress(x*nHeight/2/w+nHeight/2);
}
double a;
memset(lpPoints,0,nWidth*nHeight);
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
a=fabs(W[x*h+y]*1000);
if (a>255) a=255;
Point(x,nHeight-y-1)=(BYTE)a;
}
}
delete f;
delete W;
PutPoints(nWidth,nHeight,lpOutput,lpPoints);
delete lpPoints;
}
void Dct1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
{
int w=1,h=1,wp=0,hp=0;
while(w*2<=nWidth)
{
w*=2;
wp++;
}
while(h*2<=nHeight)
{
h*=2;
hp++;
}
int x,y;
BYTE *lpPoints=new BYTE[nWidth*nHeight];
GetPoints(nWidth,nHeight,lpInput,lpPoints);
double *f=new double[w*h];
double *W=new double[w*h];
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
f[x+y*w]=Point(x,y);
}
}
for(y=0;y<h;y++)
{
DCT(&f[w*y],&W[w*y],wp);
Progress(y*nHeight/2/h);
}
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
f[x*h+y]=W[x+w*y];
}
}
for(x=0;x<w;x++)
{
DCT(&f[x*h],&W[x*h],hp);
Progress(x*nHeight/2/w+nHeight/2);
}
double a;
memset(lpPoints,0,nWidth*nHeight);
for(y=0;y<h;y++)
{
for(x=0;x<w;x++)
{
a=fabs(W[x*h+y]);
if (a>255) a=255;
Point(x,nHeight-y-1)=(BYTE)(a);
}
}
delete f;
delete W;
PutPoints(nWidth,nHeight,lpOutput,lpPoints);
delete lpPoints;
}
int Conv2(int nWidth,int nHeight,BYTE *lpOutput,BYTE *lpInput,double mask[],int windowX,int windowY);
int Laplacian(int nWidth,int nHeight,BYTE *lpOutput,double *lpInput);
int Zerocross(int nWidth,int nHeight,BYTE *lpOutput,double *lpInput,double thresh);
int LoG(int nWidth,int nHeight,BYTE *lpOutput,BYTE *lpInput,double thresh,double sigma);
#define In(x,y) lpInput[(x)+(y)*nWidth]
#define Out(x,y) lpOutput[(x)+(y)*nWidth]
#define Mediate(x,y) lpMediate[(x)+(y)*nWidth]
#include "NumberDlg.h"
double GetNumber(const char *prompt,double number,double max)
{
CNumberDlg dlg;
dlg.m_Prompt=prompt;
dlg.m_Number=number;
dlg.DoModal();
if (dlg.m_Number>max) dlg.m_Number=max;
return dlg.m_Number;
return 1;
}
void Gauss1(int nWidth,int nHeight,BYTE *lpIn,BYTE *lpOut,void (* Progress)(int Pos))
{
double sigma=GetNumber("輸入高斯模糊半徑:",1,10);
int x,y,xx,xk,yk;
BYTE *lpInput=new BYTE[nWidth*nHeight];
BYTE *lpOutput=new BYTE[nWidth*nHeight];
GetPoints(nWidth,nHeight,lpIn,lpInput);
int radius,window; //window of the converlutin kernel(window=2*radius+1)
double dev_inv=0.5/(sigma*sigma); //1/(2*sigma^2)
radius = (int)ceil(3*sigma);
window = radius*2+1;
//fast algorithm
memcpy(lpOutput,lpInput,nWidth*nHeight);
double* lpMediate=new double[nWidth*nHeight];
double* mask=new double[window];
double sum=0;
double temp;
double weight;//sum of weight of mask at edge of the image
//generate mask
for(x=0;x<radius;x++)
{
xx=(x-radius)*(x-radius);
mask[x]=exp(-xx*dev_inv);
mask[window-1-x]=mask[x];
sum+=2*mask[x];
}
mask[radius]=1;
sum+=1;
for(x=0;x<window;x++)
{
mask[x]/=sum;
}
//row process
for(y=0;y<nHeight;y++)
{
for(x=radius;x<nWidth-radius;x++)
{
temp=0;
for(xk=-radius;xk<radius+1;xk++)
temp+=In(x+xk,y)*mask[xk+radius];
Mediate(x,y)=temp;
}
for(x=0;x<radius;x++)
{
temp=0;
weight=0;
for(xk=-x;xk<radius+1;xk++)
{
temp+=In(x+xk,y)*mask[xk+radius];
weight+=mask[xk+radius];
}
Mediate(x,y)=temp/weight;
}
for(x=nWidth-radius;x<nWidth;x++)
{
temp=0;
weight=0;
for(xk=-radius;xk<nWidth-x;xk++)
{
temp+=In(x+xk,y)*mask[xk+radius];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -