1+ #include < iostream>
2+ #include < stdio.h>
3+ #include < cblas.h>
4+ #include < opencv2/opencv.hpp>
5+
6+ using namespace std ;
7+ using namespace cv ;
8+
9+ // 使用OpenMp和OpenBlas加速filter2D(灰度图),且卷积核的长宽相等,这里实现的是长宽均为3的卷积核
10+ // RGB转化为灰度图
11+ Mat speed_rgb2gray (Mat src) {
12+ Mat dst (src.rows , src.cols , CV_8UC1);
13+ #pragma omp parallel for num_threads(4)
14+ for (int i = 0 ; i < src.rows ; i++) {
15+ for (int j = 0 ; j < src.cols ; j++) {
16+ dst.at <uchar>(i, j) = ((src.at <Vec3b>(i, j)[0 ] << 18 ) + (src.at <Vec3b>(i, j)[0 ] << 15 ) + (src.at <Vec3b>(i, j)[0 ] << 14 ) +
17+ (src.at <Vec3b>(i, j)[0 ] << 11 ) + (src.at <Vec3b>(i, j)[0 ] << 7 ) + (src.at <Vec3b>(i, j)[0 ] << 7 ) + (src.at <Vec3b>(i, j)[0 ] << 5 ) +
18+ (src.at <Vec3b>(i, j)[0 ] << 4 ) + (src.at <Vec3b>(i, j)[0 ] << 2 ) +
19+ (src.at <Vec3b>(i, j)[1 ] << 19 ) + (src.at <Vec3b>(i, j)[1 ] << 16 ) + (src.at <Vec3b>(i, j)[1 ] << 14 ) + (src.at <Vec3b>(i, j)[1 ] << 13 ) +
20+ (src.at <Vec3b>(i, j)[1 ] << 10 ) + (src.at <Vec3b>(i, j)[1 ] << 8 ) + (src.at <Vec3b>(i, j)[1 ] << 4 ) + (src.at <Vec3b>(i, j)[1 ] << 3 ) + (src.at <Vec3b>(i, j)[1 ] << 1 ) +
21+ (src.at <Vec3b>(i, j)[2 ] << 16 ) + (src.at <Vec3b>(i, j)[2 ] << 15 ) + (src.at <Vec3b>(i, j)[2 ] << 14 ) + (src.at <Vec3b>(i, j)[2 ] << 12 ) +
22+ (src.at <Vec3b>(i, j)[2 ] << 9 ) + (src.at <Vec3b>(i, j)[2 ] << 7 ) + (src.at <Vec3b>(i, j)[2 ] << 6 ) + (src.at <Vec3b>(i, j)[2 ] << 5 ) + (src.at <Vec3b>(i, j)[2 ] << 4 ) + (src.at <Vec3b>(i, j)[2 ] << 1 ) >> 20 );
23+ }
24+ }
25+ return dst;
26+ }
27+
28+ // A增加Pad的运算
29+ void get_Pad (int pad_Height, int pad_Width, int row, int col, float *A_pad, float *A) {
30+ int pad_x = pad_Height - row >> 1 ;
31+ int pad_y = pad_Width - col >> 1 ;
32+ printf (" pad_x: %d pad_y: %d\n " , pad_x, pad_y);
33+ for (int i = 0 ; i < pad_Height; i++) {
34+ for (int j = 0 ; j < pad_Width; j++) {
35+ int index = i * pad_Height + j;
36+ if (i <= pad_x || i + pad_x > pad_Height) {
37+ A_pad[index] = 0 ;
38+ }
39+ else {
40+ if (j <= pad_y || j + pad_y > pad_Width) {
41+ A_pad[index] = 0 ;
42+ }
43+ else {
44+ A_pad[index] = A[(i - pad_x) * row + j - pad_y];
45+ }
46+ }
47+ }
48+ }
49+ }
50+
51+
52+
53+ int main () {
54+ Mat src = cv::imread (" F:\\ 1.jpg" );
55+ src = speed_rgb2gray (src);
56+ int row = src.rows ;
57+ int col = src.cols ;
58+ // 将原始的
59+ float *A = new float [row * col];
60+ for (int i = 0 ; i < row * col; i++) {
61+ int x = i / row;
62+ int y = i % row;
63+ A[i] = src.at <float >(x, y);
64+ }
65+ const int KernelHeight = 3 ;
66+ const int KernelWidth = 3 ;
67+ float B[KernelHeight * KernelWidth] = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 };
68+ // 卷积核参数初始化为
69+ const int pad = (KernelHeight - 1 ) / 2 ; // 需要pad的长度
70+ const int stride = 1 ; // 卷积核滑动的步长
71+ // 计算卷积输出矩阵的长宽
72+ const int OutHeight = (row - KernelHeight + 2 * pad) / stride + 1 ;
73+ const int OutWidth = (col - KernelWidth + 2 * pad) / stride + 1 ;
74+ // 计算pad_A
75+ const int pad_Height = row + 2 * pad;
76+ const int pad_Width = col + 2 * pad;
77+ float *A_pad = new float [pad_Height * pad_Width];
78+ get_Pad (pad_Height, pad_Width, row, col, A_pad, A);
79+
80+ }
0 commit comments