Bonjour,

Ca fait plusieurs heures que je cherche sur internet et je teste différentes méthodes pour redimensionner une video dont la source est ma webcam, mais rien y fait.
Le but est d'alleger le poids de la vidéo capturée par la webcam.

Auriez-vous une solution ?

Je laisse mon code si ça vous permet de m'aiguiller. Merci.
(Je suis sous OpenCV 3.2)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
 
// -- Open-->New-->Project-->OpenCV Project
 
// -- Project Title :     monProjet
// -- Folder to creat. :  /home/morgatte/CodeBlock
// -- Project Filename :  monProjet.cbp
// -- Resulting Filena :  /home/morgatte/CodeBlock/monProjet/monProjet.cbp
 
 
 
 
// Project --> Build options... --> Search directories --> Linker
// Copiez /usr/local/lib
 
// Project --> Build options... --> Linker Settings
// copiez toutes les librairies déposées dans  /usr/local/lib/
 
// Project --> Build options... --> Search directories --> Compiler
// Copiez le chemin vers opencv2 soit... /usr/local/include/opencv
//                                       /usr/local/include/opencv2
 
 
// bin/Release/./c*
 
//#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/optflow/motempl.hpp>
#include <opencv2/video/background_segm.hpp>
 
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <fstream>
#include <vector> // Pour créer des tableaux dynamiques en longueurs (pour des lignes contenant des string)
 
 
using namespace cv;
using namespace std;
 
int time(void);                             //
string getDate (int);                       //
string nomVideo (string);                   //
string nomVideo2 (string);                  //
bool lectureFichierIni (void);              //
int heure_str2int (string);                 //
 
 
bool afficherFenetreVideo = 1;              // Montre ou bien cache la fenêtre d'affichage en directe de la vidéo
 
int newTimeOrigine;                         //
vector<string> horaire(8);                  // <-- Tableau de 8 lignes de type string de tailles dynamiques
vector<int> periode(8);                     // <-- Tableau de 8 lignes de type int de tailles dynamiques
 
 
 
int sensibilite1 = 2; // <--------------------- 3 par défaut mais 1 ou 2 est plus sensible pour une détection de loin
int sensibilite2 = 40; // <--------------------- 20 par défaut (nombres de carrés différents en tant que déclanchement d'une détection) 10 = très sensible
int sensibilite3 = 800; // <--------------------- 300 par défaut (taille du plus gros bloc détecté) entre 200 et 1000. 300 = on détecte des blocs plutôt petits
int seuilDetection = 100; // <---------------------- 100 ce seuil est dépendant de sensibilite1 et sensibilite2.
 
 
 
 
//-----------------------------------------------------------------------------------------------------------
static bool refineSegments(const Mat& img, Mat& mask, Mat& dst)
{
    int niters = sensibilite1;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    Mat temp;
    dilate(mask, temp, Mat(), Point(-1,-1), niters);
    erode(temp, temp, Mat(), Point(-1,-1), niters*2);
    dilate(temp, temp, Mat(), Point(-1,-1), niters);
    findContours( temp, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE );
    dst = Mat::zeros(img.size(), CV_8UC3);
    if(contours.size() == 0) return 0;
 
    // iterate through all the top-level contours,
    // draw each connected component with its own random color
 
    int idx = 0, largestComp = 0;
    double maxArea = 0;
    for( ; idx >= 0; idx = hierarchy[idx][0] )
    {
        const vector<Point>& c = contours[idx];
        double area = fabs(contourArea(Mat(c)));
        if( area > maxArea )
        {
            maxArea = area;
            largestComp = idx;
        }
    }
    Scalar color( 0, 100, 100 );
    drawContours( dst, contours, largestComp, color, FILLED, LINE_8, hierarchy );
 
    cout << contours.size() << " : " << maxArea << " = " << maxArea/contours.size() << endl;
 
    bool valRet = 0; if (maxArea/contours.size() > seuilDetection) valRet = 1;
    return valRet;
}
//-----------------------------------------------------------------------------------------------------------
 
 
 
 
 
