void RectangleExpositor::calculate(Image & evaluation, JSON & data)
    {
        int numberOfChanges = 0;
        Rectangle rectangle(evaluation.getColumns(), evaluation.getRows(), 0, 0);

        // -----------------------------------
        // loop over image and detect changes

        for(int i = m_x1; i < m_x2; i++)
        {
            for(int j = m_y1; j < m_y2; j++)
            {
                if(static_cast<int>(evaluation.get(j,i)) == 255)
                {
                    numberOfChanges++;
                    if(rectangle.m_x1>i) rectangle.m_x1 = i;
                    if(rectangle.m_x2<i) rectangle.m_x2 = i;
                    if(rectangle.m_y1>j) rectangle.m_y1 = j;
                    if(rectangle.m_y2<j) rectangle.m_y2 = j;
                }
            }
        }

        // -------------------------
        //check if not out of bounds

        if(rectangle.m_x1-10 > 0) rectangle.m_x1 -= 10;
        if(rectangle.m_y1-10 > 0) rectangle.m_y1 -= 10;
        if(rectangle.m_x2+10 < evaluation.getColumns()-1) rectangle.m_x2 += 10;
        if(rectangle.m_y2+10 < evaluation.getRows()-1) rectangle.m_y2 += 10;

        // --------------------------
        // Add coordinates to object

        JSON::AllocatorType& allocator = data.GetAllocator();

        JSONValue region;
        region.SetArray();
        region.PushBack(rectangle.m_x1, allocator);
        region.PushBack(rectangle.m_y1, allocator);
        region.PushBack(rectangle.m_x2, allocator);
        region.PushBack(rectangle.m_y2, allocator);

        data.AddMember("regionCoordinates", region, allocator);

        // --------------------------
        // Add number of changes

        if(numberOfChanges)
        {
            LINFO << "RectangleExpositor: activity detected from (" +  helper::to_string(rectangle.m_x1) + "," + helper::to_string(rectangle.m_y1) + ") to (" +  helper::to_string(rectangle.m_x2) + "," + helper::to_string(rectangle.m_y2) + ")";
        }

        data.AddMember("numberOfChanges", numberOfChanges, allocator);
    }
示例#2
0
    bool IoWebhook::save(Image & image, JSON & data)
    {
        // ---------------------------------------
        // Attach additional fields to JSON object
        
        JSON dataCopy;
        JSON::AllocatorType& allocator = dataCopy.GetAllocator();
        dataCopy.CopyFrom(data, allocator);
        
        JSONValue instanceName;
        instanceName.SetString(getInstanceName().c_str(), allocator);
        dataCopy.AddMember("instanceName", instanceName, allocator);
        
        // -----------------------------
        // Convert JSON object to string
        
        rapidjson::StringBuffer buffer;
        rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
        dataCopy.Accept(writer);
        
        // -------------------
        // Send a post to URL

        BINFO << "IoWebhook: post to webhook " + (std::string) getUrl();
        RestClient::response r = RestClient::post(getUrl(), "application/json", buffer.GetString());
        
        if(r.code == 200)
        {
            return true;
        }
        
        return false;
    }
