source: trunk/Cosy/videodev/Filter.cc@ 14745

Last change on this file since 14745 was 2278, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 3.8 KB
Line 
1#include "Filter.h"
2
3#include <memory.h> // memset
4#include <iostream.h> // cout
5
6ClassImp(Filter);
7
8void Filter::DrawBox(const int x1, const int y1,
9 const int x2, const int y2,
10 byte *buffer, const int col)
11{
12 for (int x=x1; x<x2+1; x++)
13 for (int y=y1; y<y2+1; y++)
14 buffer[y*768+x] = col;
15}
16
17void Filter::MarkPoint(const int x, const int y, byte *buffer, const int col)
18{
19 DrawBox(x-8, y, x-5, y, buffer, col);
20 DrawBox(x, y+5, x, y+8, buffer, col);
21 DrawBox(x+5, y, x+8, y, buffer, col);
22 DrawBox(x, y-8, x, y-5, buffer, col);
23 return;
24}
25
26float Filter::Mean(const byte *buffer, const int offset)
27{
28 double mean = 0.0;
29
30 byte *s = (byte*)buffer;
31 const byte *e0 = s+768*576;
32
33 //
34 // calculate mean value
35 //
36 while (s<e0)
37 {
38 const byte *e = s+576-offset;
39 s += offset;
40
41 while (s<e)
42 mean += *s++;
43
44 s+=offset;
45 }
46
47 return mean / ((768-2*offset)*(576-2*offset));
48}
49
50
51float Filter::SDev(const byte *buffer, const int offset, const double mean)
52{
53 //
54 // calculate sigma
55 //
56 double sdev=0.0;
57
58 for (int x=offset; x<768-offset; x++)
59 for (int y=offset; y<576-offset; y++)
60 {
61 const float val = mean - buffer[y*768+x];
62
63 sdev += val*val;
64 }
65
66 sdev /= (768-2*offset)*(576-2*offset)-1;
67
68 return sqrt(sdev);
69}
70
71int Filter::GetMeanPosition(const byte *bitmap, const int x, const int y,
72 const int box)
73{
74 unsigned int sumx=0;
75 unsigned int sumy=0;
76
77 unsigned int sum=0;
78
79 for (int dx=x-box; dx<x+box+1; dx++)
80 for (int dy=y-box; dy<y+box+1; dy++)
81 {
82 const byte m = bitmap[dy*768+dx]; // desc->buffer[3*(x+y*768)]; //
83
84 sumx += m*dx;
85 sumy += m*dy;
86 sum += m;
87 }
88
89 const float px = (float)sumx/sum;
90 const float py = (float)sumy/sum;
91
92 return (int)py*768 + (int)px;
93}
94
95void Filter::Execute(byte *img)
96{
97 const int offset = 10;
98
99 const float mean = Mean(img, offset);
100 const float sdev = SDev(img, offset, mean);
101
102 const byte cut = mean+2.5*sdev>254 ? 254 : (byte)(mean + 2.5*sdev);
103
104 //
105 // clean image from noise
106 //
107 const byte *e = img+768*576;
108 byte *i = img;
109 while (i<e)
110 {
111 if (*i<=cut)
112 *i = 0;
113 i++;
114 }
115
116 //
117 // find mean points
118 //
119 const int maxpnt = 0x1000;
120
121 int pos[maxpnt+1][2]; // FIXME
122 int cnt = 0;
123
124 for (int x=offset; x<768-offset; x++)
125 {
126 for (int y=offset; y<576-offset; y++)
127 {
128 if (img[x+768*y]==0)
129 continue;
130
131 const int ipos = GetMeanPosition(img, x, y, 5);
132
133 int j;
134 for (j=0; j<cnt; j++)
135 {
136 if (pos[j][0]==ipos)
137 {
138 if (pos[j][1] < 0xf0)
139 pos[j][1] += 0x10;
140 break;
141 }
142 }
143 if (cnt && j<cnt)
144 continue;
145
146 pos[cnt][0] = ipos;
147 pos[cnt][1] = 0x10;
148
149 cnt++;
150
151 if (cnt==maxpnt)
152 break;
153 }
154 if (cnt==maxpnt)
155 {
156 cout << "Error! More than " << maxpnt << " stars found." << endl;
157 break;
158 }
159 }
160
161 //
162 // Draw marker for found stars into picture
163 //
164 int points=0;
165
166 byte marker[768*576];
167 memset(marker, 0, 768*576);
168
169 for (int i=0; i<cnt; i++)
170 {
171 if (pos[i][1]>0xa0)
172 {
173 points++;
174
175 int px = pos[i][0]%768;
176 int py = pos[i][0]/768;
177
178 MarkPoint(px, py, marker, pos[i][1]);
179 }
180 }
181
182 //
183 // Copy markers into image
184 //
185 for (int x=0; x<768*576; x++)
186 {
187 if (!marker[x])
188 continue;
189
190 img[x]=marker[x];
191 }
192}
193
Note: See TracBrowser for help on using the repository browser.