//-----------------------------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
    bool detect = 0; bool enregistrementEnCours = 0;
    bool update_bg_model = true;
    Mat cam_frame, bgmask, out_frame, frameToSave;
    bool rec_period = 0;
    string fichierAVI;
    VideoCapture cap;
 
 
    cap.open(0);                                                                            // Initialise la webCam en tant que source vidéo
   	if (!cap.isOpened()) {cout << "La Webcam est indisponible !!!" << endl; return -1;}
 
 
    cap >> cam_frame;
                                                                          // L'image filmée est placée dans cam_frame
    if(cam_frame.empty()) {printf("aucune image provenant de la source video\n"); return -1;}
 
    Size frame_size = cam_frame.size();
    //frame_size.width /= 2;
    //frame_size.height /= 2;
 
 
//    namedWindow("video", CV_WINDOW_AUTOSIZE);
//    namedWindow("segmented", CV_WINDOW_AUTOSIZE);
 
    Ptr<BackgroundSubtractorMOG2> bgsubtractor = createBackgroundSubtractorMOG2();          // Initialise un backGround
    bgsubtractor->setVarThreshold(50);
 
    VideoWriter oVideoWriter;                                               // Initialise un objet VideoWriter, lequel stocke les images en mémoire
                                                                            // pour ensuite pouvoir les enregistrer sur le ddur en tant que fichier AVI
 
    while(1)
    {
        cap >> cam_frame;                                                          // On récupère l'image
        if(cam_frame.empty()) break;                                               // On sort si ça échoue
 
        //cvtColor(cam_frame, cam_frame, CV_BGR2GRAY); // Permet d'avoir une vidéo en noir & blanc (mettre  oVideoWriter.open(..., true) à false )
 
        resize(cam_frame, frameToSave, cv::Size(), 1.00, 1.00, INTER_CUBIC); //ou bien CV_INTER_LINEAR);
 
 
        bgsubtractor->apply(cam_frame, bgmask, update_bg_model ? -1 : 0);          // On crée un back ground
        detect = refineSegments(cam_frame, bgmask, out_frame);                     // On essaie de détecter un changement (mouvement)
 
        string afficherDection = "";
 
        if (detect) {                                                              // Si un mouvement est détecté alors...
            afficherDection = "Detection";                                         // ... on le notifie
            newTimeOrigine = time();                                               // on marque ce temps comme origine du temps qui passe.
                                                                                   //
            if (enregistrementEnCours != 1) {                                      // <---- Si aucun enregistrement n'est en cours, alors .....
                enregistrementEnCours = 1;                                         //
                oVideoWriter.release();                                            // on initialise un nouvel objet vidéo, pour préparer
                rec_period = lectureFichierIni();                                  //
                if (rec_period == 1) {                                             //
                    fichierAVI = nomVideo ("_videoSpy");                           // l'enregistrement d'une nouvelle vidéo avec un nouveau nom
                    oVideoWriter.open (fichierAVI, CV_FOURCC('D','I','V','X'), 25, frame_size, true);
                }
            }
 
        } else { // Pas de détection actuellement
 
            if (time() - newTimeOrigine > 5) {                                     // Si on ne détecte aucun mouvement depuis
                enregistrementEnCours = 0;                                         // plusieurs secondes, alors on notifie aux lignes qui suivent
            }                                                                      // qu'il va falloir arrêter d'enregistrer.
        }
 
        //------------------------------------------------------------------------------//
                                                                                        //
        if (enregistrementEnCours == 1) {                                               //
            rec_period = lectureFichierIni();                                           //
            if (rec_period == 1) {                                                      //
                    cv::putText(frameToSave, getDate(0), cv::Point(10,16), cv::FONT_HERSHEY_COMPLEX_SMALL, 1.0, cv::Scalar(255, 255, 200), 1, CV_AA);
                    oVideoWriter.write (frameToSave);                                   //  <---- ON ENREGISTRE !!!!!!!!!!!!!
            }                                                                           //
        } else {                                                                        // ...sinon ...
            oVideoWriter.release();                                                     // on a terminé d'enregistrer et donc...
        }                                                                               // on réinitialise (on ferme) l'objet VideoWriter.
        //------------------------------------------------------------------------------//
 
 
 
        if (afficherFenetreVideo == 1) {
            cv::putText(frameToSave, afficherDection, cv::Point(600,30), cv::FONT_HERSHEY_COMPLEX_SMALL, 2.0 /* Scale. 2.0 = 2x bigger */, cv::Scalar(255, 50, 255), 2 /* épaisseur */, CV_AA);
            imshow("video", frameToSave);
            imshow("segmented", out_frame);
        }
 
        int keycode = waitKey(30);
        if( keycode == 27 ) break;
    }
    return 0;
}
//-----------------------------------------------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
//-----------------------------------------------------------------------------------------------------------
// Donne le temps actuel (nb de secondes passées depuis 01/01/1970)
int time (void) {
    time_t now = time(0);
    tm *ltm = localtime(&now);
    return now;
}
//-----------------------------------------------------------------------------------------------------------
 
 
 
