Question

Please Implement ParkingLot.cpp below based off the completed Automobile Class and ClaimCheck class down below. Automobile.hpp...

Please Implement ParkingLot.cpp below based off the completed Automobile Class and ClaimCheck class down below.

Automobile.hpp

#pragma once
#include <iostream>
#include <string>
class Automobile {
friend bool operator==( const Automobile& lhs, const Automobile& rhs );
friend std::ostream & operator<<( std::ostream& stream, const Automobile& vehicle );
private:
std::string color_;
std::string brand_;
std::string model_;
std::string plateNumber_;
public:
Automobile( const std::string & color,
const std::string & brand,
const std::string & model,
const std::string & plateNumber );
};
bool operator!=( const Automobile& lhs, const Automobile& rhs );

Automobile.cpp

This is already implemented.

#include <iostream>
#include <string>
#include "Automobile.hpp"
using namespace std;
/*******************************************************************************
** Member function definitions
*******************************************************************************/
Automobile::Automobile( const std::string & color,
const std::string & brand,
const std::string & model,
const std::string & plateNumber )
: color_(color), brand_(brand), model_(model), plateNumber_(plateNumber)
{}
/*******************************************************************************
** Non-member function definitions
*******************************************************************************/
bool operator==( const Automobile& lhs, const Automobile& rhs ) {
if (lhs.color_.compare(rhs.color_) == 0 && lhs.brand_.compare(rhs.brand_) == 0 &&
lhs.model_.compare(rhs.model_) == 0 && lhs.plateNumber_.compare(rhs.plateNumber_) == 0)
{
return true;
}
return false;
}
bool operator!=( const Automobile& lhs, const Automobile& rhs )
{ return !( lhs == rhs ); }
std::ostream & operator<<( std::ostream& stream, const Automobile& vehicle )
{
// Inserting the vehicles details into the stream.
stream << "Color: " << vehicle.color_ << endl;
stream << "Brand: " << vehicle.brand_ << endl;
stream << "Model: " << vehicle.model_ << endl;
stream << "License Plate Number: " << vehicle.plateNumber_ << endl;
return stream;
}

ClaimCheck.hpp

#pragma once
#include <iostream>
#include "Automobile.hpp"
class ClaimCheck {
friend bool operator==( const ClaimCheck & lhs, const ClaimCheck & rhs );
friend std::ostream & operator<<( std::ostream & stream, const ClaimCheck & ticket );
private:
const Automobile vehicle_;
const size_t claimNumber_;
static size_t nextAvailableClaimNumber;
public:
ClaimCheck( const Automobile & vehicle );
Automobile vehicle () const;
size_t claimNumber() const;
};
bool operator!=( const ClaimCheck & lhs, const ClaimCheck & rhs );

ClaimCheck.cpp

This is already implemented.

#include <iostream>
#include "Automobile.hpp"
#include "ClaimCheck.hpp"
/*******************************************************************************
** Class attributes
*******************************************************************************/
size_t ClaimCheck::nextAvailableClaimNumber = 100;
/*******************************************************************************
** Member function definitions
*******************************************************************************/
ClaimCheck::ClaimCheck( const Automobile & vehicle )
: vehicle_(vehicle), claimNumber_(nextAvailableClaimNumber++)
{}
Automobile ClaimCheck::vehicle() const
{ return vehicle_; }
size_t ClaimCheck::claimNumber() const
{ return claimNumber_; }
/*******************************************************************************
** Non-member function definitions
*******************************************************************************/
bool operator==( const ClaimCheck & lhs, const ClaimCheck & rhs )
{
return lhs.claimNumber() == rhs.claimNumber();
}
bool operator!=( const ClaimCheck & lhs, const ClaimCheck & rhs )
{ return ! (lhs == rhs); }
std::ostream & operator<<( std::ostream & stream, const ClaimCheck & ticket )
{
stream << ticket.vehicle();
stream << "Claim Number: " << ticket.claimNumber() << endl;
return stream;
}

ParkingLot.hpp

Implement this class's cpp file down below

