简易photoshop代码数字图像处理实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一.一个简单的“photoshop”软件
二.设计目的:
数字图像处理,就是用数字计算机及其他有关数字技术,对图像进行处理,以达到预期的目的。

随着计算机的发展,图像处理技术在许多领域得到了广泛应用,数字图像处理已成为电子信息、通信、计算机、自动化、信号处理等专业的重要课程。

数字图像处理课程设计是在完成数字图像处理的相关理论的学习后,进行的综合性训练课程,其目的主要包括:
1、使学生进一步巩固数字图像处理的基本概念、理论、分析方法和实现方
法;
2、增强学生应用VC++编写数字图像处理的应用程序及分析、解决实际问
题的能力;
3、尝试将所学的内容解决实际工程问题,培养学生的工程实践能力,提高
工科学生的就业能力。

三.设计内容:
1.打开图像:
主要代码:
static char szFilter[]="BMP文件(*.bmp)|*.bmp||"; //定义过滤文件的类型
CFileDialog dlg(TRUE,"bmp",NULL,
OFN_HIDEREADONL Y|OFN_OVERWRITEPROMPT,szFilter);//定义文件对话框对象
CString filename;
int ret=dlg.DoModal(); //运行打开文件对方框
if(ret==IDOK)
{
filename=dlg.GetFileName(); //获取所选择图像的路径
m_dib.LoadFromFile(filename); //加载图像
if(!m_dib.m_bLoaded) //判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}
效果图:
2.水平镜像:把图像的第一列和最后一列调转,第二列和倒数第二列换过来,以此类推下去,直到第nw/2为止。

代码:
int temp,i,j;
for(j=0;j<nh;j++)
for(i=0;i<nw/2;i++)
{
temp=m_dib.m_pdata[j*nw+i];
m_dib.m_pdata[j*nw+i]=m_dib.m_pdata[nw-i-1+j*nw];
m_dib.m_pdata[nw-i-1+j*nw]=temp;
}
效果图:
3.素描风格:先把灰度值与右下的作对比,如果差值大于一个值则说明这是轮廓,先把非轮廓的位置像素置为黑色,最后对所有像素进行底片化处理
代码:
int temp,i,j;
for(j=0;j<nh;j++)
for(i=0;i<nw;i++)
{
temp=m_dib.m_pdata[j*nw+i]-m_dib.m_pdata[(j+1)*nw+i+1];
if(temp<10)
m_dib.m_pdata[j*nw+i]=0; //黑色为0
}
for(j=0;j<nh;j++)
for(i=0;i<nw;i++)
{
int gray=m_dib.m_pdata[j*nw+i];
m_dib.m_pdata[j*nw+i]=255-gray;
}
效果图:
4图像雾化:在图像中引入一定的随机值,打乱图像中的像素值
代码:
int i,j,k,dat; //i表示列,j表行
byte *ptemp=(byte *)new byte[nw*nh];
memset(ptemp,0,nw*nh);
for(j=0;j<nh;j++)
for(i=0;i<nw;i++)
{
k=rand()%8;//取任意的随机值
dat=j*nw+i+k;
if(dat>=nw*nh)
dat=nw*nh-1;
ptemp[j*nw+i]=m_dib.m_pdata[dat];
}
memcpy(m_dib.m_pdata,ptemp,nw*nh);
效果图:
5.浮雕处理:通过勾画图象轮廓和降低周围像素色值,从而生成具有凹凸感的浮雕效果。

其方法是生成一缓冲区,计算当前像素的左上角与右下角的像素值之差,再加上一个补值。

将其存储到缓冲区。

再将缓冲区的数据逐点替换到图像中并显示出来。

代码:
int w=3,i,j; //w为模板宽度
BYTE *p=new BYTE[nw*nh];
memcpy(p,m_dib.m_pdata,nw*nh);
for(j=w/2;j<nh-w/2;j++)
for(i= w/2;i<nw-w/2;i++)
{
p[j*nw+i]=m_dib.m_pdata[(j-1)*nw+i-1]*(1)+m_dib.m_pdata[(j+1)*nw+i+1]*(-1)+120;
}
memcpy(m_dib.m_pdata,p,nw*nh);
delete []p;
效果图:
6.直方图均衡化
代码:
int n[256]={0},g[256]={0}; //定义频数数组n,均衡化每个像素的灰度级的数组g double f[256],t[256]; //定义频率数组f,累加的频率数组t
int g_max=0,g_mim=255;
int i,j,k,z;
for(j=0;j<nh;j++) //统计灰度级的频数n
for(i=0;i<nw;i++)
{ z=m_dib.m_pdata[j*nw+i];
n[z]++;
}
for(k=0;k<=255;k++) //统计每个灰度级出现的频率
f[k]=n[k]/(nw*nh*1.0);
//累计灰度级的频率
t[0]=f[0];
for(k=1;k<=255;k++)
t[k]=t[k-1]+f[k];
for(j=0;j<nh;j++)
for(i=0;i<nw;i++)
{ BYTE w=m_dib.m_pdata[j*nw+i];
g_max=w>g_max?w:g_max; //得到最大值
g_mim=w<g_mim?w:g_mim; //得到最小值
}
for(k=0;k<=255;k++) //利用公式求每个像素均衡化后的灰度级
g[k]=(int)((g_max-g_mim)*t[k]+g_mim+0.5);
for(j=0;j<nh;j++) //逐个替换
for(i=0;i<nw;i++)
{
k=m_dib.m_pdata[j*nw+i];
m_dib.m_pdata[j*nw+i]=g[k];
}
for(j=0;j<nh;j++) //计算均衡化的直方图
for(i=0;i<nw;i++)
{ BYTE temp=m_dib.m_pdata[j*nw+i];
m_hist[temp]++;
}
m_bHist=true;
{ //绘制原图像的直方图
CString str;
int nh=m_dib.GetDIBHeight();
int i;
// 画坐标轴
// 绘制坐标轴
pDC->MoveTo(410,nh+20); //(410,nh+20 )是直方图的左上角坐标// 垂直轴
pDC->LineTo(410,nh+200);//(410,nh+200 )是直方图的左下角坐标// 水平轴
pDC->LineTo(710,nh+200);//(710,nh+200 )是直方图的右下角坐标// 写X轴刻度值
str.Format("0");
pDC->TextOut(410, nh+200+10, str);
str.Format("50");
pDC->TextOut(460, nh+200+10, str);
str.Format("100");
pDC->TextOut(510, nh+200+10, str);
str.Format("150");
pDC->TextOut(560, nh+200+10, str);
str.Format("200");
pDC->TextOut(610, nh+200+10, str);
str.Format("255");
pDC->TextOut(665, nh+200+10, str);
// 绘制X轴刻度
for ( i = 0; i < 256; i += 25)
{
if ((i & 1) == 0)
{
// 10的倍数
pDC->MoveTo(i + 10, nh+200-2);
pDC->LineTo(i + 10, nh+200+2);
}
else
{
// 10的倍数
pDC->MoveTo(i + 10, nh+200-2);
pDC->LineTo(i + 10, nh+200+2);
}
}
// 绘制X轴箭头
pDC->MoveTo(705,nh+200-5);
pDC->LineTo(710,nh+200);
pDC->LineTo(705,nh+200+5);
// 绘制y轴箭头
pDC->MoveTo(410,nh+20);
pDC->LineTo(405,nh+20+5);
pDC->MoveTo(410,nh+20);
pDC->LineTo(415,nh+20+5);
int max=0;
for(i=0;i<256;i++)
if(m_yuan[i]>max)
max=m_yuan[i];
for(i=0;i<256;i++)
{
pDC->MoveTo(410+i,nh+200);
pDC->LineTo(410+i,nh+200-(m_yuan[i]*160/max));
}
}
}
if(m_bHist==true) //绘画新的直方图
{
CString str;
int nh=m_dib.GetDIBHeight();
int i;
// 画坐标轴
// 绘制坐标轴
pDC->MoveTo(10,nh+20); //(10,nh+20 )是直方图的左上角坐标// 垂直轴
pDC->LineTo(10,nh+200);//(10,nh+200 )是直方图的左下角坐标// 水平轴
pDC->LineTo(310,nh+200);//(310,nh+200 )是直方图的右下角坐标// 写X轴刻度值
str.Format("0");
pDC->TextOut(10, nh+200+10, str);
str.Format("50");
pDC->TextOut(60, nh+200+10, str);
str.Format("100");
pDC->TextOut(110, nh+200+10, str);
str.Format("150");
pDC->TextOut(160, nh+200+10, str);
str.Format("200");
pDC->TextOut(210, nh+200+10, str);
str.Format("255");
pDC->TextOut(265, nh+200+10, str);
// 绘制X轴刻度
for ( i = 0; i < 256; i += 25)
{
if ((i & 1) == 0)
{
// 10的倍数
pDC->MoveTo(i + 10, nh+200-2);
pDC->LineTo(i + 10, nh+200+2);
}
else
{
// 10的倍数
pDC->MoveTo(i + 10, nh+200-2);
pDC->LineTo(i + 10, nh+200+2);
}
}
// 绘制X轴箭头
pDC->MoveTo(305,nh+200-5);
pDC->LineTo(310,nh+200);
pDC->LineTo(305,nh+200+5);
// 绘制y轴箭头
pDC->MoveTo(10,nh+20);
pDC->LineTo(5,nh+20+5);
pDC->MoveTo(10,nh+20);
pDC->LineTo(15,nh+20+5);
int max=0;
for(i=0;i<256;i++)
if(m_hist[i]>max)
max=m_hist[i];
for(i=0;i<256;i++)
{
pDC->MoveTo(10+i,nh+200);
pDC->LineTo(10+i,nh+200-(m_hist[i]*160/max));
}
}
效果图:
四.心得体会:
通过这次数字图像处理的课程设计,对图片有了更深一层的认识,理解了对图像处理的一些原理,在这个课程设计过程中,需要自己去查阅资料,找资料,还需要理解所找到的资料,遇到问题独立去思考,或者去请教同学,给了我一个很好的锻炼机会,做事情一定要坚持,最后一定会有收获的。

五.参考文献:
《数字图像处理》——电子工业出版社
《vc++数字图像处理实验指导书》曹老师、何家峰主编。

相关文档
最新文档