作者:爱撒娇的小妮子(华丽杀猫帮)
下载源代码
引言
感谢VCKBASE以及其中无数的大大们提供了如此多的实实在在的开源代码,使我一个在学校的学生能够接触到一些实实在在的东西.想来自己潜水也有一载了.如今眼瞅毕业了即将成为无业游民,投篇拙文留个纪念.顺便感叹一下前途的迷茫.
言归正传,写这个程序主要是由于毕业设计,放在学校档案室如土不如拿上来给大家分享.其实主要功能是对图象利用canny算子进行边缘检测.以及其他一些比较基本的滤镜功能.
主要应用了GDI+ 所以图象格式处理与显示都比较容易.主要思想是转化为一个bmp位图矩阵,然后对这个矩阵用一些算子进行操作,这些算子大多都能在网上找到现成的资料,所以不在这里赘言了.
顺便提一下canny算子只有c函数的.理论依据对数学要求颇高,我也没深入研究下去所以边缘查找的效果有时候并不是非常的好,容易检测出一些多余的东西.
编程实现:
原图

Canny算子找边缘的实现,canny算子的代码请看源文件 或者网上搜 canny算子进行提取边缘之前先要对图象进行黑白处理。
void CFigureView::OnPsCanny()
{
// TODO: 在此添加命令处理程序代码
CWaitCursor WaitCursor;
int nWidth = m_imageFile.GetWidth();
int nHeight= m_imageFile.GetHeight();
// 开辟内存,存储图象数据
unsigned char * pUnchImage = new unsigned char[nWidth*nHeight];
// 将图像数据保存在矩阵当中
for(int y = 0;y<nHeight;y++)
{
for(int x = 0;x<nWidth;x++)
{
COLORREF pixel=m_imageFile.GetPixel(x,y);
byte r,g,b;
r = GetRValue(pixel);
g = GetGValue(pixel);
b = GetBValue(pixel);
pUnchImage[y*nWidth+x] = 255<<24 | r<<16| g<<8|b;
}
}
// canny算子计算后的结果
unsigned char * pUnchEdge = new unsigned char[nWidth*nHeight];
// 调用canny函数进行边界提取
Canny(pUnchImage, nWidth, nHeight, 0.4, 0.4, 0.79, pUnchEdge) ;
//将运算完的图像转化为矩阵
for(int y=0; y<nHeight; y++)
{
for(int x=0; x<nWidth; x++)
{
byte r,g,b,Result;
r = (0x000000ff&pUnchEdge[y*nWidth+x]>>16)?0:255;
g = (0x000000ff&pUnchEdge[y*nWidth+x]>>8)?0:255;
b = (0x000000ff&pUnchEdge[y*nWidth+x])?0:255;
Result = ((r+g+b)/3);
m_imageFile.SetPixelRGB(x,y,Result,Result,Result);
}
}
MakeBlackWhiteImage(m_imageFile,0);
delete []pUnchImage;
pUnchImage = NULL ;
delete []pUnchEdge ;
pUnchEdge = NULL ;
CFigureDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
pDoc->SetModifiedFlag(TRUE);
Invalidate();
}
Canny算子效果:
 |
 |
黑白处理的 |
canny算子的效果 |
底片化处理:void CFigureView::OpposeImage(CImage& pImage)
{
CWaitCursor WaitCursor;
int height = m_imageFile.GetHeight();
int width = m_imageFile.GetWidth();
for(int x=0;x<width;x++)
{
for(int y=0;y<height;y++)
{
COLORREF pixel=m_imageFile.GetPixel(x,y);
byte r,g,b;
r=GetRValue(pixel);
g=GetGValue(pixel);
b=GetBValue(pixel);
m_imageFile.SetPixelRGB(x,y,255-r,255-g,255-b);
}
}
}
底片化处理效果:

暗化处理void CFigureView::DarkImage(CImage& pImage)
{
CWaitCursor WaitCursor;
int width = pImage.GetWidth();
int height = pImage.GetHeight();
for(int x=0;x<width;x++)
{
for(int y=0;y<height;y++)
{
COLORREF pixel=pImage.GetPixel(x,y);
byte r,g,b;
r=GetRValue(pixel);
g=GetGValue(pixel);
b=GetBValue(pixel);
pImage.SetPixelRGB(x,y,r*0.8,g*0.8,b*0.8);
}
}
}
暗化效果

等等还有一些东西不在这里废话了.
结束语
本项目在vs2005下编译运行通过.
鄙人才疏学浅,入门不久,如有错误 或者不妥或建议请指出.
其中有些算法源自网上,作者记不得了,望作者海涵
愿对本人前途指点迷津的不胜感激(找第一份工作,越找越没信心,表b4我) |