您的位置:首页 > 职场人生

黑马程序员之图像处理中的边缘检测

2014-07-14 17:18 211 查看
android培训 java培训 期待与您交流!

简单的通过灰度处理的方法,毕竟图像是离散化的,可以使用另外的方法求梯度,而不用像高数中那样拼命地算偏导数了。有很多学者提出了很多种不同性能的模板,只要按照模板作简单的四则运算就行了,当然这也是能用程序实现的关键。由于作为教学课程,所有的内容都是以简单的灰度图像来说明举例的,当然边缘检测也不例外,留作业写程序也是一样,所以马上就遇到的一个问题是如何将彩色图像转为灰度图像。在课程中,都是简单的认为灰度图像只有一个亮度,这自然是没错的,但是放到计算机里,灰度也是一种颜色,是颜色就要使用色彩模式(最常用的自然是RGB了),那么这种灰度到底应该是怎样的颜色编码呢?索性取向Photoshop,看一看各种灰度色调,终于有所发祥。其实也可以这么想,全黑是#000000,全白是#FFFFFF,那么是不是只要RGB值都相等,这个颜色就是灰度色呢?试了一下,果然如此。这样就好办了,至少第一步知道了转换的目标是什么了。但马上就又有了一个问题,彩色图片的颜色这么多,那么如何知道哪种彩色颜色对应哪种灰度颜色呢?这一点我从.net Framework中找到了答案。其实我从一开始就想在.net Framework中寻找有没有直接将RGB转成灰度或者是HIS模式(因为HIS模式中的I就使亮度,自然就容易转成灰度了)的,是不是太奢望了,所以我也没抱太大的希望,但是在这过程中却发现Color中有关一个实例方法GetBrightness(),就是用来获得颜色亮度的,真是踏破铁鞋无觅处,得来全不费功夫。该方法返回一个0~1之间的浮点数,那么如果RGB每个各占一个字节的话,那么刚好可以用这个值去乘以255,然后拼成一个RGB,这个颜色就是原始色彩所对应的灰色。程序代码如下:

Color oColor,gColor; //定义两个颜色变量,oColor为原始色彩,gColor为对应的灰度色彩
float brightness;//原始色彩的亮度
int gRGB;//灰度色彩用RGB来表示,由于R=G=B所以只用一个变量就可以了
//遍历图像中的每个像素
for (int i=0; i<oBmp.Width; i++)
{
for (int j=0; j<oBmp.Height; j++)
{
oColor = oBmp.GetPixel(i,j);//得到像素的原始色彩
brightness = oColor.GetBrightness();//得到该色彩的亮度
gRGB = (int)(brightness * 255);//用该亮度计算灰度
gColor = Color.FromArgb(gRGB,gRGB,gRGB);//组成灰度色彩
gBmp.SetPixel(i,j,gColor);最后将该灰度色彩赋予该像素
}
}
其实还是很简单的。这之后就可以按照数中所说的模板游历的方法来进行边缘检测了。程序如下:

//template为模板,nThreshold是一个阈值,用来将模板游历的结果(也就是梯度)进行划分。大于阈值的和小于阈值的
//分别赋予两种颜色,白或黑来标志边界和背景
private void EdgeDectect(int[,] template,int nThreshold)
{
//取出和模板等大的原图中的区域
int[,] gRGB = new int[3,3];
//模板值结果,梯度
int templateValue = 0;
//遍历灰度图中每个像素
for (int i=1; i<gBmp.Width - 1; i++)
{
for (int j=1; j<gBmp.Height - 1; j++)
{
//取得模板下区域的颜色,即灰度
gRGB[0,0] = gBmp.GetPixel(i-1,j-1).R;
gRGB[0,1] = gBmp.GetPixel(i-1,j).R;
gRGB[0,2] = gBmp.GetPixel(i-1,j+1).R;
gRGB[1,0] = gBmp.GetPixel(i,j-1).R;
gRGB[1,1] = gBmp.GetPixel(i,j).R;
gRGB[1,2] = gBmp.GetPixel(i,j+1).R;
gRGB[2,0] = gBmp.GetPixel(i+1,j-1).R;
gRGB[2,1] = gBmp.GetPixel(i+1,j).R;
gRGB[2,2] = gBmp.GetPixel(i+1,j+1).R;
//按模板计算
for (int m=0; m<3; m++)
{
for (int n=0; n<3; n++)
{
templateValue += template[m,n] * gRGB[m,n];
}
}
//将梯度之按阈值分类,并赋予不同的颜色
if (templateValue > nThreshold)
{
eBmp.SetPixel(i,j,Color.FromArgb(255,255,255));//白
}
else
{
eBmp.SetPixel(i,j,Color.FromArgb(0,0,0));//黑
}
templateValue = 0;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: