main.c

Updated security-cam source file with rev 503 bug fix. - Anthony Rowe, 03/24/2007 11:29 am

Download (5.6 kB)

 
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
}