1 /*
2 * libng filter -- Correction of lens distortion
3 *
4 * (c) 2002 Frederic Helin <Frederic.Helin@inrialpes.fr>,
5 * Gerd Knorr <kraxel@bytesex.org>
6 *
7 */
8
9 #include "config.h"
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include <inttypes.h>
15 #include <pthread.h>
16
17 #include "grab-ng.h"
18
19 /* ------------------------------------------------------------------- */
20
21 int parm_k = 700;
22 int parm_cx = 50;
23 int parm_cy = 50;
24 int parm_zoom = 50;
25
26 /* ------------------------------------------------------------------- */
27
28 static void *init(struct ng_video_fmt *out)
29 {
30 /* don't have to carry around status info */
31 static int dummy;
32 return &dummy;
33 }
34
35 static struct ng_video_buf*
36 frame(void *handle, struct ng_video_buf *in)
37 {
38 struct ng_video_buf *out;
39 uint8_t *dst8;
40 uint8_t *src8;
41 uint16_t *dst16;
42 uint16_t *src16;
43
44 int i, j, cx, cy, di, dj;
45 float dr, cr,ca, sx, zoom, k;
46
47 out = ng_malloc_video_buf(&in->fmt, in->fmt.height * in->fmt.bytesperline);
48 out->info = in->info;
49
50 dst8 = out->data;
51 src8 = in->data;
52 dst16 = (uint16_t*) out->data;
53 src16 = (uint16_t*) in->data;
54
55 zoom = parm_zoom / 100.0;
56 k = parm_k / 100.0;
57 cx = in->fmt.width * parm_cx / 100;
58 cy = in->fmt.height * parm_cy / 100;
59
60 #if 0
61 sensor_w = parm_sensorw/100.0;
62 sensor_h = parm_sensorh/100.0;
63
64 /* calc ratio x/y */
65 sx = in->fmt.width * sensor_h / (in->fmt.height * sensor_w);
66
67 /* calc new value of k in the coordonates systeme of computer */
68 k = k * in->fmt.height / sensor_h;
69 #else
70 sx = 1;
71 k = k * 100.0;
72 #endif
73
74 for (j = 0; j < (int)in->fmt.height ; j++) {
75 for (i = 0; i < (int)in->fmt.width ; i++) {
76
77 // compute radial distortion / parameters of center of image
78 cr = sqrt((i-cx)/sx*(i-cx)/sx+(j-cy)*(j-cy));
79 ca = atan(cr/k/zoom);
80 dr = k * tan(ca/2);
81
82 if (i == cx && j == cy) {
83 di = cx;
84 dj = cy;
85 } else {
86 di = (i-cx) * dr / cr + cx;
87 dj = (j-cy) * dr / cr + cy;
88 }
89
90 if (dj >= (int)in->fmt.height || dj < 0 ||
91 di >= (int)in->fmt.width || di < 0)
92 continue;
93
94 switch (in->fmt.fmtid) {
95 case VIDEO_RGB15_LE:
96 case VIDEO_RGB16_LE:
97 case VIDEO_RGB15_BE:
98 case VIDEO_RGB16_BE:
99 dst16[i] = src16[dj*in->fmt.width + di];
100 break;
101 case VIDEO_BGR24:
102 case VIDEO_RGB24:
103 dst8[3*i ] = src8[3*(dj*in->fmt.width + di) ];
104 dst8[3*i+1] = src8[3*(dj*in->fmt.width + di)+1];
105 dst8[3*i+2] = src8[3*(dj*in->fmt.width + di)+2];
106 break;
107 }
108 }
109 dst8 += out->fmt.bytesperline;
110 dst16 += out->fmt.bytesperline/2;
111 }
112
113 ng_release_video_buf(in);
114 return out;
115 }
116
117 static void fini(void *handle)
118 {
119 /* nothing to clean up */
120 }
121
122 /* ------------------------------------------------------------------- */
123
124 static int read_attr(struct ng_attribute *attr)
125 {
126 switch (attr->id) {
127 case 1000:
128 return parm_k;
129 case 1001:
130 return parm_zoom;
131 case 1002:
132 return parm_cx;
133 case 1003:
134 return parm_cy;
135 }
136 return 0;
137 }
138
139 static void write_attr(struct ng_attribute *attr, int value)
140 {
141 switch (attr->id) {
142 case 1000:
143 parm_k = value;
144 break;
145 case 1001:
146 parm_zoom = value;
147 break;
148 case 1002:
149 parm_cx = value;
150 break;
151 case 1003:
152 parm_cy = value;
153 break;
154 }
155 }
156
157 /* ------------------------------------------------------------------- */
158
159 static struct ng_attribute attrs[] = {
160 {
161 id: 1000,
162 name: "k",
163 type: ATTR_TYPE_INTEGER,
164 defval: 700,
165 min: 1,
166 max: 2000,
167 read: read_attr,
168 write: write_attr,
169 },{
170 id: 1001,
171 name: "zoom",
172 type: ATTR_TYPE_INTEGER,
173 defval: 50,
174 min: 10,
175 max: 100,
176 read: read_attr,
177 write: write_attr,
178 },{
179 id: 1002,
180 name: "center x",
181 type: ATTR_TYPE_INTEGER,
182 defval: 50,
183 min: 0,
184 max: 100,
185 read: read_attr,
186 write: write_attr,
187 },{
188 id: 1003,
189 name: "center y",
190 type: ATTR_TYPE_INTEGER,
191 defval: 50,
192 min: 0,
193 max: 100,
194 read: read_attr,
195 write: write_attr,
196 },{
197 /* end of list */
198 }
199 };
200
201 static struct ng_filter filter = {
202 name: "disortion correction",
203 attrs: attrs,
204 fmts:
205 (1 << VIDEO_RGB15_BE) |
206 (1 << VIDEO_RGB16_BE) |
207 (1 << VIDEO_RGB15_LE) |
208 (1 << VIDEO_RGB16_LE) |
209 (1 << VIDEO_BGR24) |
210 (1 << VIDEO_RGB24),
211 init: init,
212 frame: frame,
213 fini: fini,
214 };
215
216 extern void ng_plugin_init(void);
217 void ng_plugin_init(void)
218 {
219 ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter);
220 }
221
|
This page was automatically generated by the
LXR engine.
|