示例#3
0
    bool IoDisk::save(Image & image, JSON & data)
    {
        // ----------------------------------------
        // The naming convention that will be used
        // for the image.
        
        std::string pathToImage = getFileFormat();

        // ------------------------------------------
        // Stringify data object: build image path
        // with data information.
        
        static const std::string kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };
        for (JSONValue::ConstMemberIterator itr = data.MemberBegin(); itr != data.MemberEnd(); ++itr)
        {
            std::string name = itr->name.GetString();
            std::string type = kTypeNames[itr->value.GetType()];
            
            if(type == "String")
            {
                std::string value = itr->value.GetString();
                kerberos::helper::replace(pathToImage, name, value);
            }
            else if(type == "Number")
            {
                std::string value = kerberos::helper::to_string(itr->value.GetInt());
                kerberos::helper::replace(pathToImage, name, value);
            }
            else if(type == "Array")
            {
                std::string arrayString = "";
                for (JSONValue::ConstValueIterator itr2 = itr->value.Begin(); itr2 != itr->value.End(); ++itr2)
                {
                    type = kTypeNames[itr2->GetType()];
                    
                    if(type == "String")
                    {
                        arrayString += itr2->GetString();
                    }
                    else if(type == "Number")
                    {
                       arrayString += kerberos::helper::to_string(itr2->GetInt());
                    }
                    
                    arrayString += "-";
                }
                kerberos::helper::replace(pathToImage, name, arrayString.substr(0, arrayString.size()-1));
            }
        }
        
        /// ---------------------
        // Replace variables

        pathToImage = buildPath(pathToImage);

        // -------------------------------------------------------
        // Add path to JSON object, so other IO devices can use it
        
        JSONValue path;
        JSON::AllocatorType& allocator = data.GetAllocator();
        path.SetString(pathToImage.c_str(), allocator);
        data.AddMember("pathToImage", path, allocator);
        
        // ------------------
        // Draw date on image
        
        drawDateOnImage(image, data["timestamp"].GetString());
        
        // -------------------------
        // Save original version

        BINFO << "IoDisk: saving image " + pathToImage;
        return m_fileManager.save(image, pathToImage);
    }
示例#4
0
    bool Counter::isValid(const Image & evaluation, const ImageVector & images, JSON & data)
    {
        int numberOfChanges;
        Rectangle rectangle;
        numberOfChanges = data["numberOfChanges"].GetInt();

        int incoming = 0;
        int outgoing = 0;
        
        kerberos::Image image = evaluation;
        cv::Mat img = image.getImage();
        cv::dilate(img, img, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(25,25)));
        cv::erode(img, img, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10,10)));

        cv::Point & outTop = m_out[0];
        cv::Point & outBottom = m_out[1];
 
        cv::Point & inTop = m_in[0];
        cv::Point & inBottom = m_in[1];
        
        std::vector<std::vector<cv::Point> > contours;
        std::vector<cv::Vec4i> hierarchy;
        cv::findContours(image.getImage(), contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
        
        int numberOfContours= 0;
        for(int i = 0; i < m_features.size(); i++)
        {
            int mostRecent = m_features[i].size() - 1;
            m_features[i][mostRecent].decreaseAppearance();
        }
        
        // Find new tracks
        if(contours.size() > 0)
        {
            for( int i = 0; i< contours.size(); i++ )
            {
                cv::Moments moments = cv::moments(contours[i]);
                int x = moments.m10/moments.m00;
                int y = moments.m01/moments.m00;
                int area = cv::contourArea(contours[i]);
                
                if(area < m_minArea) continue;
            
                Feature current(x, y, area, m_appearance);
                int best = -1;
                double bestValue = 99999999;
                double bestArea = 99999999;
            
                for(int j = 0; j < m_features.size(); j++)
                {
                    int mostRecent = m_features[j].size() - 1;
                    double distance = current.distance(m_features[j][mostRecent]);
                    double areaDistance = current.areaDistance(m_features[j][mostRecent]);
                
                    if(distance < m_maxDistance && distance < bestValue + m_maxDistance/2)
                    {
                        if(areaDistance < bestArea)
                        {
                            best = j;
                            bestValue = distance;
                        }
                    }
                }
            
                if(best == -1)
                {
                    std::vector<Feature> tracking;
                    tracking.push_back(current);
                    m_features.push_back(tracking);
                }
                else
                {
                    m_features[best].push_back(current);
                }
            
                numberOfContours++;
            }
        }
        
        // Remove old tracks
        std::vector<std::vector<Feature> >::iterator it = m_features.begin();
        while(it != m_features.end())
        {
            Feature & back = it->back();
            back.decreaseAppearance();
            
            if(back.getAppearance() < 0)
            {
                it = m_features.erase(it);
            }
            else
            {
                it++;
            }
        }
        
        // Check existing tracks if they crossed the line
        it = m_features.begin();
        while(it != m_features.end())
        {
            if(it->size() > 1)
            {
                for(int j = 1; j < it->size(); j++)
                {
                    cv::Point2f prev((*it)[j-1].getX(),(*it)[j-1].getY());
                    cv::Point2f curr((*it)[j].getX(),(*it)[j].getY());
                }
                
                // Check if cross line
                cv::Point2f start((*it)[0].getX(),(*it)[0].getY());
                cv::Point2f end((*it)[it->size()-1].getX(),(*it)[it->size()-1].getY());
                
                // Check if interset in line
                cv::Point2f intersectionPointOutgoing;
                bool inLine = false;
                if(intersection(start, end, outTop, outBottom, intersectionPointOutgoing))
                {
                    inLine = true;
                }
                // Check if interset out line
                cv::Point2f intersectionPointIncoming;
                bool outLine = false;
                if(intersection(start, end, inTop, inBottom, intersectionPointIncoming))
                {
                    outLine = true;
                }
                
                // Check if interesected both
                Direction xDirection = parallell;
                Direction yDirection = parallell;
                
                if(inLine && outLine)
                {
                    // What is the direction (incoming our outgoing?)
                    if(start.x - end.x < 0)
                    {
                        xDirection = right;
                    }
                    else if(start.x - end.x > 0)
                    {
                        xDirection = left;
                    }
                    if(start.y - end.y < 0)
                    {
                        yDirection = bottom;
                    }
                    else if(start.y - end.y > 0)
                    {
                        yDirection = top;
                    }
                    
                    // Check which intersection point comes first
                    if(xDirection != parallell)
                    {
                        if(xDirection == left)
                        {
                            // Check which intersection point is most right;
                            if(intersectionPointIncoming.x > intersectionPointOutgoing.x)
                            {
                                incoming++;
                            }
                            else
                            {
                                outgoing++;
                            }
                        }
                        else if(xDirection == right)
                        {
                            // Check which intersection point is most right;
                            if(intersectionPointIncoming.x < intersectionPointOutgoing.x)
                            {
                                incoming++;
                            }
                            else
                            {
                                outgoing++;
                            }
                        }
                    }
                    else
                    {
                        
                    }
                    
                    it = m_features.erase(it);
                }
                else
                {
                    it++;
                }
            }
            else
            {
                it++;
            }
        }

        if(numberOfChanges >= m_minimumChanges)
        {
            JSON::AllocatorType& allocator = data.GetAllocator();
            data.AddMember("incoming", incoming, allocator);
            data.AddMember("outgoing", outgoing, allocator);
            
            if(m_onlyTrueWhenCounted)
            {
                if(incoming > 0 || outgoing > 0)
                {
                    BINFO << "Counter: in (" << helper::to_string(incoming) << "), out (" << helper::to_string(outgoing) << ")";
                    return true;
                }
            }
            else
            {
                return true;
            }
        }
        else
        {
            usleep(m_noMotionDelayTime*1000);
        }
        
        return false;
    }