#pragma once
#include <queue>
#include "ClaimCheck.hpp"
#include "Automobile.hpp"
struct ParkedCar {
Automobile vehicle_;
size_t claimNumber_;
};
class ParkingLot {
private:
std::queue<ParkedCar> parkedCars_; // aisles closed on one end
public:
ClaimCheck dropOff( const Automobile& vehicle );
Automobile pickUp ( const ClaimCheck& ticket );
size_t quantity();
};

ParkingLot.cpp

Implement this .cpp file using queue std

#include <queue>
#include <stdexcept>
#include <string>
#include "ClaimCheck.hpp"
#include "ParkingLot.hpp"
/*******************************************************************************
** ParkingLot Member function definitions
*******************************************************************************/
ClaimCheck ParkingLot::dropOff( const Automobile& vehicle ) {
/// To be completed:
/// Create a claim check called ticket passing in the vehicle
. . .
///
/// To be completed:
/// Add the vehicle and the ticket's claim number to the collection of parked cars.
/// Hint: Create a ParkedCar and set its vehicle and claim number attributes, then push it on to the stack.
. . .
///
return ticket;
}
Automobile ParkingLot::pickUp( const ClaimCheck& ticket ) {
/// To be completed:
/// Move cars from the front of the queue to the back of the queue until you
/// find the one you're looking for or until you looked at them all.
/// Hint: The vehicle you're looking for has a ticket claim number that matches the parked car's claim number.
. . .
///
/// To be completed:
/// If you reach this point, the vehicle you're looking for wasn't in the parking lot.
/// Optional: Throw an invalid argument exception (highly recommended but not required). Otherwise
/// print out an error message and return the ticket's vehicle.
. . .
///
}
size_t ParkingLot::quantity()
{
/// To be completed:
/// Return the number of parked cars that are currently in the parking lot
. . .
///
}

Thanks.

0 0
Add a comment Improve this question Transcribed image text
Answer #1
#include <iostream>
#include <stdio.h>
#include <thread>
#include <queue>
#include <map>
#include <set>
#include <atomic>
#include <csignal>
#include <ctime>
#include <mutex>
#include <string>
#include <syslog.h>
#include <math.h>
#include <float.h>

// OpenCV includes
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/dnn.hpp>

// MQTT
#include "mqtt.h"

using namespace std;
using namespace cv;
using namespace dnn;

// OpenCV-related variables
Mat frame, blob;
VideoCapture cap;
int delay = 5;
Net net;

// application parameters
String model;
String config;
float carconf;
int backendId;
int targetId;
string entrance;
int max_distance;
int max_frames_gone;
int rate;

// flag to control background threads
atomic<bool> keepRunning(true);

// flag to handle UNIX signals
static volatile sig_atomic_t sig_caught = 0;

// mqtt parameters
const string topic = "parking/counter";

// Car contains information about trajectory of tracked car
struct Car {
    int id;
    vector<Point> traject;
    bool counted;
    bool gone;
    int direction;
};
// tracked_cars tracks detected cars by their ids
map<int, Car> tracked_cars;

// id is a counter used to generate ids for tracked centroids
int id = 0;

// Centroid is the center point of detected car rectangle
struct Centroid {
    int id;
    Point p;
    int gone_count;
};
// centroids maps centroids by their ids
map<int, Centroid> centroids;

// total cars in and out of the parking
int total_in = 0;
int total_out = 0;

// ParkingInfo contains information about available parking spaces
struct ParkingInfo
{
    int total_in;
    int total_out;
    map<int, Centroid> centroids;
};
// currentInfo contains the latest ParkingInfo as tracked by the application
ParkingInfo currentInfo;

// nextImage provides queue for captured video frames
queue<Mat> nextImage;
// currentPerf stores the label which contains application performance information
String currentPerf;
// mutexes used in program to control thread access to shared variables
mutex m, m1, m2;

const char* keys =
    "{ help     | | Print help message. }"
    "{ device d    | 0 | camera device number. }"
    "{ input i     | | Path to input image or video file. Skip this argument to capture frames from a camera. }"
    "{ model m     | | Path to .bin file of model containing face recognizer. }"
    "{ config c    | | Path to .xml file of model containing network configuration. }"
    "{ carconf cc  | 0.5 | Confidence factor for car detection required. }"
    "{ backend b   | 0 | Choose one of computation backends: "
                        "0: automatically (by default), "
                        "1: Halide language (http://halide-lang.org/), "
                        "2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
                        "3: OpenCV implementation }"
    "{ target t    | 0 | Choose one of target computation devices: "
                        "0: CPU target (by default), "
                        "1: OpenCL, "
                        "2: OpenCL fp16 (half-float precision), "
                        "3: VPU }"
    "{ entrance e  | b | Plane axis for parking  entrance and exit division mark. Possible options: "
                        "b: Bottom frame, "
                        "t: Top frame, "
                        "l: Left frame, "
                        "r: Right frame }"
    "{ max_distance md  | 200 | Max distance in pixels between two related centroids. }"
    "{ max_frames_gone mg | 25 | Max number of frames to track the centroid which doesnt change. }"
    "{ rate r      | 1 | Number of seconds between data updates to MQTT server. }";

// nextImageAvailable returns the next image from the queue in a thread-safe way
Mat nextImageAvailable() {
    Mat rtn;
    m.lock();
    if (!nextImage.empty()) {
        rtn = nextImage.front();
        nextImage.pop();
    }
    m.unlock();

    return rtn;
}

// addImage adds an image to the queue in a thread-safe way
void addImage(Mat img) {
    m.lock();
    if (nextImage.size() < 300) {
        nextImage.push(img);
    }
    m.unlock();
}

// getCurrentInfo returns the most-recent ParkingInfo for the application.
ParkingInfo getCurrentInfo() {
    m2.lock();
    ParkingInfo info;
    info = currentInfo;
    m2.unlock();

    return info;
}

// updateInfo uppdates the current ParkingInfo for the application to the latest detected values
//void updateInfo(vector<Rect> detections) {
void updateInfo() {
    m2.lock();
    currentInfo.total_in = total_in;
    currentInfo.total_out = total_out;
    currentInfo.centroids = centroids;
    m2.unlock();
}

// resetInfo resets the current ParkingInfo for the application.
void resetInfo() {
    m2.lock();
    currentInfo.total_in = 0;
    currentInfo.total_out = 0;
    currentInfo.centroids = map<int, Centroid>();
    m2.unlock();
}

// getCurrentPerf returns a display string with the most current performance stats for the Inference Engine.
string getCurrentPerf() {
    string perf;
    m1.lock();
    perf = currentPerf;
    m1.unlock();

    return perf;
}

// savePerformanceInfo sets the display string with the most current performance stats for the Inference Engine.
void savePerformanceInfo() {
    m1.lock();

    vector<double> times;
    double freq = getTickFrequency() / 1000;
    double t = net.getPerfProfile(times) / freq;

    string label = format("Car inference time: %.2f ms", t);

    currentPerf = label;

    m1.unlock();
}

// publish MQTT message with a JSON payload
void publishMQTTMessage(const string& topic, const ParkingInfo& info) {
    ostringstream s;
    s << "{\"TOTAL_IN\": \"" << info.total_in << "\" \"TOTAL_OUT\": \"" << info.total_out << "\"}";
    string payload = s.str();

    mqtt_publish(topic, payload);

    string msg = "MQTT message published to topic: " + topic;
    syslog(LOG_INFO, "%s", msg.c_str());
    syslog(LOG_INFO, "%s", payload.c_str());
}

// message handler for the MQTT subscription for the any desired control channel topic
int handleMQTTControlMessages(void *context, char *topicName, int topicLen, MQTTClient_message *message) {
    string topic = topicName;
    string msg = "MQTT message received: " + topic;
    syslog(LOG_INFO, "%s", msg.c_str());

    return 1;
}

