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][n]*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)、

http://www.php100.com/html/program/html5/2013/0905/5441.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

卷积的应用太广泛了:比如说 考试舞弊找代考的,把两个人的照片进行卷积就,类似同一个人了

图像处理之基础---二维卷积c实现的更多相关文章

  1. 图像处理之C语言实现二维卷积

    在用C语言实现图像处理中,经常要用到二维卷积的运算,这个在matlab中是非常容易实现的,只需要conv2()就OK啦,而且速度非常的快.但是在C语言中就需要四层的for循环来实现了. 首先二维卷积的 ...

  2. 卷积神经网络(CNN)之一维卷积、二维卷积、三维卷积详解

    作者:szx_spark 由于计算机视觉的大红大紫,二维卷积的用处范围最广.因此本文首先介绍二维卷积,之后再介绍一维卷积与三维卷积的具体流程,并描述其各自的具体应用. 1. 二维卷积 图中的输入的数据 ...

  3. 二维卷积c代码

    二维卷积c代码 二维信号的卷积原理请参考另外一篇文章:http://blog.csdn.net/carson2005/article/details/43702241 这里直接给出参考代码: void ...

  4. 【转】python中的一维卷积conv1d和二维卷积conv2d

    转自:https://blog.csdn.net/qq_26552071/article/details/81178932 二维卷积conv2d 给定4维的输入张量和滤波器张量来进行2维的卷积计算.即 ...

  5. 深度学习面试题10:二维卷积(Full卷积、Same卷积、Valid卷积、带深度的二维卷积)

    目录 二维Full卷积 二维Same卷积 二维Valid卷积 三种卷积类型的关系 具备深度的二维卷积 具备深度的张量与多个卷积核的卷积 参考资料 二维卷积的原理和一维卷积类似,也有full卷积.sam ...

  6. 4.28 省选模拟赛模拟赛 最佳农场 二维卷积 NTT

    第一次遇到二维卷积 不太清楚是怎么做的. 40分暴力比对即可. 对于行为或者列为1时 容易想到NTT做快速匹配.然后找答案即可. 考虑这是一个二维的比对过程. 设\(f_{i,j}\)表示以i,j为右 ...

  7. C语言基础--二维数组

    二维数组概念: 数组中的每一个元素又是一个数组, 那么这个数组就称之为二维数组,二维数组是特殊的一维数组. 二维数组格式: 元素类型 数组名称[一维数组的个数][每个一维数组的元素个数]; 元素类型 ...

  8. Java基础--二维数组

    1.二维数组的定义 二维数组表示行列二维结构,在栈空间中的二维数组的地址指向堆空间中的一维数组,堆空间中的一维数组的地址又指向一维数组所在的内存空间. 2.二维数组的声明 二维数组声明有3种方式,推荐 ...

  9. C语言基础:二维数组 分类: iOS学习 c语言基础 2015-06-10 21:42 16人阅读 评论(0) 收藏

    二维数组和一位数组类似. 定义: 数据类型 数组名[行][列]={{ },{ }....}; 定义时,一维(行)的长度可以省略,但是二维(列)的长度不可以省略.但是访问时,一定使用双下标. 二维数组的 ...

随机推荐

  1. AtCoder Regular Contest 077 E - guruguru 线性函数 前缀和

    题目链接 题意 灯有\(m\)个亮度等级,\(1,2,...,m\),有两种按钮: 每次将亮度等级\(+1\),如\(1\rightarrow 2,2\rightarrow 3,...,m-1\rig ...

  2. 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest I. Photo Processing

    题目链接 题意 将一个升序排好的数列切成若干段,要求每段的长度\(\gt k\),对每一段中最大值与最小值的差取个最大值,问这个最大值最小是多少. 思路 二分答案 怎么check呢? dp一下. d[ ...

  3. 【转载】Outlook2010 移动数据文件到其它地方

            您可以将数据文件移到计算机的其他文件夹中.移动文件的一个原因在于可使备份更容易并且可以让默认的outlook邮件文件不在存在C盘,导致装系统不见或者文件过大而撑死了C盘.例如,如果数据 ...

  4. angular6安装

    中文 https://www.angular.cn/ 二.下载 1.安装 node.js https://nodejs.org/en/ 2.删除老angular-cli npm uninstall - ...

  5. HDU 1999 不可摸数【类似筛法求真因子和】

    不可摸数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. UVA 725 division【暴力枚举】

    [题意]:输入正整数n,用0~9这10个数字不重复组成两个五位数abcde和fghij,使得abcde/fghij的商为n,按顺序输出所有结果.如果没有找到则输出“There are no solut ...

  7. 使用putty通过证书登录Linux

    refer to: https://www.aliyun.com/jiaocheng/200196.html

  8. CentOS7安装部署jumpserver0.5

    组件说明 Jumpserver为管理后台,管理员可以通过Web页面进行资产管理.用户管理.资产授权等操作; Coco为SSH Server和Web Terminal Server.用户可以通过使用自己 ...

  9. ORACLE SQL*PLUS环境变量设置及说明

    1:查看当前用户的环境设置: SQL> define DEFINE _DATE " (CHAR) DEFINE _CONNECT_IDENTIFIER = "updb&quo ...

  10. Google开源基于Tensorflow的NLP框架重大升级

    http://weibo.com/ttarticle/p/show?id=2309404086117195475716