IMPLEMENTO DI UN CONTATORE NEL PROGRAMMA ESISTENTE

di il
4 risposte

IMPLEMENTO DI UN CONTATORE NEL PROGRAMMA ESISTENTE

Salve a tutti.
Vorrei implementare nel codice che identifica l'occupazione di un parcheggio un contatore che mi tiene il conto dei posti macchina occupati in real time.
Il programma funziona correttamente, vorrei solo implementare questo pezzettino di codice. Mi dareste una mano??

Allego il codice. Grazie in anticipo

#include <stdio.h>
#include <string>
#include <sstream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "Parking.h"
#include "utils.h"
#include "ConfigLoad.h"

using namespace std;

int main(int argc, char** argv)
{
if (argc != 3)
{
printf("usage: DetectParking.exe <Video_Filename or Camera_Number> <ParkingData_Filename>\n\n");
printf("<Camera_Number> can be 0, 1, ... for attached cameras\n");
printf("<ParkingData_Filename> should be simple txt file with lines of: id x1 y1 x2 y2 x3 y3 x4 y4\n");
return -1;
}

//Load configs
ConfigLoad::parse();


const string videoFilename = argv[1];
vector<Parking> parking_data = parse_parking_file(argv[2]);
const int delay = 1;

// Open Camera or Video File
cv::VideoCapture cap;
if (videoFilename == "0" || videoFilename == "1" || videoFilename == "2")
{
printf("Loading Connected Camera...\n");
cap.open(stoi(videoFilename));
cv::waitKey(500);
}
else
{
cap.open(videoFilename);
//cap.set(cv::CAP_PROP_POS_FRAMES, 60000); // jump to frame
}
if (!cap.isOpened())
{
cout << "Could not open: " << videoFilename << endl;
return -1;
}
const unsigned long int total_frames = cap.get(CV_CAP_PROP_FRAME_COUNT);
cv::Size videoSize = cv::Size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH), // Acquire input size
(int)cap.get(CV_CAP_PROP_FRAME_HEIGHT));

cv::VideoWriter outputVideo;
if (ConfigLoad::options["SAVE_VIDEO"] == "true")
{
string::size_type pAt = videoFilename.find_last_of('.'); // Find extension point
const string videoOutFilename = videoFilename.substr(0, pAt) + "_out.avi"; // Form the new name with container
int ex = static_cast<int>(cap.get(CV_CAP_PROP_FOURCC)); // Get Codec Type- Int form
//cv::VideoWriter::CV_FOURCC('C', 'R', 'A', 'M');
outputVideo.open(videoOutFilename, -1, cap.get(CV_CAP_PROP_FPS), videoSize, true);
}

// Initiliaze variables
cv::Mat frame, frame_blur, frame_gray, frame_out, roi, laplacian;
cv::Scalar delta, color;
char c; // Char from keyboard
ostringstream oss;
cv::Size blur_kernel = cv::Size(5, 5);
cv::namedWindow("Video", cv::WINDOW_AUTOSIZE);

