图像处理之基础---二维卷积c实现
2014-08-31 00:00
477 查看
http://wenku.baidu.com/link?url=4RzdmvP9sdaaUbnVEW4OyBD-g67wIOiJjKFF3Le_bu7hIiBS7I6hMcDmCXrQwsHvrsPvR4666J1qF1ff5JVvd2xL8rzL9N81qvL-1dwkiim
特别说明一下,根据那本书所说,这算的是线性卷积。还有种卷积叫循环卷积。
(1)、二维卷积运算之C语言实现
若x为N1*M1的二维信号,y为N2*M2的二维信号,则卷积为(N1+N2-1)*(M1+M2-1)的信号
z(i,j)=∑ ∑ x(m,n)y(i
-m,j-n)
........m n
#define N1 8 信号1的行
#define M1 10 信号1的列
#define N2 2 信号2的行
#define M2 3 信号2的列
void juanji(int x[N1][M1],int y[N2][M2],int z[N1+N2-1][M1+M2-1])
{
int i,j;
int n,m;
for(i=0;i<N1+N2-1;i++)
for(j=0;j<M1+M2-1;j++)
{
int temp=0;
for(m=0;m<N1;m++)
for(n=0;n<M1;n++)
if((i-m)>=0&&(i-m)<N2&&(j-n)>=0&&(j-n)<M2)
temp+=x[m]
*y[i-m][j-n];
z[i][j]=temp;
}
}
http://www.netfoucs.com/article/linger2012liu/76164.html#
(2)、
看卷积神经网络的时候,发现代码中计算卷积是通过矩阵乘法来计算的。
搜了一下发现网上这方面的资料很少。刚开始找中文的,找到两个。
http://blog.csdn.net/anan1205/article/details/12313593
http://zhongcheng0519.blog.163.com/blog/static/161690688201122141335874/
看了之后,还是不懂。然后开始搜英文的。
最后搜到两个挺有用的,一个是维基百科对Toeplitz的介绍,一个是图像处理的书籍。
http://en.wikipedia.org/wiki/Toeplitz_matrix
Toeplitzmatrix
http://books.google.com.hk/books?id=JeDGn6Wmf1kC&pg=PA110&lpg=PA110&dq=2-D+convolution+as+a+matrix-matrix+multiplication&source=bl&ots=kdxpa_C-Ax&sig=afy2CMZHEkoV-7ymwcBFMwvRB8U&hl=zh-CN&sa=X&ei=wjVOU_jkEMypkgW09IDwCQ&ved=0CEEQ6AEwAg#v=onepage&q=2-D%20convolution%20as%20a%20matrix-matrix%20multiplication&f=false
下面拿一个例子来讲解一下,怎么把卷积运算转换为矩阵乘法运算。其实是那本书的一个例子。
X=[
1 2
3 4]
h= [
5 6
7 8]
其中,X是卷积核。
1 X的每一行生成一个小矩阵
第一行[1 2],
首先插入1,得[1 0],补的0的数量等于H的列数-1。这里,h的列数是2,故补2-1=1个0。
再右移一位插入2,得出第二行,得[10
2 1]
再右移一位得出第三行,得
[
1 0
2 1
0 2]。把这个等于H0。
第二行[3 4],同理得
H1=[
3 0
4 3
0 4]。
观察这个过程,明显是将上一行右移再插入新的值到第一个列从而得出下一行。
我们可以假设第0行是[0 0],最后一行是[0 0]。
[
0 0
3 0
4 3
0 4
0 0
]就可以看到规律。
2 算出Toeplitz矩阵
A= [
H0 O
H1 H0
O H1],其中O是一个由若干个0组成的小矩阵。
这个例子中,
A=
[
1 0 0 0
2 1 0 0
0 2 0 0
3 0 1 0
4 3 2 1
0 4 0 2
0 0 3 0
0 0 4 3
0 0 0 4
]
3 将h变为列向量,按照行的顺序来,得
[
5
6
7
8
]
4 将Toeplitz矩阵和列向量相乘,得
[
5
16
12
22
60
40
21
52
32
]
整理为矩阵得,
[
5 16 12
22 60 40
21 52 32
]。
下面来验证一下,
首先将卷积核旋转180度,得
[
4 3
2 1
]
从左上开始,滑动算点积,得
5*1= 5,
5*2+ 6*1 = 16,
6*2= 12,
5*3+7*1=22,
5*4+6*3+7*2+8*1=60,
。。。。。。
正确!!!
特别说明一下,根据那本书所说,这算的是线性卷积。还有种卷积叫循环卷积。
值得注意的是:
第一种方法是根据定义来的,浙大、北大的教案都是这种方法,
第二种是根据几何定义来求得
其实有第三种方法:根据原理 多项式加权相乘求和,跟第二种类似
http://www.netfoucs.com/article/linger2012liu/76164.html#
(4)、
/article/1221447.html
// 计算卷积矩阵的函数
function ConvolutionMatrix(input, matrix, divisor, offset){
// 创建一个输出的 imageData 对象
var output = document.createElement("canvas")
.getContext('2d').createImageData(input);
var w = input.width, h = input.height;
var iD = input.data, oD = output.data;
var m = matrix;
// 对除了边缘的点之外的内部点的 RGB 进行操作,透明度在最后都设为 255
for (var y = 1; y < h-1; y += 1) {
for (var x = 1; x < w-1; x += 1) {
for (var c = 0; c < 3; c += 1) {
var i = (y*w + x)*4 + c;
oD[i] = offset
+(m[0]*iD[i-w*4-4] + m[1]*iD[i-w*4] + m[2]*iD[i-w*4+4]
+ m[3]*iD[i-4] + m[4]*iD[i] + m[5]*iD[i+4]
+ m[6]*iD[i+w*4-4] + m[7]*iD[i+w*4] + m[8]*iD[i+w*4+4])
/ divisor;
}
oD[(y*w + x)*4 + 3] = 255; // 设置透明度
}
}
return output;
}
(5)、
http://zhidao.baidu.com/question/50407836.html?fr=qrl&index=3&qbl=topic_question_3&word=%BE%D8%D5%F3%BE%ED%BB%FD
code:
卷积的应用太广泛了:比如说 考试舞弊找代考的,把两个人的照片进行卷积就,类似同一个人了
特别说明一下,根据那本书所说,这算的是线性卷积。还有种卷积叫循环卷积。
(1)、二维卷积运算之C语言实现
若x为N1*M1的二维信号,y为N2*M2的二维信号,则卷积为(N1+N2-1)*(M1+M2-1)的信号
z(i,j)=∑ ∑ x(m,n)y(i
-m,j-n)
........m n
#define N1 8 信号1的行
#define M1 10 信号1的列
#define N2 2 信号2的行
#define M2 3 信号2的列
void juanji(int x[N1][M1],int y[N2][M2],int z[N1+N2-1][M1+M2-1])
{
int i,j;
int n,m;
for(i=0;i<N1+N2-1;i++)
for(j=0;j<M1+M2-1;j++)
{
int temp=0;
for(m=0;m<N1;m++)
for(n=0;n<M1;n++)
if((i-m)>=0&&(i-m)<N2&&(j-n)>=0&&(j-n)<M2)
temp+=x[m]
*y[i-m][j-n];
z[i][j]=temp;
}
}
http://www.netfoucs.com/article/linger2012liu/76164.html#
(2)、
看卷积神经网络的时候,发现代码中计算卷积是通过矩阵乘法来计算的。
搜了一下发现网上这方面的资料很少。刚开始找中文的,找到两个。
http://blog.csdn.net/anan1205/article/details/12313593
http://zhongcheng0519.blog.163.com/blog/static/161690688201122141335874/
看了之后,还是不懂。然后开始搜英文的。
最后搜到两个挺有用的,一个是维基百科对Toeplitz的介绍,一个是图像处理的书籍。
http://en.wikipedia.org/wiki/Toeplitz_matrix
Toeplitzmatrix
http://books.google.com.hk/books?id=JeDGn6Wmf1kC&pg=PA110&lpg=PA110&dq=2-D+convolution+as+a+matrix-matrix+multiplication&source=bl&ots=kdxpa_C-Ax&sig=afy2CMZHEkoV-7ymwcBFMwvRB8U&hl=zh-CN&sa=X&ei=wjVOU_jkEMypkgW09IDwCQ&ved=0CEEQ6AEwAg#v=onepage&q=2-D%20convolution%20as%20a%20matrix-matrix%20multiplication&f=false
下面拿一个例子来讲解一下,怎么把卷积运算转换为矩阵乘法运算。其实是那本书的一个例子。
X=[
1 2
3 4]
h= [
5 6
7 8]
其中,X是卷积核。
1 X的每一行生成一个小矩阵
第一行[1 2],
首先插入1,得[1 0],补的0的数量等于H的列数-1。这里,h的列数是2,故补2-1=1个0。
再右移一位插入2,得出第二行,得[10
2 1]
再右移一位得出第三行,得
[
1 0
2 1
0 2]。把这个等于H0。
第二行[3 4],同理得
H1=[
3 0
4 3
0 4]。
观察这个过程,明显是将上一行右移再插入新的值到第一个列从而得出下一行。
我们可以假设第0行是[0 0],最后一行是[0 0]。
[
0 0
3 0
4 3
0 4
0 0
]就可以看到规律。
2 算出Toeplitz矩阵
A= [
H0 O
H1 H0
O H1],其中O是一个由若干个0组成的小矩阵。
这个例子中,
A=
[
1 0 0 0
2 1 0 0
0 2 0 0
3 0 1 0
4 3 2 1
0 4 0 2
0 0 3 0
0 0 4 3
0 0 0 4
]
3 将h变为列向量,按照行的顺序来,得
[
5
6
7
8
]
4 将Toeplitz矩阵和列向量相乘,得
[
5
16
12
22
60
40
21
52
32
]
整理为矩阵得,
[
5 16 12
22 60 40
21 52 32
]。
下面来验证一下,
首先将卷积核旋转180度,得
[
4 3
2 1
]
从左上开始,滑动算点积,得
5*1= 5,
5*2+ 6*1 = 16,
6*2= 12,
5*3+7*1=22,
5*4+6*3+7*2+8*1=60,
。。。。。。
正确!!!
特别说明一下,根据那本书所说,这算的是线性卷积。还有种卷积叫循环卷积。
值得注意的是:
第一种方法是根据定义来的,浙大、北大的教案都是这种方法,
第二种是根据几何定义来求得
其实有第三种方法:根据原理 多项式加权相乘求和,跟第二种类似
http://www.netfoucs.com/article/linger2012liu/76164.html#
(4)、
/article/1221447.html
// 计算卷积矩阵的函数
function ConvolutionMatrix(input, matrix, divisor, offset){
// 创建一个输出的 imageData 对象
var output = document.createElement("canvas")
.getContext('2d').createImageData(input);
var w = input.width, h = input.height;
var iD = input.data, oD = output.data;
var m = matrix;
// 对除了边缘的点之外的内部点的 RGB 进行操作,透明度在最后都设为 255
for (var y = 1; y < h-1; y += 1) {
for (var x = 1; x < w-1; x += 1) {
for (var c = 0; c < 3; c += 1) {
var i = (y*w + x)*4 + c;
oD[i] = offset
+(m[0]*iD[i-w*4-4] + m[1]*iD[i-w*4] + m[2]*iD[i-w*4+4]
+ m[3]*iD[i-4] + m[4]*iD[i] + m[5]*iD[i+4]
+ m[6]*iD[i+w*4-4] + m[7]*iD[i+w*4] + m[8]*iD[i+w*4+4])
/ divisor;
}
oD[(y*w + x)*4 + 3] = 255; // 设置透明度
}
}
return output;
}
(5)、
http://zhidao.baidu.com/question/50407836.html?fr=qrl&index=3&qbl=topic_question_3&word=%BE%D8%D5%F3%BE%ED%BB%FD
code:
一个5*5的图像和一个3*3的图像做卷积运算,具体过程如下: * * 函数名称: * TemplateMatchDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LPSTR lpDIBBitsBK - 指向背景DIB图像指针 * LONG lWidth - 源图像宽度(象素数) * LONG lHeight - 源图像高度(象素数) * LONG lTemplateWidth - 模板图像宽度(象素数) * LONG lTemplateHeight - 模板图像高度(象素数) * * 返回值: * BOOL - 运算成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用于对图像进行模板匹配运算。 * * 要求目标图像为255个灰度值的灰度图像。 ************************************************************************/ BOOL WINAPI TemplateMatchDIB (LPSTR lpDIBBits, LPSTR lpTemplateDIBBits, LONG lWidth, LONG lHeight, LONG lTemplateWidth,LONG lTemplateHeight) { // 指向源图像的指针 LPSTR lpSrc,lpTemplateSrc; // 指向缓存图像的指针 LPSTR lpDst; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; //循环变量 long i; long j; long m; long n; //中间结果 double dSigmaST; double dSigmaS; double dSigmaT; //相似性测度 double R; //最大相似性测度 double MaxR; //最大相似性出现位置 long lMaxWidth; long lMaxHeight; //像素值 unsigned char pixel; unsigned char templatepixel; // 图像每行的字节数 LONG lLineBytes,lTemplateLineBytes; // 暂时分配内存,以保存新图像 hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight); if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化新分配的内存,设定初始值为255 lpDst = (char *)lpNewDIBBits; memset(lpDst, (BYTE)255, lWidth * lHeight); // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * 8); lTemplateLineBytes = WIDTHBYTES(lTemplateWidth * 8); //计算dSigmaT dSigmaT = 0; for (n = 0;n < lTemplateHeight ;n++) { for(m = 0;m < lTemplateWidth ;m++) { // 指向模板图像倒数第j行,第i个象素的指针 lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m; templatepixel = (unsigned char)*lpTemplateSrc; dSigmaT += (double)templatepixel*templatepixel; } } //找到图像中最大相似性的出现位置 MaxR = 0.0; for (j = 0;j < lHeight - lTemplateHeight +1 ;j++) { for(i = 0;i < lWidth - lTemplateWidth + 1;i++) { dSigmaST = 0; dSigmaS = 0; for (n = 0;n < lTemplateHeight ;n++) { for(m = 0;m < lTemplateWidth ;m++) { // 指向源图像倒数第j+n行,第i+m个象素的指针 lpSrc = (char *)lpDIBBits + lLineBytes * (j+n) + (i+m); // 指向模板图像倒数第n行,第m个象素的指针 lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m; pixel = (unsigned char)*lpSrc; templatepixel = (unsigned char)*lpTemplateSrc; dSigmaS += (double)pixel*pixel; dSigmaST += (double)pixel*templatepixel; } } //计算相似性 R = dSigmaST / ( sqrt(dSigmaS)*sqrt(dSigmaT)); //与最大相似性比较 if (R > MaxR) { MaxR = R; lMaxWidth = i; lMaxHeight = j; } } } //将最大相似性出现区域部分复制到目标图像 for (n = 0;n < lTemplateHeight ;n++) { for(m = 0;m < lTemplateWidth ;m++) { lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m; lpDst = (char *)lpNewDIBBits + lLineBytes * (n+lMaxHeight) + (m+lMaxWidth); *lpDst = *lpTemplateSrc; } } // 复制图像 memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight); // 释放内存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE; }Top
这是模板匹配的代码, 里面用的就是时域卷积的算法。 同时,时域的卷积就是频域的乘积, 可以把时域的图转化成频域,相乘。 ps 卷积需要补位, a ,b l >= a+b-1; http://wenku.baidu.com/link?url=N_AvksJPpds6tlT7uGKE896ByVDH7n8olJjYiCwoqrWgUIoAA2KLVfUI-OSBYYp3j0jA6kOAYCsh4Y19IPYoG71YS2lrNgQcHUMJumYuk2O (6)、卷积的各种优化 包括二维转一维 http://bbs.csdn.net/topics/30472434
卷积的应用太广泛了:比如说 考试舞弊找代考的,把两个人的照片进行卷积就,类似同一个人了
相关文章推荐
- 图像处理之基础---二维卷积运算原理剖析
- 2.深度学习FPGA实现基础知识17(图像处理卷积运算 矩阵卷积)
- 图像处理之基础---卷积及其快速算法的C++实现
- 深度学习FPGA实现基础知识17(图像处理卷积运算 矩阵卷积)
- 深度学习FPGA实现基础知识15(Matlab图像处理“卷积”运算)
- 深度学习FPGA实现基础知识16(图像处理中任意核卷积(matlab中conv2函数)的快速实现)
- 图像处理:基础(模板、卷积运算)
- 图像处理基础之卷积
- 图像处理:基础(模板、卷积运算)
- 图像处理之基础---卷积模板简介
- 图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应)
- 图像处理:基础(模板、卷积运算)
- 图像处理:基础(模板、卷积运算)
- C++实现基础图像处理
- 图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应)
- 图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应)
- 图像处理之应用卷积一实现噪声消去
- 图像处理:基础(模板、卷积运算)
- 图像处理:基础(模板、卷积运算) .
- 图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应)