//------------------------------------------------------------------//
// Renvoie une string de type 2016/12/25 18:57:45                   //
string getDate (int mode) {                                         //
    string stDate = "";                                             // getDate(m); avec m le mode 0, 1 ou 2
    time_t now = time(0);                                           //
    tm *ltm = localtime(&now);                                      //
    if (mode == 0 || mode == 1) {  // mode = 1 --> "2016/12/25"     // mode 0 --> "2016/12/24 09:30:12"
        stDate += std::to_string(1900 + ltm->tm_year)+"/";          // mode 1 --> "2016/12/24"
        if (ltm->tm_mon < 10) stDate += "0";                        // mode 2 --> "09:30:12"
        stDate += std::to_string(1 + ltm->tm_mon)+"/";              //
        if (ltm->tm_mday < 10) stDate += "0";                       //
        stDate += std::to_string(ltm->tm_mday);                     //
    }                                                               //
                                                                    //
    if (mode == 0) stDate += " ";                                   //
                                                                    //
    if (mode == 0 || mode == 2) {                                   //
        if (ltm->tm_hour < 10) stDate += "0";                       //
        stDate += std::to_string(ltm->tm_hour)+":";                 //
        if (ltm->tm_min < 10) stDate += "0";                        //
        stDate += std::to_string(ltm->tm_min)+":";                  //
        if (ltm->tm_sec < 10) stDate += "0";                        //
        stDate += std::to_string(ltm->tm_sec);                      //
    }                                                               //
                                                                    //
    return stDate;                                                  //
}                                                                   //
//------------------------------------------------------------------//
 
 
//------------------------------------------------------------------//
string nomVideo (string cheminAVI) {                                // Ce bloc crée des noms de fichiers avec un nouveau numéro pour
    string numChar; int num = 0;                                    // chaque nouveau fichier.
    string str = cheminAVI;                                         // Ex:
    str += to_string(num);                                          // _MaVideo0.avi
    str += ".avi";                                                  // _MaVideo1.avi
    FILE * fp = fopen(str.c_str(), "rb");                           // _MaVideo2.avi
    while (fp != NULL) {                                            // ...
        fclose(fp);                                                 // _MaVideo3.avi
        num++;                                                      //
        str = cheminAVI;                                            //
        str += to_string(num);                                      //
        str += ".avi";                                              //
        fp = fopen(str.c_str(), "rb");                              //
    }                                                               //
    return str;                                                     //
}                                                                   //
//------------------------------------------------------------------//
 
 
//------------------------------------------------------------------//
string nomVideo2 (string cheminAVI) {                               // Ce bloc crée des noms de fichiers avec un nouveau numéro pour
                                                                    // chaque nouveau fichier.
    string str = cheminAVI;                                         // Ex:
    str += "(";                                                     //
    str += getDate(0);                                              // (2016/12/25 22:45:10).avi
    str += ").avi";                                                 //
    //cout << str << endl;                                          //
    return str;                                                     //
}                                                                   //
//------------------------------------------------------------------//
 
 
//------------------------------------------------------------------//
bool lectureFichierIni (void) {                                     // Cette procédure lit le contenu du fichier noRecord.ini et compare la date actuelle
    bool retour = 1;                                                // avec les lignes du fichier. Si trouvée, alors les plages de temps de cette ligne
    string dateActuelle = getDate(1); // ex: "2016/12/24"           // représentent des périodes où on ne souhaite pas que la caméra enregistre
                                                                    // (pour éviter de surcharger l'espace de stockage à des périodes inapropriées)
    ifstream fichier_spin_ini("noRecord.ini", ios::in);             // son contenu est une suite de lignes du type :
    if(fichier_spin_ini)                                            // 2016/12/10 15:00-22:00 23:10-23:45
    {                                                               // 2016/12/14 05:00-22:16
        string ligne;                                               // 2017/04/08 17:00-17:40 17:55-18:00
        while(getline(fichier_spin_ini, ligne))                     //
        {                                                           //
            if (dateActuelle == ligne.substr(0, 10)) {retour = 0; break;} else {retour = 1;}
        }                                                           //
        fichier_spin_ini.close();                                   // ligne contient les infos pour la date actuelle ex:
        //cout << ligne << endl;                                    // ligne = 2016/12/09 08:30 09:00 15:00 16:00
        if (retour == 1) {return 1;}                                //
        ligne = ligne.substr(11, ligne.size());                     // ligne = 08:30 09:00 15:00 16:00
        //cout << ligne << endl;                                    //
                                                                    //
        int i = 0;                                                  //
        while (6*i<ligne.size()) {                                  // horaire[i] est un tableau contenant les heures de la ligne
            horaire[i] = ligne.substr(i*6,5);                       //
            periode[i] = heure_str2int (horaire[i]);                //             (string)              (int)
            //cout << horaire[i] << endl;                           // horaire[0] = 08:30    periode[0] = 510
            //cout << periode[i] << endl;                           // horaire[1] = 09:00    periode[1] = 540
            i++;                                                    // horaire[2] = 15:00    periode[2] = 900
        }                                                           // horaire[3] = 16:00    periode[3] = 960
                                                                    //
        i--;                                                        //
                                                                    //
        int heureActuelle = heure_str2int (getDate (2));            //
        //cout << heureActuelle << endl;                            //
                                                                    //
        do {                                                        //
            if (heureActuelle >= periode[i-1] && heureActuelle < periode[i]) {
                //cout << periode[i-1] << "-" << heureActuelle << "-" << periode[i] << endl;
                //cout << "i = "<< i << "  " << "periode[i] = " << periode[i] << endl;
                return 0;      // On est dans une période de non enregistrement donc on abandonne le fait d'enregistrer
            }                                                       //
            i-=2;                                                   //
        } while (i>1);                                             //
                                                                    //
    }                                                               //
    else cerr << "Impossible d'ouvrir noRecord.ini !" << endl;      //
                                                                    //
    return 1;   // On est à un moment où l'enregistrement n'est pas interdit donc on accepte le fait d'enregistrer.
}                                                                   //
//------------------------------------------------------------------//
 
 
//------------------------------------------------------------------//
// (string) 08:12 --> 60*8+12 --> (int) 492                         //
int heure_str2int (string h) {                                      //
    return 60*stoi(h.substr(0,2))+stoi(h.substr(3,2));              //
}                                                                   //
//------------------------------------------------------------------//