
/
函数名称:
HoughDIB()
参数:
LPSTR lpDIBBits - 指向源DIB图像指针
LONG lWidth - 源图像宽度(象素数)
LONG lHeight - 源图像高度(象素数)
LONG lLineBytes - 源图像每行所占的字节数
WORD wBitsPerPixel - 源图像位深
LPSTR lpNewDIBBits - 目标图像数据区的指针
返回值:
BOOL - 运算成功返回TRUE,否则返回FALSE。
说明:
该函数用于对检测图像中的平行直线。如果图像中有两条平行的直线,则将这两条平行直线
提取出来。
要求目标图像为只有0和255两个灰度值的灰度图像。
/
BOOL WINAPI HoughDIB(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,LONG lLineBytes,
WORD wBitsPerPixel,LPSTR lpNewDIBBits)
{
// 指向源图像的指针
LPSTR lpSrc;
// 指向缓存图像的指针
LPSTR lpDst;
// 指向变换域的指针
LPSTR lpTrans;
// 图像每行的字节数
// LONG lLineBytes;
// 指向缓存DIB图像的指针
//LPSTR lpNewDIBBits;
//HLOCAL hNewDIBBits;
//指向变换域的指针
LPSTR lpTransArea;
HLOCAL hTransArea;
//变换域的尺寸
int iMaxDist;
int iMaxAngleNumber;
//变换域的坐标
int iDist;
int iAngleNumber;
//循环变量
long i;
long j;
//像素值
unsigned char pixel;
//存储变换域中的两个最大值
MaxValue MaxValue1;
MaxValue MaxValue2;
// 暂时分配内存,以保存新图像
//hNewDIBBits = LocalAlloc(LHND, lWidth lHeight);
// 初始化新分配的内存,设定初始值为255
lpDst = (char )lpNewDIBBits;
memset(lpDst, (BYTE)255, lLineBytes lHeight);
//计算变换域的尺寸
//最大距离
iMaxDist = (int) sqrt(lWidthlWidth + lHeightlHeight);
//角度从0-180,每格2度
iMaxAngleNumber = 90;
//为变换域分配内存
hTransArea = LocalAlloc(LHND, lWidth lHeight sizeof(int));
// 锁定内存
lpTransArea = (char )LocalLock(hTransArea);
// 初始化新分配的内存,设定初始值为0
lpTrans = (char )lpTransArea;
memset(lpTrans, 0, lWidth lHeight sizeof(int));
for(j = 0; j <lHeight; j++)
{
for(i = 0;i <lWidth; i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char )lpDIBBits + lLineBytes j + i;
//取得当前指针处的像素值,注意要转换为unsigned char型
pixel = (unsigned char)lpSrc;
//目标图像中含有0和255外的其它灰度值
if(pixel != 255 && lpSrc != 0)
{
MessageBox(NULL,"目标图像中含有0和255外的其它灰度值","错误",MB_OK);
return FALSE;
}
//如果是黑点,则在变换域的对应各点上加1
if(pixel == 0)
{
//注意步长是2度
for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++)
{
iDist = (int) fabs(icos(iAngleNumber2PI/1800) + \
jsin(iAngleNumber2PI/1800));
//变换域的对应点上加1
(lpTransArea+iDistiMaxAngleNumber+iAngleNumber) = \
(lpTransArea+iDistiMaxAngleNumber+iAngleNumber) +1;
}
}
}
}
//找到变换域中的两个最大值点
MaxValue1Value=0;
MaxValue2Value=0;
//找到第一个最大值点
for (iDist=0; iDist<iMaxDist;iDist++)
{
for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++)
{
if((int)(lpTransArea+iDistiMaxAngleNumber+iAngleNumber)>MaxValue1Value)
{
MaxValue1Value = (int)(lpTransArea+iDistiMaxAngleNumber+iAngleNumber);
MaxValue1Dist = iDist;
MaxValue1AngleNumber = iAngleNumber;
}
}
}
//将第一个最大值点附近清零
for (iDist = -9;iDist < 10;iDist++)
{
for(iAngleNumber=-1; iAngleNumber<2; iAngleNumber++)
{
if(iDist+MaxValue1Dist>=0 && iDist+MaxValue1Dist<iMaxDist \
&& iAngleNumber+MaxValue1AngleNumber>=0 && iAngleNumber+MaxValue1AngleNumber<=iMaxAngleNumber)
{
(lpTransArea+(iDist+MaxValue1Dist)iMaxAngleNumber+\
(iAngleNumber+MaxValue1AngleNumber))=0;
}
}
}
//找到第二个最大值点
for (iDist=0; iDist<iMaxDist;iDist++)
{
for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++)
{
if((int)(lpTransArea+iDistiMaxAngleNumber+iAngleNumber)>MaxValue2Value)
{
MaxValue2Value = (int)(lpTransArea+iDistiMaxAngleNumber+iAngleNumber);
MaxValue2Dist = iDist;
MaxValue2AngleNumber = iAngleNumber;
}
}
}
//判断两直线是否平行
if(abs(MaxValue1AngleNumber-MaxValue2AngleNumber)<=2)
{
//两直线平行,在缓存图像中重绘这两条直线
for(j = 0; j <lHeight; j++)
{
for(i = 0;i <lWidth; i++)
{
// 指向缓存图像倒数第j行,第i个象素的指针
lpDst = (char )lpNewDIBBits + lLineBytes j + i;
//如果该点在某一条平行直线上,则在缓存图像上将该点赋为黑
//在第一条直线上
iDist = (int) fabs(icos(MaxValue1AngleNumber2PI/1800) + \
jsin(MaxValue1AngleNumber2PI/1800));
if (iDist == MaxValue1Dist)
lpDst = (unsigned char)0;
//在第二条直线上
iDist = (int) fabs(icos(MaxValue2AngleNumber2PI/1800) + \
jsin(MaxValue2AngleNumber2PI/1800));
if (iDist == MaxValue2Dist)
lpDst = (unsigned char)0;
}
}
}
// 释放内存
LocalUnlock(hTransArea);
LocalFree(hTransArea);
// 返回
return TRUE;
}
矩阵方程 和对应的向量方程 之间的差别仅仅是记号上的不同。然而矩阵方程 出现在线性代数和应用中并不仅仅是直接与向量的线性组合问题有关。通常的情况是把矩阵 当作一个对象,它通过乘法“作用”于向量 ,产生新的向量称为 。
由这个新观点,若 ,解方程 可解释为:求出 中所有经过乘以 的“作用”后变成为 中 的向量 。
由 到 的对应是由一个向量集到另一个向量集的函数。这个概念推广了通常的函数概念,通常的函数是把一个实数变为另一个实数的规则。
由 到 的一个 变换 (或 函数 、 映射 ) 是一个规则,它把 中每个向量 对应以 中一个向量 。集 称为 的 定义域 ,而 称为 的 余定义域 (或 取值空间 )符号 : 说明 的定义域是 而余定义域是 。对于 中向量 , 中向量 称为 (在 作用下)的 像 。所有像 的集合称为 的 值域 。
对 中每个 , 由 计算得到,其中 是 矩阵。为简单起见,有时将这样一个矩阵变换记为 。注意当 有 列时, 的定义域为 ,而当 的每个列有 个元素时, 的余定义域为 。 的值域为 的列的所有线性组合的集合,因为每个像 有 的形式。
设 ,定义变换 : 为 ,于是
第三个方程是0=-35,说明方程无解。因此 不属于 的值域。
若 ,则变换 是把 中的点投影到 坐标平面上,因为
若 ,变换 定义为 ,称为 剪切变换 。可以说明,若 作用一个正方形的各点,则像的集构成带阴影的平行四边形。关键的思想是证明 将线段映射称为线段,然后验证正方形的4个顶点映射成平行四边形的4个顶点。
定义 变换(或映射) 称为线性的,若
线性变换保持向量的加法运算与标量乘法运算。
若 是线性变换,则 ,且对 的定义域中一切向量 和 以及数 和 有: 。
对所有 和 ,若一个变换满足 ,该变换必是线性的。
(若 ,可满足 定义条件1 ;若 ,可满足 定义条件2 。)
重复应用 ,得出推广: 。该推广等式,在工程和物理中,称为 叠加原理 。
给定数 ,定义 为 ,当 时, 称为 压缩变换 ;当 时, 称为 拉伸变换 。设 ,证明 是线性变换。
解:设 属于 , 为数,则
因满足 ,故此变换必是线性的。
其实可以猜出矩阵 。
几何线型变化的话(因为你提到了坐标),因此我建议你采用开源的计算几何库,矩阵变化,平移,向量运算都有
看看这个
>
第2行除以 -5,得到
0 3 1 1
第3行减去第2行乘以5 +a/3,得到
0 0 (12-a)/3 (12-a)/3
第4行减去第2行 2,得到
0 0 0 b-4
这就是你要的结果
程序是下面这样,但只能处理长宽一样的方形图像,灰度和彩色图像都可,要用其他图像只需把Lenabmp改为其他图像,但图像要保存在m文件所在路径下。下面还有一个运行后的图像(之一),希望能对你有所帮助。
clear;clc;
%%%%%%%%%%测试图像只能是方形图像,长宽像素一样。
f=imread('Lenabmp');%%读取图像数据,图像只能保存在m文件所在的路径下
d=size(f);
if length(d)>2
f=rgb2gray((f));%%%%%%%%如果是彩色图像则转化为灰度图
end
T=d(1);
SUB_T=T/2;
% 2进行二维小波分解
l=wfilters('db10','l'); % db10(消失矩为10)低通分解滤波器冲击响应(长度为20)
L=T-length(l);
l_zeros=[l,zeros(1,L)]; % 矩阵行数与输入图像一致,为2的整数幂
h=wfilters('db10','h'); % db10(消失矩为10)高通分解滤波器冲击响应(长度为20)
h_zeros=[h,zeros(1,L)]; % 矩阵行数与输入图像一致,为2的整数幂
for i=1:T; % 列变换
row(1:SUB_T,i)=dyaddown( ifft( fft(l_zeros)fft(f(:,i)') ) )'; % 圆周卷积<->FFT
row(SUB_T+1:T,i)=dyaddown( ifft( fft(h_zeros)fft(f(:,i)') ) )'; % 圆周卷积<->FFT
end;
for j=1:T; % 行变换
line(j,1:SUB_T)=dyaddown( ifft( fft(l_zeros)fft(row(j,:)) ) ); % 圆周卷积<->FFT
line(j,SUB_T+1:T)=dyaddown( ifft( fft(h_zeros)fft(row(j,:)) ) ); % 圆周卷积<->FFT
end;
decompose_pic=line; % 分解矩阵
% 图像分为四块
lt_pic=decompose_pic(1:SUB_T,1:SUB_T); % 在矩阵左上方为低频分量--fi(x)fi(y)
rt_pic=decompose_pic(1:SUB_T,SUB_T+1:T); % 矩阵右上为--fi(x)psi(y)
lb_pic=decompose_pic(SUB_T+1:T,1:SUB_T); % 矩阵左下为--psi(x)fi(y)
rb_pic=decompose_pic(SUB_T+1:T,SUB_T+1:T); % 右下方为高频分量--psi(x)psi(y)
% 3分解结果显示
figure(1);
subplot(2,1,1);
imshow(f,[]); % 原始图像
title('original pic');
subplot(2,1,2);
image(abs(decompose_pic)); % 分解后图像
title('decomposed pic');
figure(2);
% colormap(map);
subplot(2,2,1);
imshow(abs(lt_pic),[]); % 左上方为低频分量--fi(x)fi(y)
title('\Phi(x)\Phi(y)');
subplot(2,2,2);
imshow(abs(rt_pic),[]); % 矩阵右上为--fi(x)psi(y)
title('\Phi(x)\Psi(y)');
subplot(2,2,3);
imshow(abs(lb_pic),[]); % 矩阵左下为--psi(x)fi(y)
title('\Psi(x)\Phi(y)');
subplot(2,2,4);
imshow(abs(rb_pic),[]); % 右下方为高频分量--psi(x)psi(y)
title('\Psi(x)\Psi(y)');
% 5重构源图像及结果显示
% construct_pic=decompose_matrix'decompose_picdecompose_matrix;
l_re=l_zeros(end:-1:1); % 重构低通滤波
l_r=circshift(l_re',1)'; % 位置调整
h_re=h_zeros(end:-1:1); % 重构高通滤波
h_r=circshift(h_re',1)'; % 位置调整
top_pic=[lt_pic,rt_pic]; % 图像上半部分
t=0;
for i=1:T; % 行插值低频
if (mod(i,2)==0)
topll(i,:)=top_pic(t,:); % 偶数行保持
else
t=t+1;
topll(i,:)=zeros(1,T); % 奇数行为零
end
end;
for i=1:T; % 列变换
topcl_re(:,i)=ifft( fft(l_r)fft(topll(:,i)') )'; % 圆周卷积<->FFT
end;
bottom_pic=[lb_pic,rb_pic]; % 图像下半部分
t=0;
for i=1:T; % 行插值高频
if (mod(i,2)==0)
bottomlh(i,:)=bottom_pic(t,:); % 偶数行保持
else
bottomlh(i,:)=zeros(1,T); % 奇数行为零
t=t+1;
end
end
这个只是一级分解,matlab自带的函数可以实现多级分解,级数由编程者自己确定。
是的,是一样的。
(1)编写用双性变换法设计巴特沃兹低通IIR数字滤波器的程序,要求通带 内频率低于02pirad时,容许幅度误差在1dB之内,频率在03pirad到pirad 之间的阻带衰减大于10dB。
(2)用双线性变换法设计Butterworth低通IIR数字滤波器,要求使用buttord, butter和bilinear函数。滤波器技术指标:取样频率1Hz,通带内临界频率02Hz,通带内衰减小于1dB;阻带临界频率03Hz,阻带内衰减大于25dB。
(3)以pi/64为取样间隔,在屏幕上打印出数字滤波器的频率区间[0,pi] 上的幅 频响应特性曲线(|H(ejw)|或20lg|H(ejw)|)。
(4)在屏幕上打印出H(z)的分子,分母多项式系数。
扩展资料
通带截止频率为02prad,阻带截止频率为03prad,图中横坐标w是数字频率,对应的模拟频率为0-fs/2。通带截止频率为04prad,阻带截止频率为06prad
看低通滤波器的幅频特性,并掌握了用双线性变换法设计巴特沃斯低通IIR数字滤波器的方法。双线性变换法首先根据模拟滤波器的指标设计出相应的模拟滤波器,然后再讲设计好的模拟滤波器转换成满足给定指标的数字滤波器。
以上就是关于求助编程实现hough变换检测直线全部的内容,包括:求助编程实现hough变换检测直线、线性方程组(八)- 线性变换介绍、用C++编写程序 已知两套坐标数据求坐标转换的7参数 ,线性变换。有平移参数,旋转参数和尺度参数等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)