// Loop through Video
while (cap.isOpened())
{
cap.read(frame);
if (frame.empty())
{
printf("Error reading frame\n");
return -1;
}
//printf("msec: %d frames: %d\n", CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES);
double video_pos_msec = cap.get(CV_CAP_PROP_POS_MSEC);
double video_pos_frame = cap.get(CV_CAP_PROP_POS_FRAMES);

frame_out = frame.clone();
cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
cv::GaussianBlur(frame_gray, frame_blur, blur_kernel, 3, 3);

cout << ConfigLoad::options["DETECT_PARKING"];
printf("1\n");

if (ConfigLoad::options["DETECT_PARKING"] == "true")
{
for (Parking& park : parking_data)
{
// Check if parking is occupied
roi = frame_blur(park.getBoundingRect());
cv::Laplacian(roi, laplacian, CV_64F);
delta = cv::mean(cv::abs(laplacian), park.getMask());
park.setStatus( delta[0] < atof(ConfigLoad::options["PARK_LAPLACIAN_TH"].c_str()) );
printf("| %d: d=%-5.1f", park.getId(), delta[0]);
}
printf("2\n");
}

// Parking Overlay
for (Parking park : parking_data)
{
if (park.getStatus()) color = cv::Scalar(0, 255, 0); //verde
else color = cv::Scalar(0, 0, 255);
cv::drawContours(frame_out, park.getContourPoints(), -1, color, 2, CV_AA);





// Parking ID overlay
cv::Point p = park.getCenterPoint();
cv::putText(frame_out, to_string(park.getId()), cv::Point(p.x + 1, p.y + 1), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 2, CV_AA); //Riempimento colore pos
cv::putText(frame_out, to_string(park.getId()), cv::Point(p.x - 1, p.y - 1), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 2, CV_AA);
cv::putText(frame_out, to_string(park.getId()), cv::Point(p.x - 1, p.y + 1), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 2, CV_AA);//bianco
cv::putText(frame_out, to_string(park.getId()), cv::Point(p.x + 1, p.y - 1), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 2, CV_AA);
cv::putText(frame_out, to_string(park.getId()), p, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 2, CV_AA);
}
// Text Overlay
oss.str("");
oss << (unsigned long int)video_pos_frame << "/" << total_frames;
cv::putText(frame_out, oss.str(), cv::Point(5, 30), cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(0, 0, 255), 2, CV_AA); //rosso

// Save Video
if (ConfigLoad::options["SAVE_VIDEO"] == "true")
{
outputVideo.write(frame_out);
}

// Show Video
cv::imshow("Video", frame_out);
c = (char)cv::waitKey(delay);
if (c == 27) break;
}

return 0;
}

4 Risposte

  • Re: IMPLEMENTO DI UN CONTATORE NEL PROGRAMMA ESISTENTE

    Utilizza i tag CODE per il codice nel forum.

    E poi spiega qualcosa del programma. Se l'hai scritto tu dovresti indicare quando viene determinato il fatto che il posto è occupato. C'è anche un commento a proposito ... è la posizione corretta nel codice?
  • Re: IMPLEMENTO DI UN CONTATORE NEL PROGRAMMA ESISTENTE

    Mi chiederei anche perchè c'è un filtro gaussiano applicato sempre
  • Re: IMPLEMENTO DI UN CONTATORE NEL PROGRAMMA ESISTENTE

    Il programma non è stato scritto da me, ho fatto solo qualche modifica perchè inizialmente mi dava problemi con le librerie di Opencv. io dovrei implementare un pezzetto di codice che in pratica mi tenga il conto ( con stampa su terminale) del numero di parcheggi liberi rimasti.

    La parte che determina l'occupazione del posto è nella riga:

    // Check if parking is occupied
    roi = frame_blur(park.getBoundingRect());
    cv::Laplacian(roi, laplacian, CV_64F);
    delta = cv::mean(cv::abs(laplacian), park.getMask());
    park.setStatus( delta[0] < atof(ConfigLoad::options["PARK_LAPLACIAN_TH"].c_str()) );
    printf("| %d: d=%-5.1f", park.getId(), delta[0]);
    }
    printf("2\n");
    }



    Metto il link del programma:
    https://github.com/eladj/detectParkin
    e il video che fa vedere come funziona:
    https://www.youtube.com/watch?v=bPeGC8-PQJ

    Ho anche un altro problema, nel momento in cui provo il programma facendo una prova con la ripresa da un parcheggio qualsiasi, il programma individua si l'occupazione del parcheggio da parte di un'auto, ma non esclude l'occupazione dello stesso da parte di altri oggetti ( quindi se qualsiasi cosa passa sopra il perimetro tracciato, lui lo segna come occupato e questo non lo dovrebbe poter fare), quindi dovrei dargli una percentuale di occupazione da rispettare.. Potreste darmi una mano?
  • Re: IMPLEMENTO DI UN CONTATORE NEL PROGRAMMA ESISTENTE

    Così è impossibile risponderti.

    Cosa determina che sia occupato? È il valore di delta[0] ?

    E quanto vale nel caso di posto occupato? Solo tu provando il codice puoi saperlo ed intervenire.

    Anche per l'altro problema, se rilevi solo il passaggio di un oggetto nell'area non potrai risolvere. Ed è anche molto complesso perché potrebbe essere un motorino...

    Tu non mi sembra che abbia la minima idea di come affrontare il problema (è una mia impressione) e faresti bene ad affidarti ad una persona esperta in loco.
Devi accedere o registrarti per scrivere nel forum
4 risposte