我最近正在看《Visual C++数字图像处理开发入门与编程实践》这本书,对与里面介绍的直线的Hough变换中的像素坐标有些不是太清楚。
首先,在书中所有图像的像素数组的排列顺序都是按扫描行自下而上存储的,也就是位图的原点位于左下角。但是当介绍直线的Hough变换时书中是这样介绍的:“用二维向量(ρ,θ)描述图像中的每一条直线区域,则可将图像上的直线区域计数器映射到参数空间H(ρ,θ)中的存储单元,由于ρ为直线区域到原点的距离,因此对于对角线长度为n的图像,固定左上角为原点,可得到ρ的取值范围为【0,n】,令θ以1度为增量,可得到θ的取值范围【0,360】
按照这里的意思,图像原点又变成了左上角,我看了看书上的程序觉得有些出入,对里面的角度认识也不是太准确,里面的θ是直线和谁的夹角?是以左下角为原点的夹角还是以左上角为原点的夹角?部分程序如下:
/**************************************************************************
*直线的Hough检测
*参数:image0为源文件,image1为边缘检测结果,w、h为图像的宽和高,
*由于得到的Hought变换类型结果图像与源图像大小不同,为了得到新的宽、高信息w、h使用了引用类型***************************************************************************/
void HoughLine(BYTE* image0,BYTE*&image1,unsigned int &w,unsigned int &h,int scale = 1)
{
//定义三角函数表
double sinValue[360];
double cosValue[360];
int i,x,y;
int k=100;
int p =(int)(sqrt(w*w+h*h)+1);//计算对角线长度
//申请临时储存空间用来保存边缘检测结果
BYTE* tempImage=(BYTE)malloc(sizeof(BYTE)*w*h*4);
SideGrandiant(image0,tempImage,w,h);//边缘检测
//根据Hough变换结果图的大小,重新为输出图像分配空间
if(image!=NULL) free(image1);
image1=(BYTE*)malloc(sizeof(BYTE*)p*360*4);
memset(image1,0,(p)*360*4);
BYTE** HoughBuf = CreatImage(image1,360,p);//将图像转换成矩阵形式
//计算三角函数表
for(i=0;i<360;i++)
{
sinValue[i] = sin(i*3.1415926/180);
cosValue[i] = cos(i*3.1415926/180);
}
int tp;
//遍历源图像中的每一个像素
for(y=0;y<h;y++) /////////这里是不是就是说明了像素是从图像的最下面也就是左下角开始遍历的////////
for(x=0;x<w;x++)
{
//对经过当前像素的任何直线区域进行检测
for(i=0;i<360;i++)
{
if(tempImage[(y*w+x)*4]>k)
{
tp=(int)(x*sinValue[i]+y*cosValue[i]; ///////这里的i角度是直线和左上角还是左下角的夹角?//// //忽略负数同时防止计数器溢出
if(tp<0||HoughBuf[tp][i*4]==255)continue;
HoughBuf[tp][i*4]+=scale;
HoughBuf[tp][i*4+1]+=scale;
HoughBuf[tp][i*4+2]+=scale;
HoughBuf[tp][i*4+3]+=255;
}
}
}
//重新设定图像大小
w=360;
h=p;
free(HoughBuf);
free(tempImage);
}
首先,在书中所有图像的像素数组的排列顺序都是按扫描行自下而上存储的,也就是位图的原点位于左下角。但是当介绍直线的Hough变换时书中是这样介绍的:“用二维向量(ρ,θ)描述图像中的每一条直线区域,则可将图像上的直线区域计数器映射到参数空间H(ρ,θ)中的存储单元,由于ρ为直线区域到原点的距离,因此对于对角线长度为n的图像,固定左上角为原点,可得到ρ的取值范围为【0,n】,令θ以1度为增量,可得到θ的取值范围【0,360】
按照这里的意思,图像原点又变成了左上角,我看了看书上的程序觉得有些出入,对里面的角度认识也不是太准确,里面的θ是直线和谁的夹角?是以左下角为原点的夹角还是以左上角为原点的夹角?部分程序如下:
/**************************************************************************
*直线的Hough检测
*参数:image0为源文件,image1为边缘检测结果,w、h为图像的宽和高,
*由于得到的Hought变换类型结果图像与源图像大小不同,为了得到新的宽、高信息w、h使用了引用类型***************************************************************************/
void HoughLine(BYTE* image0,BYTE*&image1,unsigned int &w,unsigned int &h,int scale = 1)
{
//定义三角函数表
double sinValue[360];
double cosValue[360];
int i,x,y;
int k=100;
int p =(int)(sqrt(w*w+h*h)+1);//计算对角线长度
//申请临时储存空间用来保存边缘检测结果
BYTE* tempImage=(BYTE)malloc(sizeof(BYTE)*w*h*4);
SideGrandiant(image0,tempImage,w,h);//边缘检测
//根据Hough变换结果图的大小,重新为输出图像分配空间
if(image!=NULL) free(image1);
image1=(BYTE*)malloc(sizeof(BYTE*)p*360*4);
memset(image1,0,(p)*360*4);
BYTE** HoughBuf = CreatImage(image1,360,p);//将图像转换成矩阵形式
//计算三角函数表
for(i=0;i<360;i++)
{
sinValue[i] = sin(i*3.1415926/180);
cosValue[i] = cos(i*3.1415926/180);
}
int tp;
//遍历源图像中的每一个像素
for(y=0;y<h;y++) /////////这里是不是就是说明了像素是从图像的最下面也就是左下角开始遍历的////////
for(x=0;x<w;x++)
{
//对经过当前像素的任何直线区域进行检测
for(i=0;i<360;i++)
{
if(tempImage[(y*w+x)*4]>k)
{
tp=(int)(x*sinValue[i]+y*cosValue[i]; ///////这里的i角度是直线和左上角还是左下角的夹角?//// //忽略负数同时防止计数器溢出
if(tp<0||HoughBuf[tp][i*4]==255)continue;
HoughBuf[tp][i*4]+=scale;
HoughBuf[tp][i*4+1]+=scale;
HoughBuf[tp][i*4+2]+=scale;
HoughBuf[tp][i*4+3]+=255;
}
}
}
//重新设定图像大小
w=360;
h=p;
free(HoughBuf);
free(tempImage);
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货