1 /* 2 * GStreamer 3 * Copyright (C) 2011 Robert Jobbagy <jobbagy.robert@gmail.com> 4 * Copyright (C) 2011 - 2018 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., 51 Franklin St, Fifth Floor, 42 * Boston, MA 02110-1301, USA. 43 */ 44 45 #ifndef MOTIONCELLS_H_ 46 #define MOTIONCELLS_H_ 47 48 #include <opencv2/core.hpp> 49 #include <fstream> 50 #include <vector> 51 #include <glib.h> 52 53 //MotionCells defines 54 #define MC_HEADER 64 55 #define MC_TYPE 1 56 #define MC_VERSION 1 57 #define MC_VERSIONTEXT "MotionCells-1" 58 #define MSGLEN 6 59 #define BUSMSGLEN 20 60 61 using namespace std; 62 63 struct MotionCellHeader{ 64 gint32 headersize; 65 gint32 type; 66 gint32 version; 67 gint32 itemsize; 68 gint32 gridx; 69 gint32 gridy; 70 gint64 starttime; 71 char name[MC_HEADER - 32]; 72 }; 73 74 struct MotionCellData{ 75 gint32 timestamp; 76 char *data; 77 }; 78 79 typedef struct { 80 int upper_left_x; 81 int upper_left_y; 82 int lower_right_x; 83 int lower_right_y; 84 } motionmaskcoordrect; 85 86 typedef struct { 87 int R_channel_value; 88 int G_channel_value; 89 int B_channel_value; 90 } cellscolor; 91 92 typedef struct { 93 int lineidx; 94 int columnidx; 95 } motioncellidx; 96 97 struct Cell 98 { 99 double MotionArea; 100 double CellArea; 101 double MotionPercent; 102 bool hasMotion; 103 }; 104 105 struct MotionCellsIdx 106 { 107 cv::Rect motioncell; 108 //Points for the edges of the rectangle. 109 cv::Point cell_pt1; 110 cv::Point cell_pt2; 111 int lineidx; 112 int colidx; 113 }; 114 115 struct OverlayRegions 116 { 117 cv::Point upperleft; 118 cv::Point lowerright; 119 }; 120 121 class MotionCells 122 { 123 public: 124 125 MotionCells (); 126 virtual ~ MotionCells (); 127 128 int performDetectionMotionCells (cv::Mat p_frame, double p_sensitivity, 129 double p_framerate, int p_gridx, int p_gridy, gint64 timestamp_millisec, 130 bool p_isVisble, bool p_useAlpha, int motionmaskcoord_count, 131 motionmaskcoordrect * motionmaskcoords, int motionmaskcells_count, 132 motioncellidx * motionmaskcellsidx, cellscolor motioncellscolor, 133 int motioncells_count, motioncellidx * motioncellsidx, gint64 starttime, 134 char *datafile, bool p_changed_datafile, int p_thickness); 135 setPrevFrame(cv::Mat p_prevframe)136 void setPrevFrame (cv::Mat p_prevframe) 137 { 138 m_pprevFrame = p_prevframe.clone(); 139 } getMotionCellsIdx()140 char *getMotionCellsIdx () 141 { 142 return m_motioncellsidxcstr; 143 } 144 getMotionCellsIdxCount()145 int getMotionCellsIdxCount () 146 { 147 return m_motioncells_idx_count; 148 } 149 getChangedDataFile()150 bool getChangedDataFile () 151 { 152 return m_changed_datafile; 153 } 154 getDatafileInitFailed()155 char *getDatafileInitFailed () 156 { 157 return m_initdatafilefailed; 158 } 159 getDatafileSaveFailed()160 char *getDatafileSaveFailed () 161 { 162 return m_savedatafilefailed; 163 } 164 getInitErrorCode()165 int getInitErrorCode () 166 { 167 return m_initerrorcode; 168 } 169 getSaveErrorCode()170 int getSaveErrorCode () 171 { 172 return m_saveerrorcode; 173 } 174 freeDataFile()175 void freeDataFile () 176 { 177 if (mc_savefile) { 178 fclose (mc_savefile); 179 mc_savefile = NULL; 180 m_saveInDatafile = false; 181 } 182 } 183 184 private: 185 186 double calculateMotionPercentInCell (int p_row, int p_col, double *p_cellarea, 187 double *p_motionarea); 188 void performMotionMaskCoords (motionmaskcoordrect * p_motionmaskcoords, 189 int p_motionmaskcoords_count); 190 void performMotionMask (motioncellidx * p_motionmaskcellsidx, 191 int p_motionmaskcells_count); 192 void calculateMotionPercentInMotionCells (motioncellidx * 193 p_motionmaskcellsidx, int p_motionmaskcells_count = 0); 194 int saveMotionCells (gint64 timestamp_millisec); 195 int initDataFile (char *p_datafile, gint64 starttime); 196 void blendImages (cv::Mat p_actFrame, cv::Mat p_cellsFrame, 197 float p_alpha, float p_beta); 198 setData(cv::Mat img,int lin,int col,uchar valor)199 void setData (cv::Mat img, int lin, int col, uchar valor) 200 { 201 ((uchar *) (img.data + img.step[0] * lin))[col] = valor; 202 } 203 getData(cv::Mat img,int lin,int col)204 uchar getData (cv::Mat img, int lin, int col) 205 { 206 return ((uchar *) (img.data + img.step[0] * lin))[col]; 207 } 208 getIsNonZero(cv::Mat img)209 bool getIsNonZero (cv::Mat img) 210 { 211 int lin, col; 212 213 for (lin = 0; lin < img.size().height; lin++) 214 for (col = 0; col < img.size().width; col++) { 215 if ((((uchar *) (img.data + img.step[0] * lin))[col]) > 0) 216 return true; 217 } 218 return false; 219 } 220 setMotionCells(int p_frameWidth,int p_frameHeight)221 void setMotionCells (int p_frameWidth, int p_frameHeight) 222 { 223 int i, j; 224 225 m_cellwidth = (double) p_frameWidth / (double) m_gridx; 226 m_cellheight = (double) p_frameHeight / (double) m_gridy; 227 m_pCells = new Cell *[m_gridy]; 228 for (i = 0; i < m_gridy; i++) 229 m_pCells[i] = new Cell[m_gridx]; 230 231 //init cells 232 for (i = 0; i < m_gridy; i++) 233 for (j = 0; j < m_gridx; j++) { 234 m_pCells[i][j].MotionArea = 0; 235 m_pCells[i][j].CellArea = 0; 236 m_pCells[i][j].MotionPercent = 0; 237 m_pCells[i][j].hasMotion = false; 238 } 239 } 240 241 cv::Mat m_pprevFrame, m_pdifferenceImage, m_pbwImage, m_pcurFrame, 242 transparencyimg; 243 bool m_isVisible, m_changed_datafile, m_useAlpha, m_saveInDatafile; 244 Cell **m_pCells; 245 vector < MotionCellsIdx > m_MotionCells; 246 vector < OverlayRegions > m_OverlayRegions; 247 int m_gridx, m_gridy; 248 double m_cellwidth, m_cellheight; 249 double m_alpha, m_beta; 250 double m_sensitivity; 251 int m_framecnt, m_motioncells_idx_count, m_initerrorcode, m_saveerrorcode; 252 char *m_motioncellsidxcstr, *m_initdatafilefailed, *m_savedatafilefailed; 253 FILE *mc_savefile; 254 MotionCellHeader m_header; 255 256 }; 257 258 #endif /* MOTIONCELLS_H_ */ 259