TEST(SEQUENCE_HEURISTIC, IS_VALID)
{
    Heuristic * heuristic = Factory<Heuristic>::getInstance()->create("Sequence");

    StringMap settings;
    settings["heuristics.Sequence.minimumChanges"] = "1";
    settings["heuristics.Sequence.minimumDuration"] = "2";
    settings["heuristics.Sequence.motionDelayTime"] = "1000";
    settings["heuristics.Sequence.noMotionDelayTime"] = "1000";
    heuristic->setup(settings);

    // ----------------------------
    // Mocking image

    Image image;
    ImageVector images;

    JSON json;
    JSON::AllocatorType& allocator = json.GetAllocator();

    json.SetObject();
    json.AddMember("numberOfChanges", 0, allocator);

    // --------------------
    // Nothing changed thus false.
    bool isValid = heuristic->isValid(image, images, json);
    EXPECT_EQ(false, isValid);

    // ---------------------
    // Changed, but this is only the first occurence thus again false.
    json.RemoveMember ("numberOfChanges");
    json.AddMember("numberOfChanges", 1, allocator);
    isValid = heuristic->isValid(image, images, json);
    EXPECT_EQ(false, isValid);

    // ---------------------
    // Changed and the second occurence thus true.
    isValid = heuristic->isValid(image, images, json);
    EXPECT_EQ(true, isValid);
}