# 卷积的介绍

$(f*g)(x)=\int_{-\infty}^{\infty}f(t)g(x-t)dt$

$((\cdots((f*g)*g)\cdots)*g)(x) \rightarrow \frac 1{\sigma\sqrt{2\pi}} e^{-x^2/{\sigma^2}}$

\begin{align*} r = p\cdot q &= (a_0 b_0) \\ &+ (a_0 b_1 + a_1 b_0) x \\ &+ (a_0 b_2 + a_1 b_1+ a_2 b_0) x^2 \\ &+ (a_0 b_3 + a_1 b_2 + a_2 b_1) x^3 \\ &+ (a_1 b_3 + a_2 b_2) x^4 \\ &+ (a_2 b_3) x^5 \end{align*}

\begin{align*} (p * q)[n] &= \sum_{m=-\infty}^\infty p[m]\cdot q[n-m] \\ r[1] &= \sum_{m=0}^1 p[m]\cdot q[1-m] &&= a_0 b_1 + a_1 b_0 \\ r[2] &= \sum_{m=0}^2 p[m]\cdot q[2-m] &&= a_0 b_2 + a_1 b_1 + a_2 b_0 \\ &\cdots \end{align*}

# 卷积与图像处理

\begin{align*} && a_0 && a_1 && a_2 && a_3 && a_4 \\ && a_0b_0 && a_0b_1 && a_0b_2 && a_0b_3 \\ && && a_1b_0 && a_1b_1 && a_1b_2 && a_1b_3 \\ && && && a_2b_0 && a_2b_1 && a_2b_2 && a_2b_3 \\ && && && && a_3b_0 && a_3b_1 && a_3b_2 && a_3b_3 \\ && && && && && a_4b_0 && a_4b_1 && a_4b_2 && a_4b_3 \\ \hline && c_0 && c_1 && c_2 && c_3 && c_4 && c_5 && c_6 && c_7 \end{align*}

$\text{Dest}[i, j] = \sum_{y=-\infty}^\infty \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}[i - y, j - x]$

$\text{Dest}[i, j] = \sum_{y=\max\{0,i-r\}}^{\min\{i+r,n\}} \left( \sum_{x=\max\{0,j-r\}}^{\min\{j+r,m\}} \text{Src}[y, x] \cdot \text{Ker}[i - y, j - x] \right)$

# 高斯滤波器

\begin{align*} \text{Ker}_1[x] &= \frac 1{\sigma\sqrt{2\pi}} e^{-x^2/{\sigma^2}} \\ \text{Ker}_2[i, j] &= \frac 1{2\sigma^2\pi} e^{-(i^2+j^2)/{\sigma^2}} \end{align*}

\begin{align*} \text{Ker}_2[i, j] &= \text{Ker}_1[i] \cdot \text{Ker}_1[j] \\ \text{Dest}[i, j] &= \sum_{y=-\infty}^\infty \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}_2[i - y, j - x] \\ &= \sum_{y=-\infty}^\infty \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}_1[i-y] \cdot \text{Ker}_1[j-x]\\ &= \sum_{y=-\infty}^\infty \left( \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}_1[j-x]\right) \text{Ker}_1[i-y] \end{align*}

1 // cflags: -lopencv_highgui -lopencv_core
2
3 #include <iostream>
4 #include <cmath>
5 #include <opencv2/highgui/highgui.hpp>
6
7 using namespace cv;
8 using namespace std;
9
10 const char* title = "gaussian-filter";
11
12 Mat kernelMatrix(int radius, double sigma)
13 {
14         int d = radius * 2 + 1;
15         Mat kernel(2, d, CV_64F);
16
17         double coef = 0;
18         for(int i = 0; i <= radius; i++) {
19                 // f(x) = 1/(sigma * sqrt(2 pi)) * e ^ -x^2/(2 s^2)
20                 int dx = i - radius;
21                 double dx_2 = dx * dx;
22                 double w = pow(M_E, - dx_2 / (2 * sigma * sigma));
23
24                 coef += w;
25                 kernel.at<double>(0, i) = w;
26                 kernel.at<double>(0, d - i - 1= w;
27                 // when you used values from i to j (j>i), the sum of them is:
28                 // kernel[1, j] - (i ? kernel[1, i-1] : 0)
29                 kernel.at<double>(1, i) = coef;
30         }
31
32         for(int i = radius + 1; i < d; i++) {
33                 coef += kernel.at<double>(0, i);
34                 kernel.at<double>(1, i) = coef;
35         }
36
37         return kernel;
38 }
39
40
41 void convolution(const Mat& img, const Mat& kernel, Mat& output, bool t = true)
42 {
43         for(int y = 0, x = 0; y < img.rows; x = (++x<img.cols)? x : (y++0)) {
44                 Vec3d r(000);
45
46                 int ideal = x - int(kernel.cols / 2),
47                     ran_beg = max(ideal, 0- ideal,
48                     ran_end = min(ideal + kernel.cols, img.cols) - ideal;
49
50                 for(int i = ran_beg; i < ran_end; i++) {
51                         double weight = kernel.at<double>(0, i);
52                         Vec3b pixel = img.at<Vec3b>(y, ideal + i);
53
54                         r[0+= pixel[0* weight;
55                         r[1+= pixel[1* weight;
56                         r[2+= pixel[2* weight;
57                 }
58
59                 double coef = kernel.at<double>(1, ran_end - 1);
60                 if(ran_beg) coef -= kernel.at<double>(1, ran_beg - 1);
61
62                 output.at<Vec3b>(t?x:y, t?y:x) = Vec3b(
63                         saturate_cast<uchar>(r[0]/coef),
64                         saturate_cast<uchar>(r[1]/coef),
65                         saturate_cast<uchar>(r[2]/coef));
66         }
67 }
68
69
70 int main()
71 {
72         namedWindow(title, WINDOW_AUTOSIZE);
73
74         const int r = 10;
75
77             kernel = kernelMatrix(r, (r - 1* 0.3 + 0.8);
78
79         Mat product_v = Mat(img.cols, img.rows, img.type());
80         Mat product_h = Mat(img.rows, img.cols, img.type());
81
82         convolution(img, kernel, product_v);
83         convolution(product_v, kernel, product_h);
84
85         imshow(title, product_h);
86         for(; waitKey(0> 0;);
87
88         destroyWindow(title);
89 }

posted on 2015-08-12 00:35 Shihira 阅读(3150) 评论(0)  编辑 收藏 引用 所属分类: 图形编程

 只有注册用户登录后才能发表评论。 【推荐】100%开源！大型工业跨平台软件C++源码提供，建模，组态！ 相关文章:

• 随笔 - 12
• 文章 - 0
• 评论 - 33
• 引用 - 0

### 公告

• 大家有什么不清楚的，尽管提问，或者发邮件给我
• 由于本人的水平有限，经验不足，难免会出现错误；请各位不吝赐教，以便在今后的工作和学习中改正；
• 2012/8/1晚8:00更正了（七）和（八）中的代码；

•