// closestCentroid finds the id of the tracked centroid which is the closest to the point passed in as parameter.
// The function uses euclidean distance as a measure of the closeness of the points and returns both as a pair
pair<int, double> closestCentroid(const Point p, const map<int, Centroid> centroids) {
    int id = 0;
    double dist = DBL_MAX;

    for (map<int, Centroid>::const_iterator it = centroids.begin(); it != centroids.end(); ++it) {
         int _id = it->second.id;
         Point _p = it->second.p;

         // If the movement is horizontal, only consider centroids with some small Y coordinate fluctuation
         if (entrance.compare("l") == 0 || entrance.compare("r") == 0) {
             if ((_p.y < (p.y-70)) || (_p.y > (p.y+70))){
                 continue;
             }
         }

         // If the movement is vertical, only consider centroids with some small X coordinate fluctuation
         if (entrance.compare("b") == 0 || entrance.compare("t") == 0) {
             if (_p.x < (p.x-50) || _p.x > (p.x+50)){
                 continue;
             }
         }

         double dx = double(p.x - _p.x);
         double dy = double(p.y - _p.y);
         double _dist = sqrt(dx*dx + dy*dy);

         if (_dist < dist) {
             dist = _dist;
             id = _id;
         }
    }

    return make_pair(id, dist);
}

// addCentroid adds a new centroid to the list of tracked centroids and increments id counter
void addCentroid(Point p) {
    Centroid c;
    c.id = id;
    c.p = p;
    c.gone_count = 0;

    centroids[c.id] = c;
    id++;
}

// removeCentroid removes existing centroid from the list of tracked centroids
void removeCentroid(int id) {
    centroids.erase(id);
    // find gone centroid id in tracked cars map and mark it as gone
    if (tracked_cars.find(id) != tracked_cars.end()){
        tracked_cars[id].gone = true;
    }
}

// updateCentroids takes detected centroid points and updates tracked centroids
void updateCentroids(vector<Point> points) {
    if (points.size() == 0) {
        for (map<int, Centroid>::iterator it = centroids.begin(); it != centroids.end(); ++it) {
            it->second.gone_count++;
            if (it->second.gone_count > max_frames_gone) {
                removeCentroid(it->second.id);
            }
        }

        return;
    }

    if (centroids.empty()) {
        for(const auto& p: points) {
            addCentroid(p);
        }
    } else {
        set<int> checked_points;
        set<int> checked_centroids;
        // iterate through all detected points and update tracked centroid positions
        for(vector<Point>::size_type i = 0; i != points.size(); i++) {
            pair<int, double> closest = closestCentroid(points[i], centroids);

            // if the distance from the point to the closest centroid is too large, don't associate them together
            // also avoid associating with centroid which already has a different association
            if (closest.second > max_distance || (checked_points.find(closest.first) != checked_points.end())) {
                continue;
            }
            // update position of the closest centroid
            centroids[closest.first].p = points[i];
            centroids[closest.first].gone_count = 0;
            // add centroids to checked points
            checked_points.insert(i);
            checked_centroids.insert(closest.first);
        }

        // iterate through all *already tracked* centroids and increment their gone frame count
        // if they weren't updated from the list of detected centroid points
        for (map<int, Centroid>::iterator it = centroids.begin(); it != centroids.end(); ++it) {
            // if centroid wasn't updated - we assume it's missing from the frame
            if (checked_centroids.find(it->second.id) == checked_centroids.end()) {
                it->second.gone_count++;
                if (it->second.gone_count > max_frames_gone) {
                    removeCentroid(it->second.id);
                }
            }
        }

        // iterate through *detected* centroids and add the ones which werent associated
        // with any of the tracked centroids and add start tracking them
        for(vector<Point>::size_type i = 0; i != points.size(); i++) {
            // if detected point was not associated with any already tracked centroids we add it in
            if (checked_points.find(i) == checked_points.end()) {
                addCentroid(points[i]);
            }
        }
    }

    return;
}

