hihocoder #1363 图像算子

Time Limit:10000ms
Case Time Limit:1000ms
Memory Limit:256MB

Description

在图像处理的技术中,经常会用到算子与图像进行卷积运算,从而达到平滑图像或是查找边界的效果。

假设原图为H × W的矩阵A,算子矩阵为D × D的矩阵Op,则处理后的矩阵B大小为(H-D+1) × (W-D+1)。其中:

B[i][j] = ∑(A[i-1+dx][j-1+dy]*Op[dx][dy]) | (dx = 1 .. D, dy = 1 .. D), 1 ≤ i ≤ H-D+1, 1 ≤ j ≤ W-D+1

给定矩阵A和B,以及算子矩阵的边长D。你能求出算子矩阵中每个元素的值吗?

Input

第1行:3个整数,H, W, D,分别表示原图的高度和宽度,以及算子矩阵的大小。5≤H,W≤60,1≤D≤5,D一定是奇数。

第2..H+1行:每行W个整数,第i+1行第j列表示A[i][j],0≤A[i][j]≤255

接下来H-D+1行:每行W-D+1个整数,表示B[i][j],B[i][j]在int范围内,可能为负数。

 

输入保证有唯一解,并且解矩阵的每个元素都是整数。

Output

第1..D行:每行D个整数,第i行第j列表示Op[i][j]。

Sample Input
5 5 3
1 6 13 10 3
13 1 5 6 15
8 2 15 0 12
19 19 17 18 18
9 18 19 5 17
22 15 6
35 -36 51
-20 3 -32

Sample Output

0 1 0
1 -4 1
0 1 0

Solution:
  1 #include <iostream>
  2 #include <climits>
  3 #include <cmath>
  4 #include <algorithm>
  5 #include <cstdio>
  6 #include <cstring>
  7 using namespace std;
  8 int H, W, D;
  9 
 10 int **img;
 11 int **fimg;
 12 float **matrix;
 13 float *Y;
 14 float *kernel;
 15 
 16 void swapRow(int i, int j) {
 17     for (int k = 0; k < D*D; ++k) {
 18         swap(matrix[i][k], matrix[j][k]);
 19     }
 20 }
 21 
 22 void print() {
 23     for (int i = 0; i < H-D+1; ++i) {
 24         for (int j = 0; j < W-D+1; ++j) {
 25             for (int s = 0; s < D; ++s) {
 26                 for (int t = 0; t < D; ++t) {
 27                     printf("%.1f ", matrix[i*(W-D+1)+j][s*D+t]);
 28                 }
 29             }
 30             printf("= %.1f\n", Y[i*(W-D+1)+j]);
 31         }
 32     }
 33     printf("\n");
 34 
 35 } 
 36 
 37 int ftoi(float f) {
 38     return floor(f+0.01);    
 39 }
 40 
 41 void sol() {
 42     Y = new float[(H-D+1)*(W-D+1)];
 43     matrix = new float*[(H-D+1)*(W-D+1)];
 44     for (int i = 0; i < H-D+1; ++i) {
 45         for (int j = 0; j < W-D+1; ++j) {
 46             Y[i*(W-D+1)+j] = fimg[i][j];
 47             matrix[i*(W-D+1)+j] = new float[D*D];
 48             for (int s = 0; s < D; ++s) {
 49                 for (int t = 0; t < D; ++t) {
 50                     matrix[i*(W-D+1)+j][s*D+t] = img[i+s][j+t];
 51                     //printf("%d ", (int)matrix[i*(W-D+1)+j][s*D+t]);
 52                 }
 53             }
 54             //printf("= %d\n", (int)Y[i*(W-D+1)+j]);
 55         }
 56     }
 57     //print();
 58     int len = (H-D+1)*(W-D+1);
 59     for (int i = 0; i < len; ++i) {
 60         int t = i;
 61         for (; t < len; ++t) {
 62             if (matrix[t][i] != 0) {
 63                 break;
 64             }
 65         }
 66         if (t < len) {
 67             if (i != t) swapRow(i, t);
 68         }
 69         else {
 70             continue;
 71         }
 72         float d = matrix[i][i];
 73         for (int j = 0; j < D*D; ++j) {
 74             matrix[i][j] /= d;
 75         }
 76         Y[i] /= d;
 77         
 78         for (int k = i+1; k < len; ++k) {
 79             d = matrix[k][i];
 80             for (int s = i; s < D*D; ++s) {
 81                 matrix[k][s] -= d * matrix[i][s];
 82             }
 83             Y[k] -= d*Y[i];
 84         }
 85         //print();
 86     }
 87     
 88     kernel = new float[D*D];
 89     
 90     for (int i = D*D-1; i >= 0; --i) {
 91         float f = 0;
 92         for (int j = D*D-1; j > i; --j) {
 93             f += kernel[j]*matrix[i][j];
 94         }
 95         kernel[i] = Y[i]-f;
 96     }
 97     
 98     for (int i = 0; i < D*D; ++i) {
 99         printf("%d%c", ftoi(kernel[i]), i%D == D-1 ? '\n' : ' ');
100     }
101 }
102 
103 int main(int argc, char *argv[]) {
104     scanf("%d%d%d", &H, &W, &D);
105     img = new int*[H];
106     for (int i = 0; i < H; ++i) {
107         img[i] = new int[W];
108         for (int j = 0; j < W; ++j) {
109             scanf("%d", img[i] + j);
110         }
111     }
112     fimg = new int*[H-D+1];
113     for (int i = 0; i < H-D+1; ++i) {
114         fimg[i] = new int[W-D+1];
115         for (int j = 0; j < W-D+1; ++j) {
116             scanf("%d", fimg[i] + j);
117         }
118     }
119     
120     sol();
121 }

 

 
posted @ 2016-09-04 14:37  HaruHaru  阅读(259)  评论(0编辑  收藏  举报