security-cam: main.c

File main.c, 5.6 kB (added by agr, 2 years ago)

Updated security-cam source file with rev 503 bug fix.

Line 
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <cc3.h>
4 #include <jpeglib.h>
5 #include <cc3_frame_diff.h>
6
7 // How many pixels should change in a frame to be seen as motion
8 // Remember, the frame is downsampled to 16x16
9 #define NUM_PIX_CHANGE_THRESH     10
10
11 // How much the color of a single pixel should change to be detected
12 #define PIX_CHANGE_THRESH         20
13
14
15 static void capture_current_jpeg (FILE * f);
16 static void init_jpeg (void);
17 static void destroy_jpeg (void);
18
19 int main (void)
20 {
21   uint32_t img_cnt;
22   void *tmp;
23   FILE *f;
24   cc3_frame_diff_pkt_t fd_pkt;
25   cc3_image_t img;
26   uint32_t pixel_change_threshold;
27
28   pixel_change_threshold = NUM_PIX_CHANGE_THRESH;
29
30
31
32
33   cc3_uart_init (0,
34                  CC3_UART_RATE_115200,
35                  CC3_UART_MODE_8N1, CC3_UART_BINMODE_TEXT);
36
37   cc3_camera_init ();
38
39   cc3_filesystem_init ();
40
41   //cc3_set_colorspace(CC3_COLORSPACE_YCRCB);
42   cc3_camera_set_resolution (CC3_CAMERA_RESOLUTION_HIGH);
43   // Set camera to low-res for faster frame differencing
44   // cc3_camera_set_resolution (CC3_CAMERA_RESOLUTION_LOW);
45   // cc3_pixbuf_set_subsample (CC3_SUBSAMPLE_NEAREST, 2, 2);
46   cc3_timer_wait_ms (1000);
47
48   // init pixbuf with width and height
49   cc3_pixbuf_load ();
50
51   // init jpeg
52   init_jpeg ();
53
54   cc3_led_set_state (1, true);
55
56  
57
58   fd_pkt.coi = 1;
59   cc3_pixbuf_frame_set_coi (fd_pkt.coi);
60   fd_pkt.template_width = 16;
61   fd_pkt.template_height = 16;
62   fd_pkt.previous_template =
63     malloc (fd_pkt.template_width * fd_pkt.template_height *
64             sizeof (uint32_t));
65
66   if (fd_pkt.previous_template == NULL)
67     printf ("Malloc FD startup error!\r");
68
69   fd_pkt.current_template =
70     malloc (fd_pkt.template_width * fd_pkt.template_height *
71             sizeof (uint32_t));
72
73   if (fd_pkt.current_template == NULL)
74     printf ("Malloc FD startup error!\r");
75
76   fd_pkt.total_x = cc3_g_pixbuf_frame.width;
77   fd_pkt.total_y = cc3_g_pixbuf_frame.height;
78   fd_pkt.load_frame = 1;        // load a new frame
79   fd_pkt.threshold = PIX_CHANGE_THRESH;
80
81   img.channels = 1;
82   img.width = cc3_g_pixbuf_frame.width;
83   img.height = 1;               // image will hold just 1 row for scanline processing
84   img.pix = malloc (img.width);
85
86
87   img_cnt = 0;
88   while (true) {
89     char filename[32];
90
91
92     // Wait some time for the change to go away and for the image to stabalize
93     cc3_timer_wait_ms (2000);
94
95     cc3_pixbuf_load ();
96     fd_pkt.load_frame = 1;      // load a new frame
97     if (cc3_frame_diff_scanline_start (&fd_pkt) != 0) {
98       while (cc3_pixbuf_read_rows (img.pix, 1)) {
99         cc3_frame_diff_scanline (&img, &fd_pkt);
100       }
101       cc3_frame_diff_scanline_finish (&fd_pkt);
102     }
103     else
104       printf ("frame diff start error\r");
105
106     fd_pkt.load_frame = 0;      // load a new frame
107     do {
108
109       cc3_pixbuf_load ();
110       if (cc3_frame_diff_scanline_start (&fd_pkt) != 0) {
111         while (cc3_pixbuf_read_rows (img.pix, 1)) {
112           cc3_frame_diff_scanline (&img, &fd_pkt);
113         }
114         cc3_frame_diff_scanline_finish (&fd_pkt);
115       }
116       else
117         printf ("frame diff start error\r");
118
119       // swap last frame template with current
120       tmp = fd_pkt.previous_template;
121       fd_pkt.previous_template = fd_pkt.current_template;
122       fd_pkt.current_template = tmp;
123       printf ("diff from last frame: %d\r\n", fd_pkt.num_pixels);
124     } while (fd_pkt.num_pixels < pixel_change_threshold);
125
126     printf ("Changed detected, write jpg!\r\n");
127
128     // Check if files exist, if they do then skip over them
129     do {
130 #ifdef VIRTUAL_CAM
131       snprintf (filename, 16, "img%.5d.jpg", img_cnt);
132 #else
133       snprintf (filename, 16, "c:/img%.5d.jpg", img_cnt);
134 #endif
135       f = fopen (filename, "r");
136       if (f != NULL) {
137         printf ("%s already exists...\n", filename);
138         img_cnt++;
139         fclose (f);
140       }
141     } while (f != NULL);
142
143     // print file that you are going to write to stderr
144     fprintf (stderr, "<%s>\r\n", filename);
145     f = fopen (filename, "w");
146     if (f == NULL || img_cnt > 200) {
147       cc3_led_set_state (3, true);
148       printf ("Error: Can't open file\r\n");
149       if (img_cnt > 200)
150         printf ("Card full\r\n");
151       while (1);
152     }
153     // Switch to full color for stored images
154     cc3_pixbuf_frame_set_coi (CC3_CHANNEL_ALL);
155     // Save the jpeg
156     capture_current_jpeg (f);
157     // Switch back to a single COI for the frame diff
158     cc3_pixbuf_frame_set_coi (fd_pkt.coi);
159
160     fclose (f);
161     img_cnt++;
162   }
163
164
165   destroy_jpeg ();
166   return 0;
167 }
168
169
170
171
172 static struct jpeg_compress_struct cinfo;
173 static struct jpeg_error_mgr jerr;
174 //static cc3_pixel_t *row;
175 uint8_t *row;
176
177 void init_jpeg (void)
178 {
179   cinfo.err = jpeg_std_error (&jerr);
180   jpeg_create_compress (&cinfo);
181
182   // parameters for jpeg image
183   cinfo.image_width = cc3_g_pixbuf_frame.width;
184   cinfo.image_height = cc3_g_pixbuf_frame.height;
185   printf ("image width=%d image height=%d\n", cinfo.image_width,
186           cinfo.image_height);
187   cinfo.input_components = 3;
188   // cinfo.in_color_space = JCS_YCbCr;
189   cinfo.in_color_space = JCS_RGB;
190
191   // set image quality, etc.
192   jpeg_set_defaults (&cinfo);
193   jpeg_set_quality (&cinfo, 100, true);
194
195   // allocate memory for 1 row
196   row = cc3_malloc_rows (1);
197   if (row == NULL)
198     printf ("Out of memory!\n");
199 }
200
201 void capture_current_jpeg (FILE * f)
202 {
203   JSAMPROW row_pointer[1];
204   row_pointer[0] = row;
205
206   // output is file
207   jpeg_stdio_dest (&cinfo, f);
208
209   // capture a frame to the FIFO
210   //cc3_pixbuf_load();
211   cc3_pixbuf_rewind ();
212
213   // read and compress
214   jpeg_start_compress (&cinfo, TRUE);
215   while (cinfo.next_scanline < cinfo.image_height) {
216     cc3_pixbuf_read_rows (row, 1);
217     jpeg_write_scanlines (&cinfo, row_pointer, 1);
218   }
219
220   // finish
221   jpeg_finish_compress (&cinfo);
222 }
223
224
225
226 void destroy_jpeg (void)
227 {
228   jpeg_destroy_compress (&cinfo);
229   free (row);
230 }