// carMovement calculates movement of the car along particular movement axis according to the entrance position
// as a mean value of all the previous poisitions of the car centroids and returns it
int carMovement(vector<Point> traject, string entrance) {
    int mean_movement = 0;

    for(vector<Point>::size_type i = 0; i != traject.size(); i++) {
        // when movement is horizontal only consider trajectory along X axis
        if (entrance.compare("l") == 0 || entrance.compare("r") == 0) {
            mean_movement = mean_movement + traject[i].x;
        }
        // when movement is vertical only consider trajectory along Y axis
        if (entrance.compare("b") == 0 || entrance.compare("t") == 0) {
            mean_movement = mean_movement + traject[i].y;
        }
    }

    // calculate average centroid movement
    mean_movement = mean_movement / traject.size();

    return mean_movement;
}

// carDirection calculates the direction of the car movement along particular movement axis based on
// the entrance position as a difference between current car's position and its previous movement
int carDirection(Point p, int movement, string entrance) {
    int direction = 0;

    // when movement is horizontal only consider trajectory along X axis
    if (entrance.compare("l") == 0 || entrance.compare("r") == 0) {
       direction = p.x - movement;
    }
    // when movement is vertical only consider trajectory along Y axis
    if (entrance.compare("b") == 0 || entrance.compare("t") == 0) {
        direction = p.y - movement;
    }

    return direction;
}

// centroids2Cars iterates through all centroids and associates them with tracked_cars
void centroids2Cars() {
    // iterate through updated centroids and update tracked car counts
    for (map<int, Centroid>::iterator it = centroids.begin(); it != centroids.end(); ++it) {
        int id = it->second.id;
        Point p = it->second.p;

        Car car;
        // if the centroid is not tracked yet, add it to tracked_cars
        if (tracked_cars.find(id) == tracked_cars.end()) {
            car.id = id;
            car.traject.push_back(p);
            car.counted = false;
            car.gone = false;
            car.direction = 0;
        } else {
            car = tracked_cars[id];
            // calculate mean movement from car trajectory
            int movement = carMovement(car.traject, entrance);
            // add the centroid to the car trajectory
            car.traject.push_back(p);
            // calculate car direction based on trajectory and current position
            car.direction = carDirection(p, movement, entrance);
        }
        tracked_cars[id] = car;
    }
}

// updateCarTotals iterates through all tracked cars and updates total counts both in and out of the parking
void updateCarTotals() {
    for (map<int, Car>::iterator it = tracked_cars.begin(); it != tracked_cars.end(); ++it) {
        int id        = it->second.id;
        int direction = it->second.direction;
        bool gone     = it->second.gone;
        bool counted  = it->second.counted;

        if (!counted) {
            if (!gone){
                if (entrance.compare("t") == 0 || entrance.compare("l") == 0) {
                    // direction is "positive" i.e. movement along Y/X axis goes up
                    if (direction > 0) {
                        total_in++;
                        it->second.counted = true;
                    }
                }

                if (entrance.compare("b") == 0 || entrance.compare("r") == 0) {
                    // direction is "negative" i.e. movement along Y/X axis goes down
                    if (direction < 0) {
                        total_in++;
                        it->second.counted = true;
                    }
                }
            } else {
                if (entrance.compare("t") == 0 || entrance.compare("l") == 0) {
                    // "negative" direction i.e. car centroid coords along movement axis go down
                    if (direction < 0) {
                        total_out++;
                        tracked_cars.erase(id);
                    }
                }

                if (entrance.compare("b") == 0 || entrance.compare("r") == 0) {
                    // "positive" direction i.e. car centroid coords along movement axis go up
                    if (direction > 0) {
                        total_out++;
                        tracked_cars.erase(id);
                    }
                }
            }
        } else {
            if (gone) {
                tracked_cars.erase(id);
            }
        }
    }
}

// Function called by worker thread to process the next available video frame.
void frameRunner() {
    while (keepRunning.load()) {
        Mat next = nextImageAvailable();
        if (!next.empty()) {
            // convert to 4d vector as required by vehicle detection model and detect cars
            blobFromImage(next, blob, 1.0, Size(672, 384));
            net.setInput(blob);
            Mat result = net.forward();

            // get detected cars and in and out counts
            vector<Rect> frame_cars;
            int count_in = 0;
            int count_out = 0;
            float* data = (float*)result.data;

            for (size_t i = 0; i < result.total(); i += 7)
            {
                int label = (int)data[i + 1];
                float confidence = data[i + 2];
                if (label == 1 && confidence > carconf)
                {
                    int left = (int)(data[i + 3] * frame.cols);
                    int top = (int)(data[i + 4] * frame.rows);
                    int right = (int)(data[i + 5] * frame.cols);
                    int bottom = (int)(data[i + 6] * frame.rows);
                    int width = right - left + 1;
                    int height = bottom - top + 1;

                    frame_cars.push_back(Rect(left, top, width, height));
                }
            }

            vector<Point> frame_centroids;
            vector<Rect>  car_detections;
            for(auto const& fc: frame_cars) {
                // make sure the car rect is completely inside the main Mat
                if ((fc & Rect(0, 0, next.cols, next.rows)) != fc) {
                    continue;
                }

                // detected car rectangle dimensions
                int width = fc.width;
                int height = fc.height;
                // if detected rectangle is too small, skip it
                if (width < 70 || height < 70) {
                    continue;
                }

                // Sometimes detected car rectangle stretches way over the actual car dimensions
                // so we clip the sizes of the rectangle to avoid skewing the centroid positions
                int w_clip = 200;
                if (width > w_clip) {
                    if ((fc.x + w_clip) < frame.cols) {
                        width = w_clip;
                    }
                } else if ((fc.x + width) > frame.cols) {
                    width = frame.cols - fc.x;
                }

                int h_clip = 350;
                if (height > h_clip) {
                    if ((fc.y + h_clip) < frame.rows){
                        height = h_clip;
                    }
                } else if ((fc.y + height) > frame.rows) {
                    height = frame.rows - fc.y;
                }

                // calculate detected car centroid coordinates
                int x = fc.x + static_cast<int>(width/2.0);
                int y = fc.y + static_cast<int>(height/2.0);

                // append detected centroid and draw rectangle
                frame_centroids.push_back(Point(x,y));
                car_detections.push_back(Rect(fc.x, fc.y, width, height));
            }

            // update tracked centroids using the centroids detected in the frame
            updateCentroids(frame_centroids);

            // associate centroids with tracked cars
            centroids2Cars();
            // update tracked cars total counters
            updateCarTotals();
            // update analytics and performance info
            updateInfo();
            savePerformanceInfo();
        }
    }

    cout << "Video processing thread stopped" << endl;
}

// Function called by worker thread to handle MQTT updates. Pauses for rate second(s) between updates.
void messageRunner() {
    while (keepRunning.load()) {
        ParkingInfo info = getCurrentInfo();
        publishMQTTMessage(topic, info);
        this_thread::sleep_for(chrono::seconds(rate));
    }

    cout << "MQTT sender thread stopped" << endl;
}

// signal handler for the main thread
void handle_sigterm(int signum)
{
    /* we only handle SIGTERM and SIGKILL here */
    if (signum == SIGTERM) {
        cout << "Interrupt signal (" << signum << ") received" << endl;
        sig_caught = 1;
    }
}

