source: trunk/MagicSoft/Cosy/videodev/Filter.cc@ 744

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