-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconv2
71 lines (61 loc) · 2.19 KB
/
conv2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
https://blog.csdn.net/u014267567/article/details/53842915
https://blog.csdn.net/xiaoyanghijk/article/details/52073162 关于full\same\valid如何来的
OpenCV实现MATLAB的conv2
Matlab中的conv2计算的是卷积,不是相关,即需要将卷积核顺时针旋转180度,
并且基准心是核的中心
在full模式下,same模式下自动填充0
在valid模式下,直接进行卷积
而在opencv下,卷积其实不是卷积,而且相关,默认是填充0,默认模式是same,所以对source图像进行填充0就是full,进行裁剪就是valid
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
enum ConvolutionType {
/* Return the full convolution, including border */
CONVOLUTION_FULL,
/* Return only the part that corresponds to the original image */
CONVOLUTION_SAME,
/* Return only the submatrix containing elements that were not influenced by the border */
CONVOLUTION_VALID
};
Mat conv2(const Mat &img, const Mat& ikernel, ConvolutionType type)
{
Mat dest;
Mat kernel;
flip(ikernel,kernel,-1);
Mat source = img;
if(CONVOLUTION_FULL == type)
{
source = Mat();
const int additionalRows = kernel.rows-1, additionalCols = kernel.cols-1;
copyMakeBorder(img, source, (additionalRows+1)/2, (additionalRows)/2, (additionalCols+1)/2, (additionalCols)/2, BORDER_CONSTANT, Scalar(0));
}
//Point anchor(kernel.cols - kernel.cols/2 - 1, kernel.rows - kernel.rows/2 - 1);
Point anchor(-1, -1);
int borderMode = BORDER_CONSTANT;
filter2D(source, dest, img.depth(), kernel, anchor, 0, borderMode); //same
if(CONVOLUTION_VALID == type)
{
dest = dest.colRange((kernel.cols-1)/2, dest.cols - kernel.cols/2).rowRange((kernel.rows-1)/2, dest.rows - kernel.rows/2);
}
return dest;
}
int main()
{
double a[81];
double b[25];
for(int i = 1; i <= 81; i++)
a[i-1] = i;
for(int i = 1; i <= 25; i++)
b[i-1] = 0.5;
Mat A(9,9,CV_64F,a);
Mat B(5,5,CV_64F, b);
cout << A << endl << endl;
cout << B << endl << endl;
Mat C = conv2(A,B,CONVOLUTION_VALID);
Mat D = conv2(A,B,CONVOLUTION_FULL);
cout<<"valid:"<<endl<<C<<endl<<endl<<"full:"<<endl<<D<<endl;
return 0;
}