int main(int argc, char** argv)
{
    // parse command parameters
    CommandLineParser parser(argc, argv, keys);
    parser.about("Use this script to using OpenVINO.");
    if (argc == 1 || parser.has("help"))
    {
        parser.printMessage();

        return 0;
    }

    model = parser.get<String>("model");
    config = parser.get<String>("config");
    carconf = parser.get<float>("carconf");
    backendId = parser.get<int>("backend");
    targetId = parser.get<int>("target");
    entrance = parser.get<string>("entrance");
    rate = parser.get<int>("rate");
    max_distance = parser.get<int>("max_distance");
    max_frames_gone = parser.get<int>("max_frames_gone");

    // connect MQTT messaging
    int result = mqtt_start(handleMQTTControlMessages);
    if (result == 0) {
        syslog(LOG_INFO, "MQTT started.");
    } else {
        syslog(LOG_INFO, "MQTT NOT started: have you set the ENV varables?");
    }

    mqtt_connect();

    // read in car detection model
    net = readNet(model, config);
    net.setPreferableBackend(backendId);
    net.setPreferableTarget(targetId);

    // open video capture source
    if (parser.has("input")) {
        cap.open(parser.get<String>("input"));

        // also adjust delay so video playback matches the number of FPS in the file
        double fps = cap.get(CAP_PROP_FPS);
        delay = 1000/fps;
    }
    else
        cap.open(parser.get<int>("device"));

    if (!cap.isOpened()) {
        cerr << "ERROR! Unable to open video source\n";
        return -1;
    }

    // register SIGTERM signal handler
    signal(SIGTERM, handle_sigterm);

    // start worker threads
    thread t1(frameRunner);
    thread t2(messageRunner);

    // read video input data
    for (;;) {
        cap.read(frame);

        if (frame.empty()) {
            keepRunning = false;
            cerr << "ERROR! blank frame grabbed\n";
            break;
        }

        addImage(frame);

        // print Inference Engine performance info
        string label = getCurrentPerf();
        putText(frame, label, Point(0, 25), FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(255, 255, 255));

        ParkingInfo info = getCurrentInfo();
        label = format("Cars In: %d Cars Out: %d", info.total_in, info.total_out);
        putText(frame, label, Point(0, 45), FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(255, 255, 255));
        // draw car centroids
        for (map<int, Centroid>::const_iterator it = info.centroids.begin(); it != info.centroids.end(); ++it) {
            circle(frame, it->second.p, 5.0, CV_RGB(0, 255, 0), 2);
            label = format("[%d, %d]", it->second.p.x, it->second.p.y);
            putText(frame, label, Point(it->second.p.x+5, it->second.p.y),
                            FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(0, 255, 0));
        }

        imshow("Parking Lot Counter", frame);

        if (waitKey(delay) >= 27 || sig_caught) {
            cout << "Attempting to stop background threads" << endl;
            keepRunning = false;
            break;
        }
    }

    // wait for the threads to finish
    t1.join();
    t2.join();
    cap.release();

    // disconnect MQTT messaging
    mqtt_disconnect();
    mqtt_close();

    return 0;
}
Add a comment
Know the answer?
Add Answer to:
Please Implement ParkingLot.cpp below based off the completed Automobile Class and ClaimCheck class down below. Automobile.hpp...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Implement the ParkingLot.cpp with the given ParkingLot.hpp ********************************************************************* ParkingLot.hpp #pragma once #include <queue> #include "ClaimCheck.hpp" #include...

    Implement the ParkingLot.cpp with the given ParkingLot.hpp ********************************************************************* ParkingLot.hpp #pragma once #include <queue> #include "ClaimCheck.hpp" #include "Automobile.hpp" struct ParkedCar { Automobile vehicle_; size_t claimNumber_; }; class ParkingLot { private: std::queue<ParkedCar> parkedCars_; // aisles closed on one end public: ClaimCheck dropOff( const Automobile& vehicle ); Automobile pickUp ( const ClaimCheck& ticket ); size_t quantity(); }; ********************************************************************************* ParkingLot.cpp #include <queue> #include <stdexcept> #include <string> #include "ClaimCheck.hpp" #include "ParkingLot.hpp" /******************************************************************************* ** ParkingLot Member function definitions *******************************************************************************/ ClaimCheck ParkingLot::dropOff( const Automobile& vehicle ) {...

  • This is assignment and code from this site but it will not compile....can you help? home...

    This is assignment and code from this site but it will not compile....can you help? home / study / engineering / computer science / computer science questions and answers / c++ this assignment requires several classes which interact with each other. two class aggregations ... Question: C++ This assignment requires several classes which interact with each other. Two class aggregatio... (1 bookmark) C++ This assignment requires several classes which interact with each other. Two class aggregations are formed. The program...

  • c++ Create a Grocery list dynamically allocated object. also store pointer in to a standard vector...

    c++ Create a Grocery list dynamically allocated object. also store pointer in to a standard vector //GroceryItem.cpp #pragma once // include guard #include <string> #include <iostream> class GroceryItem { // Insertion and Extraction Operators friend std::ostream & operator<<( std::ostream & stream, const GroceryItem & groceryItem ); friend std::istream & operator>>( std::istream & stream, GroceryItem & groceryItem ); // Relational Operators friend bool operator==( const GroceryItem & lhs, const GroceryItem & rhs ); friend bool operator< ( const GroceryItem & lhs,...

  • HELP PLEASE ANSWER 3(c). Consider the following function object: #include <string> class CustomCompare public: bool operator...

    HELP PLEASE ANSWER 3(c). Consider the following function object: #include <string> class CustomCompare public: bool operator (const atd:istringk 1hs, const std::string& rhs) if (1hs. length) 0 && rhs.lengthO 0) return false; int 1 lhs. length )-1; intr rhs. length)-1; return (ro&&10) I Write one C++ statement that defines a variable myCustomPQ, where myCustomPQ is a priority queue storing strings and using CustomCompare.

  • A library maintains a collection of books. Books can be added to and deleted from and...

    A library maintains a collection of books. Books can be added to and deleted from and checked out and checked in to this collection. Title and author name identify a book. Each book object maintains a count of the number of copies available and the number of copies checked out. The number of copies must always be greater than or equal to zero. If the number of copies for a book goes to zero, it must be deleted from the...

  • Hi guys! I need help for the Data Structure class i need to provide implementation of...

    Hi guys! I need help for the Data Structure class i need to provide implementation of the following methods: Destructor Add Subtract Multiply Derive (extra credit ) Evaluate (extra credit ) ------------------------------------------------------- This is Main file cpp file #include "polynomial.h" #include <iostream> #include <sstream> using std::cout; using std::cin; using std::endl; using std::stringstream; int main(int argc, char* argv[]){    stringstream buffer1;    buffer1.str(        "3 -1 2 0 -2.5"    );    Polynomial p(3);    p.Read(buffer1);    cout << p.ToString()...

  • C++ When running my tests for my char constructor the assertion is coming back false and...

    C++ When running my tests for my char constructor the assertion is coming back false and when printing the string garbage is printing that is different everytime but i dont know where it is wrong Requirements: You CANNOT use the C++ standard string or any other libraries for this assignment, except where specified. You must use your ADT string for the later parts of the assignment. using namespace std; is stricly forbiden. As are any global using statements. Name the...

  • Use a B-Tree to implement the set.h class. #ifndef MAIN_SAVITCH_SET_H #define MAIN_SAVITCH_SET_H #include <cstdlib> // Provides...

    Use a B-Tree to implement the set.h class. #ifndef MAIN_SAVITCH_SET_H #define MAIN_SAVITCH_SET_H #include <cstdlib> // Provides size_t namespace main_savitch_11 { template <class Item> class set { public: // TYPEDEFS typedef Item value_type; // CONSTRUCTORS and DESTRUCTOR set( ); set(const set& source); ~set( ) { clear( ); } // MODIFICATION MEMBER FUNCTIONS void operator =(const set& source); void clear( ); bool insert(const Item& entry); std::size_t erase(const Item& target); // CONSTANT MEMBER FUNCTIONS std::size_t count(const Item& target) const; bool empty( ) const...

  • For the LinkedList class, create a getter and setter for the private member 'name', constructing your...

    For the LinkedList class, create a getter and setter for the private member 'name', constructing your definitions based upon the following declarations respectively: std::string get_name() const; and void set_name(std::string); In the Main.cpp file, let's test your getter and setter for the LinkedLIst private member 'name'. In the main function, add the following lines of code: cout << ll.get_name() << endl; ll.make_test_list(); ll.set_name("My List"); cout << ll.get_name() << endl; Output should be: Test List My List Compile and run your code;...

  • // thanks for helping // C++ homework // The homework is to complete below in the...

    // thanks for helping // C++ homework // The homework is to complete below in the stack.h : // 1. the copy constructor // 2. the assignment operator // 3. the destructor // 4. Write a test program (mytest.cpp) to test copy and assignment // 5. Verify destructor by running the test program in Valgrind // This is the main.cpp #include <iostream> #include "stack.h" using namespace std; int main() { Stack<int> intStack; cout << "\nPush integers on stack and dump...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT