⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 globalfunc.cpp

📁 visual c++图像处理经典算法示例程序 把功能都集中在一个程序中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -