Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / ext / opencv / MotionCells.cpp
1 /*
2  * GStreamer
3  * Copyright (C) 2011 Robert Jobbagy <jobbagy.robert@gmail.com>
4  * Copyright (C) 2011 Nicola Murino <nicola.murino@gmail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Alternatively, the contents of this file may be used under the
25  * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
26  * which case the following provisions apply instead of the ones
27  * mentioned above:
28  *
29  * This library is free software; you can redistribute it and/or
30  * modify it under the terms of the GNU Library General Public
31  * License as published by the Free Software Foundation; either
32  * version 2 of the License, or (at your option) any later version.
33  *
34  * This library is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
37  * Library General Public License for more details.
38  *
39  * You should have received a copy of the GNU Library General Public
40  * License along with this library; if not, write to the
41  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
42  * Boston, MA 02111-1307, USA.
43  */
44
45 #include <cstdlib>
46 #include <errno.h>
47 #include <math.h>
48 #include <gst/gst.h>
49 #include <arpa/inet.h>
50 #include "MotionCells.h"
51
52 uint64_t ntohl64 (uint64_t val);
53 uint64_t htonl64 (uint64_t val);
54
55 uint64_t
56 ntohl64 (uint64_t val)
57 {
58   uint64_t res64;
59   uint32_t low = (uint32_t) (val & 0x00000000FFFFFFFFLL);
60   uint32_t high = (uint32_t) ((val & 0xFFFFFFFF00000000LL) >> 32);
61   low = ntohl (low);
62   high = ntohl (high);
63   res64 = (uint64_t) high + (((uint64_t) low) << 32);
64   return res64;
65 }
66
67
68 uint64_t
69 htonl64 (uint64_t val)
70 {
71   uint64_t res64;
72   uint32_t low = (uint32_t) (val & 0x00000000FFFFFFFFLL);
73   uint32_t high = (uint32_t) ((val & 0xFFFFFFFF00000000LL) >> 32);
74   low = htonl (low);
75   high = htonl (high);
76   res64 = (uint64_t) high + (((uint64_t) low) << 32);
77   return res64;
78 }
79
80 MotionCells::MotionCells ()
81 {
82   m_framecnt = 0;
83   m_motioncells_idx_count = 0;
84   m_motioncellsidxcstr = NULL;
85   m_saveInDatafile = false;
86   mc_savefile = NULL;
87   m_pcurFrame = NULL;
88   m_pprevFrame = NULL;
89   transparencyimg = NULL;
90   m_pdifferenceImage = NULL;
91   m_pbwImage = NULL;
92   m_initdatafilefailed = new char[BUSMSGLEN];
93   m_savedatafilefailed = new char[BUSMSGLEN];
94   m_initerrorcode = 0;
95   m_saveerrorcode = 0;
96   m_alpha = 0.5;
97   m_beta = 0.5;
98   m_useAlpha = false;
99   m_isVisible = false;
100
101 }
102
103 MotionCells::~MotionCells ()
104 {
105   if (mc_savefile) {
106     fclose (mc_savefile);
107     mc_savefile = NULL;
108   }
109   delete[]m_initdatafilefailed;
110   delete[]m_savedatafilefailed;
111   if (m_motioncellsidxcstr)
112     delete[]m_motioncellsidxcstr;
113   if (m_pcurFrame)
114     cvReleaseImage (&m_pcurFrame);
115   if (m_pprevFrame)
116     cvReleaseImage (&m_pprevFrame);
117   if (transparencyimg)
118     cvReleaseImage (&transparencyimg);
119   if (m_pdifferenceImage)
120     cvReleaseImage (&m_pdifferenceImage);
121   if (m_pbwImage)
122     cvReleaseImage (&m_pbwImage);
123 }
124
125 int
126 MotionCells::performDetectionMotionCells (IplImage * p_frame,
127     double p_sensitivity, double p_framerate, int p_gridx, int p_gridy,
128     gint64 timestamp_millisec, bool p_isVisible, bool p_useAlpha,
129     int motionmaskcoord_count, motionmaskcoordrect * motionmaskcoords,
130     int motionmaskcells_count, motioncellidx * motionmaskcellsidx,
131     cellscolor motioncellscolor, int motioncells_count,
132     motioncellidx * motioncellsidx, gint64 starttime, char *p_datafile,
133     bool p_changed_datafile, int p_thickness)
134 {
135
136   int sumframecnt = 0;
137   int ret = 0;
138   p_framerate >= 1 ? p_framerate <= 5 ? sumframecnt = 1
139       : p_framerate <= 10 ? sumframecnt = 2
140       : p_framerate <= 15 ? sumframecnt = 3
141       : p_framerate <= 20 ? sumframecnt = 4
142       : p_framerate <= 25 ? sumframecnt = 5 : sumframecnt = 0 : sumframecnt = 0;
143
144   m_framecnt++;
145   m_changed_datafile = p_changed_datafile;
146   if (m_framecnt >= sumframecnt) {
147     m_useAlpha = p_useAlpha;
148     m_gridx = p_gridx;
149     m_gridy = p_gridy;
150     if (m_changed_datafile) {
151       ret = initDataFile (p_datafile, starttime);
152       if (ret != 0)
153         return ret;
154     }
155
156     m_frameSize = cvGetSize (p_frame);
157     m_frameSize.width /= 2;
158     m_frameSize.height /= 2;
159     setMotionCells (m_frameSize.width, m_frameSize.height);
160     m_sensitivity = 1 - p_sensitivity;
161     m_isVisible = p_isVisible;
162     m_pcurFrame = cvCloneImage (p_frame);
163     IplImage *m_pcurgreyImage = cvCreateImage (m_frameSize, IPL_DEPTH_8U, 1);
164     IplImage *m_pprevgreyImage = cvCreateImage (m_frameSize, IPL_DEPTH_8U, 1);
165     IplImage *m_pgreyImage = cvCreateImage (m_frameSize, IPL_DEPTH_8U, 1);
166     IplImage *m_pcurDown =
167         cvCreateImage (m_frameSize, m_pcurFrame->depth, m_pcurFrame->nChannels);
168     IplImage *m_pprevDown = cvCreateImage (m_frameSize, m_pprevFrame->depth,
169         m_pprevFrame->nChannels);
170     m_pbwImage = cvCreateImage (m_frameSize, IPL_DEPTH_8U, 1);
171     cvPyrDown (m_pprevFrame, m_pprevDown);
172     cvCvtColor (m_pprevDown, m_pprevgreyImage, CV_RGB2GRAY);
173     cvPyrDown (m_pcurFrame, m_pcurDown);
174     cvCvtColor (m_pcurDown, m_pcurgreyImage, CV_RGB2GRAY);
175     m_pdifferenceImage = cvCloneImage (m_pcurgreyImage);
176     //cvSmooth(m_pcurgreyImage, m_pcurgreyImage, CV_GAUSSIAN, 3, 0);//TODO camera noise reduce,something smoothing, and rethink runningavg weights
177
178     //Minus the current gray frame from the 8U moving average.
179     cvAbsDiff (m_pprevgreyImage, m_pcurgreyImage, m_pdifferenceImage);
180
181     //Convert the image to black and white.
182     cvAdaptiveThreshold (m_pdifferenceImage, m_pbwImage, 255,
183         CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, 7);
184
185     // Dilate and erode to get object blobs
186     cvDilate (m_pbwImage, m_pbwImage, NULL, 2);
187     cvErode (m_pbwImage, m_pbwImage, NULL, 2);
188
189     //mask-out the overlay on difference image
190     if (motionmaskcoord_count > 0)
191       performMotionMaskCoords (motionmaskcoords, motionmaskcoord_count);
192     if (motionmaskcells_count > 0)
193       performMotionMask (motionmaskcellsidx, motionmaskcells_count);
194     if (getIsNonZero (m_pbwImage)) {    //detect Motion
195       GST_DEBUG ("DETECT MOTION \n");
196       if (m_MotionCells.size () > 0)    //it contains previous motioncells what we used when frames dropped
197         m_MotionCells.clear ();
198       if (transparencyimg)
199         cvReleaseImage (&transparencyimg);
200       (motioncells_count > 0) ?
201           calculateMotionPercentInMotionCells (motioncellsidx,
202           motioncells_count)
203           : calculateMotionPercentInMotionCells (motionmaskcellsidx, 0);
204
205       transparencyimg = cvCreateImage (cvGetSize (p_frame), p_frame->depth, 3);
206       cvSetZero (transparencyimg);
207       if (m_motioncellsidxcstr)
208         delete[]m_motioncellsidxcstr;
209       m_motioncells_idx_count = m_MotionCells.size () * MSGLEN; //one motion cell idx: (lin idx : col idx,) it's 4 character except last motion cell idx
210       m_motioncellsidxcstr = new char[m_motioncells_idx_count];
211       char *tmpstr = new char[MSGLEN];
212       for (int i = 0; i < MSGLEN; i++)
213         tmpstr[i] = ' ';
214       for (unsigned int i = 0; i < m_MotionCells.size (); i++) {
215         CvPoint pt1, pt2;
216         pt1.x = m_MotionCells.at (i).cell_pt1.x * 2;
217         pt1.y = m_MotionCells.at (i).cell_pt1.y * 2;
218         pt2.x = m_MotionCells.at (i).cell_pt2.x * 2;
219         pt2.y = m_MotionCells.at (i).cell_pt2.y * 2;
220         if (m_useAlpha && m_isVisible) {
221           cvRectangle (transparencyimg,
222               pt1,
223               pt2,
224               CV_RGB (motioncellscolor.B_channel_value,
225                   motioncellscolor.G_channel_value,
226                   motioncellscolor.R_channel_value), CV_FILLED);
227         } else if (m_isVisible) {
228           cvRectangle (p_frame,
229               pt1,
230               pt2,
231               CV_RGB (motioncellscolor.B_channel_value,
232                   motioncellscolor.G_channel_value,
233                   motioncellscolor.R_channel_value), p_thickness);
234         }
235
236         if (i < m_MotionCells.size () - 1) {
237           snprintf (tmpstr, MSGLEN, "%d:%d,", m_MotionCells.at (i).lineidx,
238               m_MotionCells.at (i).colidx);
239         } else {
240           snprintf (tmpstr, MSGLEN, "%d:%d", m_MotionCells.at (i).lineidx,
241               m_MotionCells.at (i).colidx);
242         }
243         if (i == 0)
244           strncpy (m_motioncellsidxcstr, tmpstr, m_motioncells_idx_count);
245         else
246           strcat (m_motioncellsidxcstr, tmpstr);
247       }
248       if (m_MotionCells.size () == 0)
249         strncpy (m_motioncellsidxcstr, " ", m_motioncells_idx_count);
250
251       if (m_useAlpha && m_isVisible) {
252         if (m_MotionCells.size () > 0)
253           blendImages (p_frame, transparencyimg, m_alpha, m_beta);
254       }
255
256       delete[]tmpstr;
257
258       if (mc_savefile && m_saveInDatafile) {
259         ret = saveMotionCells (timestamp_millisec);
260         if (ret != 0)
261           return ret;
262       }
263     } else {
264       m_motioncells_idx_count = 0;
265       if (m_MotionCells.size () > 0)
266         m_MotionCells.clear ();
267       if (transparencyimg)
268         cvReleaseImage (&transparencyimg);
269     }
270
271     if (m_pprevFrame)
272       cvReleaseImage (&m_pprevFrame);
273     m_pprevFrame = cvCloneImage (m_pcurFrame);
274     m_framecnt = 0;
275     if (m_pcurFrame)
276       cvReleaseImage (&m_pcurFrame);
277     if (m_pdifferenceImage)
278       cvReleaseImage (&m_pdifferenceImage);
279     if (m_pcurgreyImage)
280       cvReleaseImage (&m_pcurgreyImage);
281     if (m_pprevgreyImage)
282       cvReleaseImage (&m_pprevgreyImage);
283     if (m_pgreyImage)
284       cvReleaseImage (&m_pgreyImage);
285     if (m_pbwImage)
286       cvReleaseImage (&m_pbwImage);
287     if (m_pprevDown)
288       cvReleaseImage (&m_pprevDown);
289     if (m_pcurDown)
290       cvReleaseImage (&m_pcurDown);
291     if (m_pCells) {
292       for (int i = 0; i < m_gridy; ++i) {
293         delete[]m_pCells[i];
294       }
295       delete[]m_pCells;
296     }
297
298     if (p_framerate <= 5) {
299       if (m_MotionCells.size () > 0)
300         m_MotionCells.clear ();
301       if (transparencyimg)
302         cvReleaseImage (&transparencyimg);
303     }
304   } else {                      //we do frame drop
305     m_motioncells_idx_count = 0;
306     ret = -2;
307     for (unsigned int i = 0; i < m_MotionCells.size (); i++) {
308       CvPoint pt1, pt2;
309       pt1.x = m_MotionCells.at (i).cell_pt1.x * 2;
310       pt1.y = m_MotionCells.at (i).cell_pt1.y * 2;
311       pt2.x = m_MotionCells.at (i).cell_pt2.x * 2;
312       pt2.y = m_MotionCells.at (i).cell_pt2.y * 2;
313       if (m_useAlpha && m_isVisible) {
314         cvRectangle (transparencyimg,
315             pt1,
316             pt2,
317             CV_RGB (motioncellscolor.B_channel_value,
318                 motioncellscolor.G_channel_value,
319                 motioncellscolor.R_channel_value), CV_FILLED);
320       } else if (m_isVisible) {
321         cvRectangle (p_frame,
322             pt1,
323             pt2,
324             CV_RGB (motioncellscolor.B_channel_value,
325                 motioncellscolor.G_channel_value,
326                 motioncellscolor.R_channel_value), p_thickness);
327       }
328
329     }
330     if (m_useAlpha && m_isVisible) {
331       if (m_MotionCells.size () > 0)
332         blendImages (p_frame, transparencyimg, m_alpha, m_beta);
333     }
334   }
335   return ret;
336 }
337
338 int
339 MotionCells::initDataFile (char *p_datafile, gint64 starttime)  //p_date is increased with difference between current and previous buffer ts
340 {
341   MotionCellData mcd;
342   if (strncmp (p_datafile, " ", 1)) {
343     mc_savefile = fopen (p_datafile, "w");
344     if (mc_savefile == NULL) {
345       //fprintf(stderr, "%s %d:initDataFile:fopen:%d (%s)\n", __FILE__, __LINE__, errno,
346       //strerror(errno));
347       strncpy (m_initdatafilefailed, strerror (errno), BUSMSGLEN - 1);
348       m_initerrorcode = errno;
349       return 1;
350     } else {
351       m_saveInDatafile = true;
352     }
353   } else
354     mc_savefile = NULL;
355   bzero (&m_header, sizeof (MotionCellHeader));
356   m_header.headersize = htonl (MC_HEADER);
357   m_header.type = htonl (MC_TYPE);
358   m_header.version = htonl (MC_VERSION);
359   //it needs these bytes
360   m_header.itemsize =
361       htonl ((int) ceil (ceil (m_gridx * m_gridy / 8.0) / 4.0) * 4 +
362       sizeof (mcd.timestamp));
363   m_header.gridx = htonl (m_gridx);
364   m_header.gridy = htonl (m_gridy);
365   m_header.starttime = htonl64 (starttime);
366
367   snprintf (m_header.name, sizeof (m_header.name), "%s %dx%d", MC_VERSIONTEXT,
368       ntohl (m_header.gridx), ntohl (m_header.gridy));
369   m_changed_datafile = false;
370   return 0;
371 }
372
373 int
374 MotionCells::saveMotionCells (gint64 timestamp_millisec)
375 {
376
377   MotionCellData mc_data;
378   mc_data.timestamp = htonl (timestamp_millisec);
379   mc_data.data = NULL;
380   //There is no datafile
381   if (mc_savefile == NULL)
382     return 0;
383
384   if (ftello (mc_savefile) == 0) {
385     //cerr << "Writing out file header"<< m_header.headersize <<":" << sizeof(MotionCellHeader) << " itemsize:"
386     //<< m_header.itemsize << endl;
387     if (fwrite (&m_header, sizeof (MotionCellHeader), 1, mc_savefile) != 1) {
388       //fprintf(stderr, "%s %d:saveMotionCells:fwrite:%d (%s)\n", __FILE__, __LINE__, errno,
389       //strerror(errno));
390       strncpy (m_savedatafilefailed, strerror (errno), BUSMSGLEN - 1);
391       m_saveerrorcode = errno;
392       return -1;
393     }
394   }
395
396   mc_data.data =
397       (char *) calloc (1,
398       ntohl (m_header.itemsize) - sizeof (mc_data.timestamp));
399   if (mc_data.data == NULL) {
400     //fprintf(stderr, "%s %d:saveMotionCells:calloc:%d (%s)\n", __FILE__, __LINE__, errno,
401     //strerror(errno));
402     strncpy (m_savedatafilefailed, strerror (errno), BUSMSGLEN - 1);
403     m_saveerrorcode = errno;
404     return -1;
405   }
406
407   for (unsigned int i = 0; i < m_MotionCells.size (); i++) {
408     int bitnum =
409         m_MotionCells.at (i).lineidx * ntohl (m_header.gridx) +
410         m_MotionCells.at (i).colidx;
411     int bytenum = (int) floor (bitnum / 8.0);
412     int shift = bitnum - bytenum * 8;
413     mc_data.data[bytenum] = mc_data.data[bytenum] | (1 << shift);
414     //cerr << "Motion Detected " <<  "line:" << m_MotionCells.at(i).lineidx << " col:" << m_MotionCells.at(i).colidx;
415     //cerr << "    bitnum " << bitnum << " bytenum " << bytenum << " shift " << shift << " value " << (int)mc_data.data[bytenum] << endl;
416   }
417
418   if (fwrite (&mc_data.timestamp, sizeof (mc_data.timestamp), 1,
419           mc_savefile) != 1) {
420     //fprintf(stderr, "%s %d:saveMotionCells:fwrite:%d (%s)\n", __FILE__, __LINE__, errno,
421     //strerror(errno));
422     strncpy (m_savedatafilefailed, strerror (errno), BUSMSGLEN - 1);
423     m_saveerrorcode = errno;
424     return -1;
425   }
426
427   if (fwrite (mc_data.data,
428           ntohl (m_header.itemsize) - sizeof (mc_data.timestamp), 1,
429           mc_savefile) != 1) {
430     //fprintf(stderr, "%s %d:saveMotionCells:fwrite:%d (%s)\n", __FILE__, __LINE__, errno,
431     //strerror(errno));
432     strncpy (m_savedatafilefailed, strerror (errno), BUSMSGLEN - 1);
433     m_saveerrorcode = errno;
434     return -1;
435   }
436
437   free (mc_data.data);
438   return 0;
439 }
440
441 double
442 MotionCells::calculateMotionPercentInCell (int p_row, int p_col,
443     double *p_cellarea, double *p_motionarea)
444 {
445   double cntpixelsnum = 0;
446   double cntmotionpixelnum = 0;
447
448   int ybegin = floor ((double) p_row * m_cellheight);
449   int yend = floor ((double) (p_row + 1) * m_cellheight);
450   int xbegin = floor ((double) (p_col) * m_cellwidth);
451   int xend = floor ((double) (p_col + 1) * m_cellwidth);
452   int cellw = xend - xbegin;
453   int cellh = yend - ybegin;
454   int cellarea = cellw * cellh;
455   *p_cellarea = cellarea;
456   int thresholdmotionpixelnum = floor ((double) cellarea * m_sensitivity);
457
458   for (int i = ybegin; i < yend; i++) {
459     for (int j = xbegin; j < xend; j++) {
460       cntpixelsnum++;
461       if ((((uchar *) (m_pbwImage->imageData + m_pbwImage->widthStep * i))[j]) >
462           0) {
463         cntmotionpixelnum++;
464         if (cntmotionpixelnum >= thresholdmotionpixelnum) {     //we dont needs calculate anymore
465           *p_motionarea = cntmotionpixelnum;
466           return (cntmotionpixelnum / cntpixelsnum);
467         }
468       }
469       int remainingpixelsnum = cellarea - cntpixelsnum;
470       if ((cntmotionpixelnum + remainingpixelsnum) < thresholdmotionpixelnum) { //moving pixels number will be less than threshold
471         *p_motionarea = 0;
472         return 0;
473       }
474     }
475   }
476
477   return (cntmotionpixelnum / cntpixelsnum);
478 }
479
480 void
481 MotionCells::calculateMotionPercentInMotionCells (motioncellidx *
482     p_motioncellsidx, int p_motioncells_count)
483 {
484   if (p_motioncells_count == 0) {
485     for (int i = 0; i < m_gridy; i++) {
486       for (int j = 0; j < m_gridx; j++) {
487         m_pCells[i][j].MotionPercent = calculateMotionPercentInCell (i, j,
488             &m_pCells[i][j].CellArea, &m_pCells[i][j].MotionArea);
489         m_pCells[i][j].hasMotion =
490             m_sensitivity < m_pCells[i][j].MotionPercent ? true : false;
491         if (m_pCells[i][j].hasMotion) {
492           MotionCellsIdx mci;
493           mci.lineidx = i;
494           mci.colidx = j;
495           mci.cell_pt1.x = floor ((double) j * m_cellwidth);
496           mci.cell_pt1.y = floor ((double) i * m_cellheight);
497           mci.cell_pt2.x = floor ((double) (j + 1) * m_cellwidth);
498           mci.cell_pt2.y = floor ((double) (i + 1) * m_cellheight);
499           int w = mci.cell_pt2.x - mci.cell_pt1.x;
500           int h = mci.cell_pt2.y - mci.cell_pt1.y;
501           mci.motioncell = cvRect (mci.cell_pt1.x, mci.cell_pt1.y, w, h);
502           m_MotionCells.push_back (mci);
503         }
504       }
505     }
506   } else {
507     for (int k = 0; k < p_motioncells_count; ++k) {
508
509       int i = p_motioncellsidx[k].lineidx;
510       int j = p_motioncellsidx[k].columnidx;
511       m_pCells[i][j].MotionPercent =
512           calculateMotionPercentInCell (i, j,
513           &m_pCells[i][j].CellArea, &m_pCells[i][j].MotionArea);
514       m_pCells[i][j].hasMotion =
515           m_pCells[i][j].MotionPercent > m_sensitivity ? true : false;
516       if (m_pCells[i][j].hasMotion) {
517         MotionCellsIdx mci;
518         mci.lineidx = p_motioncellsidx[k].lineidx;
519         mci.colidx = p_motioncellsidx[k].columnidx;
520         mci.cell_pt1.x = floor ((double) j * m_cellwidth);
521         mci.cell_pt1.y = floor ((double) i * m_cellheight);
522         mci.cell_pt2.x = floor ((double) (j + 1) * m_cellwidth);
523         mci.cell_pt2.y = floor ((double) (i + 1) * m_cellheight);
524         int w = mci.cell_pt2.x - mci.cell_pt1.x;
525         int h = mci.cell_pt2.y - mci.cell_pt1.y;
526         mci.motioncell = cvRect (mci.cell_pt1.x, mci.cell_pt1.y, w, h);
527         m_MotionCells.push_back (mci);
528       }
529     }
530   }
531 }
532
533 void
534 MotionCells::performMotionMaskCoords (motionmaskcoordrect * p_motionmaskcoords,
535     int p_motionmaskcoords_count)
536 {
537   CvPoint upperleft;
538   upperleft.x = 0;
539   upperleft.y = 0;
540   CvPoint lowerright;
541   lowerright.x = 0;
542   lowerright.y = 0;
543   for (int i = 0; i < p_motionmaskcoords_count; i++) {
544     upperleft.x = p_motionmaskcoords[i].upper_left_x;
545     upperleft.y = p_motionmaskcoords[i].upper_left_y;
546     lowerright.x = p_motionmaskcoords[i].lower_right_x;
547     lowerright.y = p_motionmaskcoords[i].lower_right_y;
548     cvRectangle (m_pbwImage, upperleft, lowerright, CV_RGB (0, 0, 0),
549         CV_FILLED);
550   }
551 }
552
553 void
554 MotionCells::performMotionMask (motioncellidx * p_motionmaskcellsidx,
555     int p_motionmaskcells_count)
556 {
557   for (int k = 0; k < p_motionmaskcells_count; k++) {
558     int beginy = p_motionmaskcellsidx[k].lineidx * m_cellheight;
559     int beginx = p_motionmaskcellsidx[k].columnidx * m_cellwidth;
560     int endx =
561         (double) p_motionmaskcellsidx[k].columnidx * m_cellwidth + m_cellwidth;
562     int endy =
563         (double) p_motionmaskcellsidx[k].lineidx * m_cellheight + m_cellheight;
564     for (int i = beginy; i < endy; i++)
565       for (int j = beginx; j < endx; j++) {
566         ((uchar *) (m_pbwImage->imageData + m_pbwImage->widthStep * i))[j] = 0;
567       }
568   }
569 }
570
571 ///BGR if we use only OpenCV
572 //RGB if we use gst+OpenCV
573 void
574 MotionCells::blendImages (IplImage * p_actFrame, IplImage * p_cellsFrame,
575     float p_alpha, float p_beta)
576 {
577
578   int height = p_actFrame->height;
579   int width = p_actFrame->width;
580   int step = p_actFrame->widthStep / sizeof (uchar);
581   int channels = p_actFrame->nChannels;
582   int cellstep = p_cellsFrame->widthStep / sizeof (uchar);
583   uchar *curImageData = (uchar *) p_actFrame->imageData;
584   uchar *cellImageData = (uchar *) p_cellsFrame->imageData;
585
586   for (int i = 0; i < height; i++)
587     for (int j = 0; j < width; j++)
588       for (int k = 0; k < channels; k++)
589         if (cellImageData[i * cellstep + j * channels + k] > 0) {
590           curImageData[i * step + j * channels + k] =
591               round ((double) curImageData[i * step + j * channels +
592                   k] * p_alpha + ((double) cellImageData[i * cellstep +
593                       j * channels + k] * p_beta));
594         }
595 }