canny边缘提取之二 高斯图像滤波(将matlab的imfilter函数转换为C++函数)
2015-05-13 11:05
645 查看
matlab格式详解:
1.函数模板
B=imfilter(A,H,options);
(a) -Boundary
options
%
% X
Input array values outside thebounds of the array
% are implicitly assumed tohave the value X.
When no
% boundary option isspecified, IMFILTER uses X = 0.
%
% 'symmetric'
Input array values outside the bounds of thearray
% are computed bymirror-reflecting the array across
% the array border.
%
% 'replicate'
Input array values outside the bounds of thearray
% are assumed to equal thenearest array border
% value.(图片边界处像素的计算,采用将边界向外延长n=((size(H,1)+1)/2-1)个像素,延长的像素值为对应边界像素值。)
%
% 'circular'
Input array values outside the bounds of thearray
% are computed by implicitlyassuming the input array
% is periodic.
(b) Output size options
% (Output size options for IMFILTER areanalogous to the SHAPE option
% in the functions CONV2 and FILTER2.)
%
% 'same'
The output array is the same size as theinput
% array.
This is the default behavior when no output
% size options are specified.
%
% 'full'
The output array is the full filteredresult, and so
% is larger than the inputarray.
%
c) Correlation and convolution
%
% 'corr'
IMFILTER performs multidimensional filteringusing
% correlation, which is thesame way that FILTER2
% performs filtering.
When no correlation or
% convolution option isspecified, IMFILTER uses
% correlation.(滤波模板H不发生变换,直接进行模板计算)
%
% 'conv'
IMFILTER performs multidimensionalfiltering using
% convolution.
(滤波模板H发生180度旋转(先行转置,后列转置),之后进行模板计算)
%
‘Conv’详解:卷积窗为,180度旋转后==》
2.滤波/卷积过程
线性滤波可以用卷积实现,输出图像的像素值是输入图像对应像素及其邻域像素的线性加权,权重矩阵称为卷积窗。图20.56说明了图像卷积的过程,图像I为,卷积窗为。现在要计算像素点(2,4)卷积后的结果,卷积过程如下:
(1)将卷积窗相对于中心旋转180度,得;
(2)将卷积窗的中心滑动至(2,4);
(3)计算(2,4)的邻域与卷积窗对应像素的积,并求和,结果即为卷积后(2,4)处的像素值。
因此(2,4)的卷积结果为1´2 + 8´9+ 15´4 + 7´7 + 5´14 + 16´3 + 6´13 + 1´20 +8´22
= 575。
卷积窗滑动过程中有可能超出图像的边界,如图20.57所示。对于图像边界外的像素值,一般有两种方法处理,其一是用0填充(图20.58),其二是用最邻近的边界值填充(图20.59)。
图20.56 图像卷积过程 图20.57 图像卷积越界
图20.58 卷积过程的边界处理,0填充 图20.59 卷积过程的边界处理,邻域填充
相关与卷积类似,输出图像的像素值是输入图像对应像素及其邻域的线性加权,权重矩阵称为相关窗。相关与卷积的唯一差别是,不需要对相关窗口旋转。图像相关也需要考虑到边界的处理,处理方式与卷积相同。
3.注意事项,
当前处理像素f(i,j)在卷积窗口的对应位置为,i=size(H,1)+1/2;j=size(H,2)+1/2;
即,(a)当H尺寸为7*1时,i=(7+1)/2=4;(该值对应matlab时=4;对应C时=3)
(b)当H尺寸为6*1时,i=(6+1)/2=3;(该值对应matlab时=3;对应C时=2)
H=[h1,h2,h3,h4,h5,h6,h7]; F(i)=f(i-3)*h1+ f(i-2)*h2+f(i-1)*h3+ f(i)*h4+f(i+1)*h5+ f(i+2)*h6+f(i+3)*f7;
H=[h1,h2,h3,h4,h5,h6]; F(i)= f(i-2)*h1+f(i-1)*h2+ f(i)*h3+ f(i+1)*h4+f(i+2)*h5+f(i+3)*f6;
C++转换:
//matlab_canny.h
//将matlab中的edge(I,'canny')函数转换为C++代码
class matlab_canny{
public:
struct canny_data{
int height;
int width;
float* data;
};
//对图像src进行水平方向/垂直方向的滤波 ,仅对一个方向进行卷积
//src --- 原始图像
//filter -- 滤波后图像
//H -- 卷积窗口
//其中相对于matlab中的imfilter来说,对应的option为'corr'+'replicate'
void matlab_imfilter(canny_data* src, canny_data* filter, canny_data* H);
};
//matlab_canny.cpp
#include"canny_matlab.h"
void matlab_canny::matlab_imfilter(canny_data* src, canny_data* filter, canny_data* H)
{
int height, width, h_h_1, h_h_2, h_w_1, h_w_2;
float sum_data, src_data;
height = src->height;
width = src->width;
int direction = 0;//进行水平和垂直方向卷积 direction-卷积方向:0--水平+垂直;1--水平; 2--垂直
if (H->height == 0 && H->width == 0)
{
printf("ERROR:卷积窗口H大小为0!");
}
if (H->height == 0)
{
h_h_1 = 0;
h_h_2 = 0;
direction = 1;//进行水平方向卷积
}
else
{
h_h_1 = (H->height - 1) / 2;
h_h_2 = H->height - h_h_1;
h_h_1 = -h_h_1;
}
if (H->width == 0)
{
h_w_1 = 0;
h_w_2 = 0;
direction = 2;//进行
b2b9
垂直方向卷积
}
else
{
h_w_1 = (H->width - 1) / 2;
h_w_2 = H->width - h_w_1;
h_w_1 = -h_w_1;
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
sum_data = 0;
switch (direction)
{
case 0://水平卷积+垂直卷积
for (int h_h = h_h_1; h_h < h_h_2; h_h++)
{
for (int h_w = h_w_1; h_w < h_w_2; h_w++)
{
if ((i + h_h >= 0 && i + h_h < height) || (j + h_w >= 0 && j + h_w < width))//待处理的像素的行或者列在边界内,或者行和列都在边界内
{
//对于边界的处理,按照replicate规则,即延长边界像素值=边界像素值
if (i + h_h < 0)
src_data = src->data[0 * width + j];
else if (i + h_h >= height)
src_data = src->data[(height - 1) * width + j];
else if (j + h_w < 0)
src_data = src->data[i * width + 0];
else if (j + h_w >= width)
src_data = src->data[i * width + width - 1];
else
src_data = src->data[(i + h_h) * width + (j + h_w)];
}
else//待处理的像素的行和列都不在边界内
{
}
sum_data = sum_data + src_data * H->data[(h_h - h_h_1) * H->width + (h_w - h_w_1)];
}
}
case 1 ://水平卷积
for (int h_w = h_w_1; h_w < h_w_2; h_w++)
{
if (j + h_w < 0)
src_data = src->data[i * width + 0];
else if (j + h_w >= width)
src_data = src->data[i * width + width - 1];
else
src_data = src->data[i * width + (j + h_w)];
sum_data = sum_data + src_data * H->data[(h_w - h_w_1)];
}
break;
case 2://垂直卷积
for (int h_h = h_h_1; h_h < h_h_2; h_h++)
{
if (i + h_h < 0)
src_data = src->data[0 * width + j];
else if (i + h_h >= height)
src_data = src->data[(height - 1) * width + j];
else
src_data = src->data[(i + h_h) * width + j];
sum_data = sum_data + src_data * H->data[(h_h - h_h_1)];
}
}
filter->data[i * width + j] = sum_data;
}
}
}
实例:
int main()
{
matlab_canny::canny_data src, fff, HH;
matlab_canny m_canny;
float data[10 * 10];
float H[4] = { -2, -1, 4, 3 };
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
data[i * 10 + j] = i+1;
}
}
float filter[10 * 10];
src.height = 10;
src.width = 10;
src.data = data;
fff.height = 10;
fff.width = 10;
fff.data = filter;
HH.height = 0;
HH.width = 4;
HH.data = H;
m_canny.matlab_imfilter(&src, &fff, &HH);
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
printf("%f ", fff.data[i * 10 + j]);
}
printf("\n");
}
1.函数模板
B=imfilter(A,H,options);
(a) -Boundary
options
%
% X
Input array values outside thebounds of the array
% are implicitly assumed tohave the value X.
When no
% boundary option isspecified, IMFILTER uses X = 0.
%
% 'symmetric'
Input array values outside the bounds of thearray
% are computed bymirror-reflecting the array across
% the array border.
%
% 'replicate'
Input array values outside the bounds of thearray
% are assumed to equal thenearest array border
% value.(图片边界处像素的计算,采用将边界向外延长n=((size(H,1)+1)/2-1)个像素,延长的像素值为对应边界像素值。)
%
% 'circular'
Input array values outside the bounds of thearray
% are computed by implicitlyassuming the input array
% is periodic.
(b) Output size options
% (Output size options for IMFILTER areanalogous to the SHAPE option
% in the functions CONV2 and FILTER2.)
%
% 'same'
The output array is the same size as theinput
% array.
This is the default behavior when no output
% size options are specified.
%
% 'full'
The output array is the full filteredresult, and so
% is larger than the inputarray.
%
c) Correlation and convolution
%
% 'corr'
IMFILTER performs multidimensional filteringusing
% correlation, which is thesame way that FILTER2
% performs filtering.
When no correlation or
% convolution option isspecified, IMFILTER uses
% correlation.(滤波模板H不发生变换,直接进行模板计算)
%
% 'conv'
IMFILTER performs multidimensionalfiltering using
% convolution.
(滤波模板H发生180度旋转(先行转置,后列转置),之后进行模板计算)
%
‘Conv’详解:卷积窗为,180度旋转后==》
2.滤波/卷积过程
线性滤波可以用卷积实现,输出图像的像素值是输入图像对应像素及其邻域像素的线性加权,权重矩阵称为卷积窗。图20.56说明了图像卷积的过程,图像I为,卷积窗为。现在要计算像素点(2,4)卷积后的结果,卷积过程如下:
(1)将卷积窗相对于中心旋转180度,得;
(2)将卷积窗的中心滑动至(2,4);
(3)计算(2,4)的邻域与卷积窗对应像素的积,并求和,结果即为卷积后(2,4)处的像素值。
因此(2,4)的卷积结果为1´2 + 8´9+ 15´4 + 7´7 + 5´14 + 16´3 + 6´13 + 1´20 +8´22
= 575。
卷积窗滑动过程中有可能超出图像的边界,如图20.57所示。对于图像边界外的像素值,一般有两种方法处理,其一是用0填充(图20.58),其二是用最邻近的边界值填充(图20.59)。
图20.56 图像卷积过程 图20.57 图像卷积越界
图20.58 卷积过程的边界处理,0填充 图20.59 卷积过程的边界处理,邻域填充
相关与卷积类似,输出图像的像素值是输入图像对应像素及其邻域的线性加权,权重矩阵称为相关窗。相关与卷积的唯一差别是,不需要对相关窗口旋转。图像相关也需要考虑到边界的处理,处理方式与卷积相同。
3.注意事项,
当前处理像素f(i,j)在卷积窗口的对应位置为,i=size(H,1)+1/2;j=size(H,2)+1/2;
即,(a)当H尺寸为7*1时,i=(7+1)/2=4;(该值对应matlab时=4;对应C时=3)
(b)当H尺寸为6*1时,i=(6+1)/2=3;(该值对应matlab时=3;对应C时=2)
H=[h1,h2,h3,h4,h5,h6,h7]; F(i)=f(i-3)*h1+ f(i-2)*h2+f(i-1)*h3+ f(i)*h4+f(i+1)*h5+ f(i+2)*h6+f(i+3)*f7;
H=[h1,h2,h3,h4,h5,h6]; F(i)= f(i-2)*h1+f(i-1)*h2+ f(i)*h3+ f(i+1)*h4+f(i+2)*h5+f(i+3)*f6;
C++转换:
//matlab_canny.h
//将matlab中的edge(I,'canny')函数转换为C++代码
class matlab_canny{
public:
struct canny_data{
int height;
int width;
float* data;
};
//对图像src进行水平方向/垂直方向的滤波 ,仅对一个方向进行卷积
//src --- 原始图像
//filter -- 滤波后图像
//H -- 卷积窗口
//其中相对于matlab中的imfilter来说,对应的option为'corr'+'replicate'
void matlab_imfilter(canny_data* src, canny_data* filter, canny_data* H);
};
//matlab_canny.cpp
#include"canny_matlab.h"
void matlab_canny::matlab_imfilter(canny_data* src, canny_data* filter, canny_data* H)
{
int height, width, h_h_1, h_h_2, h_w_1, h_w_2;
float sum_data, src_data;
height = src->height;
width = src->width;
int direction = 0;//进行水平和垂直方向卷积 direction-卷积方向:0--水平+垂直;1--水平; 2--垂直
if (H->height == 0 && H->width == 0)
{
printf("ERROR:卷积窗口H大小为0!");
}
if (H->height == 0)
{
h_h_1 = 0;
h_h_2 = 0;
direction = 1;//进行水平方向卷积
}
else
{
h_h_1 = (H->height - 1) / 2;
h_h_2 = H->height - h_h_1;
h_h_1 = -h_h_1;
}
if (H->width == 0)
{
h_w_1 = 0;
h_w_2 = 0;
direction = 2;//进行
b2b9
垂直方向卷积
}
else
{
h_w_1 = (H->width - 1) / 2;
h_w_2 = H->width - h_w_1;
h_w_1 = -h_w_1;
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
sum_data = 0;
switch (direction)
{
case 0://水平卷积+垂直卷积
for (int h_h = h_h_1; h_h < h_h_2; h_h++)
{
for (int h_w = h_w_1; h_w < h_w_2; h_w++)
{
if ((i + h_h >= 0 && i + h_h < height) || (j + h_w >= 0 && j + h_w < width))//待处理的像素的行或者列在边界内,或者行和列都在边界内
{
//对于边界的处理,按照replicate规则,即延长边界像素值=边界像素值
if (i + h_h < 0)
src_data = src->data[0 * width + j];
else if (i + h_h >= height)
src_data = src->data[(height - 1) * width + j];
else if (j + h_w < 0)
src_data = src->data[i * width + 0];
else if (j + h_w >= width)
src_data = src->data[i * width + width - 1];
else
src_data = src->data[(i + h_h) * width + (j + h_w)];
}
else//待处理的像素的行和列都不在边界内
{
}
sum_data = sum_data + src_data * H->data[(h_h - h_h_1) * H->width + (h_w - h_w_1)];
}
}
case 1 ://水平卷积
for (int h_w = h_w_1; h_w < h_w_2; h_w++)
{
if (j + h_w < 0)
src_data = src->data[i * width + 0];
else if (j + h_w >= width)
src_data = src->data[i * width + width - 1];
else
src_data = src->data[i * width + (j + h_w)];
sum_data = sum_data + src_data * H->data[(h_w - h_w_1)];
}
break;
case 2://垂直卷积
for (int h_h = h_h_1; h_h < h_h_2; h_h++)
{
if (i + h_h < 0)
src_data = src->data[0 * width + j];
else if (i + h_h >= height)
src_data = src->data[(height - 1) * width + j];
else
src_data = src->data[(i + h_h) * width + j];
sum_data = sum_data + src_data * H->data[(h_h - h_h_1)];
}
}
filter->data[i * width + j] = sum_data;
}
}
}
实例:
int main()
{
matlab_canny::canny_data src, fff, HH;
matlab_canny m_canny;
float data[10 * 10];
float H[4] = { -2, -1, 4, 3 };
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
data[i * 10 + j] = i+1;
}
}
float filter[10 * 10];
src.height = 10;
src.width = 10;
src.data = data;
fff.height = 10;
fff.width = 10;
fff.data = filter;
HH.height = 0;
HH.width = 4;
HH.data = H;
m_canny.matlab_imfilter(&src, &fff, &HH);
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
printf("%f ", fff.data[i * 10 + j]);
}
printf("\n");
}
相关文章推荐
- canny边缘提取之二 高斯图像滤波
- canny边缘提取之四 双阈值边缘检测及连接 matlab函数转C++
- 【MATLAB图像处理3】 canny边缘检测 (附源码)
- Matlab实现:图像边缘提取
- 身份证号码图像提取--基于canny边缘检测的连通域检测算法
- matlab 图像高斯平滑滤波处理(转载)
- matlab图像特征提取--边缘,角点,SURF检测
- 图像边缘检测及提取方法总结(含Matlab代码)
- 【MATLAB图像处理3】 canny边缘检测 (附源码)
- 局部边缘保持滤波(LEP)高动态范围图像HDR压缩 matlab程序(一)
- canny边缘提取之三 双阈值计算 matlab中edge(I,'canny')函数中sselectThresholds()函数的C++转换
- 【Matlab学习笔记】【图像滤波去噪】高斯平滑滤波
- 局部边缘保持滤波(LEP)高动态范围图像HDR压缩 matlab程序(二)
- matlab实现图像滤波——高斯滤波
- matlab laplacian of gaussian(拉普拉斯高斯) 图像滤波
- 基于L0边缘保持滤波的图像融合 matlab代码
- OpenCV学习笔记1:使用Camera获取图像,并用Canny转换成边缘图,并支持鼠标点击保存图片
- 局部边缘保持滤波(LEP)高动态范围图像HDR压缩 matlab程序(一)
- 从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中
- 局部边缘保持滤波(LEP)高动态范围图像HDR压缩 matlab程序(二)