root/snippet/image_projection/projection.c

Revision 86, 7.8 KB (checked in by aqua, 21 months ago)

roll back to revision 79

Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <math.h>
6
7#include "matrix.h"
8
9#define WIDTH  640
10#define HEIGHT 480
11
12#define INFILE  "test2.raw"
13#define OUTFILE "test2_%s.raw"
14
15typedef unsigned char uchar;
16
17static int bound_check( int x, int y ){
18
19        if( x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT )
20                return 0;
21
22        return 1;
23
24}
25
26void fwarping( uchar* dst, uchar* src, matrix* p ){
27
28        int i, j, x, y;
29        double w;
30
31        memset( dst, 0, sizeof(uchar)*WIDTH*HEIGHT );
32        if( p->row != 3 || p->col != 3 )
33                return;
34
35        for( j = 0 ; j < HEIGHT ; j++ ){
36                for( i = 0 ; i < WIDTH ; i++ ){
37                        w = p->var[2][0]*i + p->var[2][1]*j + p->var[2][2];
38
39                        x = (int)((p->var[0][0]*i + p->var[0][1]*j + p->var[0][2]) / w);
40                        y = (int)((p->var[1][0]*i + p->var[1][1]*j + p->var[1][2]) / w);
41                       
42                        if( !bound_check(x, y) )
43                                continue;
44
45                        dst[y*WIDTH+x] = src[j*WIDTH+i];
46                }
47        }
48
49}
50
51void fwarping_i( uchar* dst, uchar* src, matrix* p ){
52
53        double px, py, w;
54        int i, j, x, y;
55
56        double* pixel;
57        double* ratio;
58
59        double  wx[2], wy[2];
60
61        pixel = (double*)malloc(sizeof(double)*WIDTH*HEIGHT);
62        ratio = (double*)malloc(sizeof(double)*WIDTH*HEIGHT);
63
64        memset( pixel, 0, sizeof(double)*WIDTH*HEIGHT);
65        memset( ratio, 0, sizeof(double)*WIDTH*HEIGHT);
66
67        if( p->row != 3 || p->col != 3 )
68                return;
69
70        for( j = 0 ; j < HEIGHT ; j++ ){
71                for( i = 0 ; i < WIDTH ; i++ ){
72
73                        w = p->var[2][0]*i + p->var[2][1]*j + p->var[2][2];
74
75                        px = (p->var[0][0]*i + p->var[0][1]*j + p->var[0][2]) / w;
76                        py = (p->var[1][0]*i + p->var[1][1]*j + p->var[1][2]) / w;
77
78                        x = (int)floor(px);
79                        y = (int)floor(py);
80
81                        wx[1] = px - x;
82                        wx[0] = 1.0 - wx[1];
83
84                        wy[1] = py - y;
85                        wy[0] = 1.0 - wy[1];
86
87                        if( bound_check( x, y ) ){
88                                pixel[y*WIDTH+x]     += src[j*WIDTH+i]*wx[0]*wy[0];
89                                ratio[y*WIDTH+x]     += wx[0]*wy[0];
90                        }
91
92                        if( bound_check( x+1, y ) ){
93                                pixel[y*WIDTH+(x+1)] += src[j*WIDTH+i]*wx[1]*wy[0];
94                                ratio[y*WIDTH+(x+1)] += wx[1]*wy[0];
95                        }
96
97                        if( bound_check( x, y+1 ) ){
98                                pixel[(y+1)*WIDTH+x] += src[j*WIDTH+i]*wx[0]*wy[1];
99                                ratio[(y+1)*WIDTH+x] += wx[0]*wy[1];
100                        }
101
102                        if( bound_check( x+1, y+1 ) ){
103                                pixel[(y+1)*WIDTH+(x+1)] += src[j*WIDTH+i]*wx[1]*wy[1];
104                                ratio[(y+1)*WIDTH+(x+1)] += wx[1]*wy[1];
105                        }
106
107                }
108
109        }       
110        for( j = 0 ; j < HEIGHT ; j++ )
111                for( i = 0 ; i < WIDTH ; i++ )
112                        dst[j*WIDTH+i] = (uchar)round(pixel[j*WIDTH+i]/ratio[j*WIDTH+i]);
113               
114        free(ratio);
115        free(pixel);
116
117}
118
119void bwarping( uchar* dst, uchar* src, matrix* p ){
120
121        double w;
122
123        int i, j, x, y;
124
125        matrix* inv = matrix_inv(p);
126
127        for( j = 0 ; j < HEIGHT ; j++ ){
128                for( i = 0 ; i < WIDTH ; i++ ){
129                        w = inv->var[2][0]*i + inv->var[2][1]*j + inv->var[2][2];
130
131                        x = (int)((inv->var[0][0]*i + inv->var[0][1]*j + inv->var[0][2])/w);
132                        y = (int)((inv->var[1][0]*i + inv->var[1][1]*j + inv->var[1][2])/w);
133                       
134                        if( !bound_check(x, y) )
135                                continue;
136
137                        dst[j*WIDTH+i] = src[y*WIDTH+x];
138                }
139        }
140        matrix_free(inv);
141}
142
143void bwarping_i( uchar* dst, uchar* src, matrix* p ){
144
145        double w, pixel, ratio, px, py;
146
147        double wx[2];
148        double wy[2];
149
150        int i, j, x, y;
151
152        matrix* inv = matrix_inv(p);
153
154        for( j = 0 ; j < HEIGHT ; j++ ){
155                for( i = 0 ; i < WIDTH ; i++ ){
156                        ratio = pixel = 0.0;
157                        w = inv->var[2][0]*i + inv->var[2][1]*j + inv->var[2][2];
158
159                        px = (inv->var[0][0]*i + inv->var[0][1]*j + inv->var[0][2]) / w;
160                        py = (inv->var[1][0]*i + inv->var[1][1]*j + inv->var[1][2]) / w;
161                       
162                        wx[1] = px - floor(px);
163                        wx[0] = 1.0 - wx[1];
164
165                        wy[1] = py - floor(py);
166                        wy[0] = 1.0 - wy[1];
167
168                        x = floor(px);
169                        y = floor(py);
170
171                        if( bound_check(x, y) ){
172                                pixel += wx[0]*wy[0]*src[y*WIDTH+x];
173                                ratio += wx[0]*wy[0];
174                        }
175                        if( bound_check(x+1, y) ){
176                                pixel += wx[1]*wy[0]*src[y*WIDTH+x+1];
177                                ratio += wx[1]*wy[0];
178                        }
179                        if( bound_check(x, y+1) ){
180                                pixel += wx[0]*wy[1]*src[(y+1)*WIDTH+x];
181                                ratio += wx[0]*wy[1];
182                        }
183                        if( bound_check(x+1, y+1) ){
184                                pixel += wx[1]*wy[1]*src[(y+1)*WIDTH+x+1];
185                                ratio += wx[1]*wy[1];
186                        }
187                        dst[j*WIDTH+i] = (uchar)floor( pixel/ratio + 0.5 );
188
189                }
190
191        }
192        matrix_free(inv);
193
194}
195
196matrix* projection_matrix( double* x, double* y, double* _x, double* _y ){
197
198        matrix* a;
199        matrix* b;
200        matrix* c;
201       
202        matrix* a_inv;
203        matrix* projection;
204       
205        a = matrix_new( 8, 8 );
206        b = matrix_new( 8, 1 );
207
208        a->var[0][0] = x[0];
209        a->var[0][1] = y[0];
210        a->var[0][2] = 1.0;
211        a->var[0][6] = -1 * _x[0] * x[0];
212        a->var[0][7] = -1 * _x[0] * y[0];
213       
214        a->var[1][0] = x[1];
215        a->var[1][1] = y[1];
216        a->var[1][2] = 1.0;
217        a->var[1][6] = -1 * _x[1] * x[1];
218        a->var[1][7] = -1 * _x[1] * y[1];
219       
220        a->var[2][0] = x[2];
221        a->var[2][1] = y[2];
222        a->var[2][2] = 1.0;
223        a->var[2][6] = -1 * _x[2] * x[2];
224        a->var[2][7] = -1 * _x[2] * y[2];
225       
226        a->var[3][0] = x[3];
227        a->var[3][1] = y[3];
228        a->var[3][2] = 1.0;
229        a->var[3][6] = -1 * _x[3] * x[3];
230        a->var[3][7] = -1 * _x[3] * y[3];
231       
232        a->var[4][3] = x[0];
233        a->var[4][4] = y[0];
234        a->var[4][5] = 1.0;
235        a->var[4][6] = -1 * x[0] * _y[0];
236        a->var[4][7] = -1 * y[0] * _y[0];
237
238        a->var[5][3] = x[1];
239        a->var[5][4] = y[1];
240        a->var[5][5] = 1.0;
241        a->var[5][6] = -1 * x[1] * _y[1];
242        a->var[5][7] = -1 * y[1] * _y[1];
243
244        a->var[6][3] = x[2];
245        a->var[6][4] = y[2];
246        a->var[6][5] = 1.0;
247        a->var[6][6] = -1 * x[2] * _y[2];
248        a->var[6][7] = -1 * y[2] * _y[2];
249
250        a->var[7][3] = x[3];
251        a->var[7][4] = y[3];
252        a->var[7][5] = 1.0;
253        a->var[7][6] = -1 * x[3] * _y[3];
254        a->var[7][7] = -1 * y[3] * _y[3];
255       
256        b->var[0][0] = _x[0];
257        b->var[1][0] = _x[1];
258        b->var[2][0] = _x[2];
259        b->var[3][0] = _x[3];
260        b->var[4][0] = _y[0];
261        b->var[5][0] = _y[1];
262        b->var[6][0] = _y[2];
263        b->var[7][0] = _y[3];
264
265        a_inv = matrix_inv(a);
266        c = matrix_multiple( a_inv, b );
267
268        projection = matrix_new( 3, 3 );
269        projection->var[0][0] = c->var[0][0];
270        projection->var[0][1] = c->var[1][0];
271        projection->var[0][2] = c->var[2][0];
272       
273        projection->var[1][0] = c->var[3][0];
274        projection->var[1][1] = c->var[4][0];
275        projection->var[1][2] = c->var[5][0];
276       
277        projection->var[2][0] = c->var[6][0];
278        projection->var[2][1] = c->var[7][0];
279        projection->var[2][2] = 1.0;
280
281        matrix_free(a);
282        matrix_free(b);
283        matrix_free(c);
284
285        matrix_free(a_inv);
286
287        return projection;
288}
289
290int main(int argc, char* argv[]){
291       
292        matrix *projection;
293
294        FILE* in;
295        FILE* out;
296
297        uchar* src;
298        uchar* dst;
299
300        /*
301        double x[] = {
302                277.0,  536.0,  284.0,  541.0
303        };
304        double y[] = {
305                61.0,   8.0,    387.0,  450.0
306        };
307        */
308        double x[] = {
309                235.0,  355.0,  242.0,  362.0
310        };
311        double y[] = {
312                51.0,   82.0,   443.0,  412.0
313        };
314
315       
316        double _x[] = {
317                240.0,  350.0,  240.0,  350.0
318        };
319        double _y[] = {
320                82.0,   82.0,   412.0,  412.0
321        };
322       
323
324        /*
325        double _x[] = {
326                20.0,   620.0,  20.0,   620.0
327        };
328        double _y[] = {
329                20.0,   20.0,   460.0,  460.0
330        };
331       
332        double _x[] = {
333                220.0,  420.0,  220.0,  420.0
334        };
335        double _y[] = {
336                140.0,  140.0,  340.0,  340.0
337        };
338        */
339
340        char filename[255];
341       
342        projection = projection_matrix( x, y, _x, _y );
343       
344        src = (uchar*)malloc(sizeof(uchar)*WIDTH*HEIGHT );
345        dst = (uchar*)malloc(sizeof(uchar)*WIDTH*HEIGHT );
346       
347        in = fopen( INFILE, "rb" );
348        fread( src, sizeof(uchar), WIDTH*HEIGHT, in );
349        fclose(in);
350
351        fwarping( dst, src, projection );
352
353        sprintf( filename, OUTFILE, "fwarping" );
354        out = fopen( filename, "wb" );
355        fwrite( dst, sizeof(uchar), WIDTH*HEIGHT, out );
356        fclose(out);
357
358        fwarping_i( dst, src, projection );
359
360        sprintf( filename, OUTFILE, "fwarping_i" );
361        out = fopen( filename, "wb" );
362        fwrite( dst, sizeof(uchar), WIDTH*HEIGHT, out );
363        fclose(out);
364
365        bwarping( dst, src, projection );
366
367        sprintf( filename, OUTFILE, "bwarping" );
368        out = fopen( filename, "wb" );
369        fwrite( dst, sizeof(uchar), WIDTH*HEIGHT, out );
370        fclose(out);
371
372        bwarping_i( dst, src, projection );
373       
374        sprintf( filename, OUTFILE, "bwarping_i" );
375        out = fopen( filename, "wb" );
376        fwrite( dst, sizeof(uchar), WIDTH*HEIGHT, out );
377        fclose(out);
378
379        return 0;
380}
381
382
Note: See TracBrowser for help on using the browser.