{"action":"created","comment":{"url":"https://api.github.com/repos/Itseez/opencv/pulls/comments/54100699","id":54100699,"diff_hunk":"@@ -0,0 +1,517 @@\n+/*M///////////////////////////////////////////////////////////////////////////////////////\n+//\n+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\n+//\n+//  By downloading, copying, installing or using the software you agree to this license.\n+//  If you do not agree to this license, do not download, install,\n+//  copy or use the software.\n+//\n+//\n+//                           License Agreement\n+//                For Open Source Computer Vision Library\n+//\n+// Copyright (C) 2000, Intel Corporation, all rights reserved.\n+// Copyright (C) 2016, Itseez Inc, all rights reserved.\n+// Third party copyrights are property of their respective owners.\n+//\n+// Redistribution and use in source and binary forms, with or without modification,\n+// are permitted provided that the following conditions are met:\n+//\n+//   * Redistribution's of source code must retain the above copyright notice,\n+//     this list of conditions and the following disclaimer.\n+//\n+//   * Redistribution's in binary form must reproduce the above copyright notice,\n+//     this list of conditions and the following disclaimer in the documentation\n+//     and/or other materials provided with the distribution.\n+//\n+//   * The name of the copyright holders may not be used to endorse or promote products\n+//     derived from this software without specific prior written permission.\n+//\n+// This software is provided by the copyright holders and contributors \"as is\" and\n+// any express or implied warranties, including, but not limited to, the implied\n+// warranties of merchantability and fitness for a particular purpose are disclaimed.\n+// In no event shall the Intel Corporation or contributors be liable for any direct,\n+// indirect, incidental, special, exemplary, or consequential damages\n+// (including, but not limited to, procurement of substitute goods or services;\n+// loss of use, data, or profits; or business interruption) however caused\n+// and on any theory of liability, whether in contract, strict liability,\n+// or tort (including negligence or otherwise) arising in any way out of\n+// the use of this software, even if advised of the possibility of such damage.\n+//\n+//M*/\n+\n+#include \"precomp.hpp\"\n+#include \"limits\"\n+\n+#include <iostream>\n+\n+using std::cout;\n+using std::endl;\n+\n+/****************************************************************************************\\\n+*                        Stochastic Gradient Descent SVM Classifier                      *\n+\\****************************************************************************************/\n+\n+namespace cv\n+{\n+namespace ml\n+{\n+\n+class SVMSGDImpl : public SVMSGD\n+{\n+\n+public:\n+    SVMSGDImpl();\n+\n+    virtual ~SVMSGDImpl() {}\n+\n+    virtual bool train(const Ptr<TrainData>& data, int);\n+\n+    virtual float predict( InputArray samples, OutputArray results=noArray(), int flags = 0 ) const;\n+\n+    virtual bool isClassifier() const;\n+\n+    virtual bool isTrained() const;\n+\n+    virtual void clear();\n+\n+    virtual void write(FileStorage &fs) const;\n+\n+    virtual void read(const FileNode &fn);\n+\n+    virtual Mat getWeights(){ return weights_; }\n+\n+    virtual float getShift(){ return shift_; }\n+\n+    virtual int getVarCount() const { return weights_.cols; }\n+\n+    virtual String getDefaultName() const {return \"opencv_ml_svmsgd\";}\n+\n+    virtual void setOptimalParameters(int svmsgdType = ASGD, int marginType = SOFT_MARGIN);\n+\n+    CV_IMPL_PROPERTY(int, SvmsgdType, params.svmsgdType)\n+    CV_IMPL_PROPERTY(int, MarginType, params.marginType)\n+    CV_IMPL_PROPERTY(float, MarginRegularization, params.marginRegularization)\n+    CV_IMPL_PROPERTY(float, InitialStepSize, params.initialStepSize)\n+    CV_IMPL_PROPERTY(float, StepDecreasingPower, params.stepDecreasingPower)\n+    CV_IMPL_PROPERTY_S(cv::TermCriteria, TermCriteria, params.termCrit)\n+\n+private:\n+    void updateWeights(InputArray sample, bool isPositive, float stepSize, Mat &weights);\n+\n+    void writeParams( FileStorage &fs ) const;\n+\n+    void readParams( const FileNode &fn );\n+\n+    static inline bool isPositive(float val) { return val > 0; }\n+\n+    static void normalizeSamples(Mat &matrix, Mat &average, float &multiplier);\n+\n+    float calcShift(InputArray _samples, InputArray _responses) const;\n+\n+    static void makeExtendedTrainSamples(const Mat &trainSamples, Mat &extendedTrainSamples, Mat &average, float &multiplier);\n+\n+\n+\n+    // Vector with SVM weights\n+    Mat weights_;\n+    float shift_;\n+\n+    // Parameters for learning\n+    struct SVMSGDParams\n+    {\n+        float marginRegularization;\n+        float initialStepSize;\n+        float stepDecreasingPower;\n+        TermCriteria termCrit;\n+        int svmsgdType;\n+        int marginType;\n+    };\n+\n+    SVMSGDParams params;\n+};\n+\n+Ptr<SVMSGD> SVMSGD::create()\n+{\n+    return makePtr<SVMSGDImpl>();\n+}\n+\n+void SVMSGDImpl::normalizeSamples(Mat &samples, Mat &average, float &multiplier)\n+{\n+    int featuresCount = samples.cols;\n+    int samplesCount = samples.rows;\n+\n+    average = Mat(1, featuresCount, samples.type());\n+    CV_Assert(average.type() ==  CV_32FC1);\n+    for (int featureIndex = 0; featureIndex < featuresCount; featureIndex++)\n+    {\n+        average.at<float>(featureIndex) = static_cast<float>(mean(samples.col(featureIndex))[0]);\n+    }\n+\n+    for (int sampleIndex = 0; sampleIndex < samplesCount; sampleIndex++)\n+    {\n+        samples.row(sampleIndex) -= average;\n+    }\n+\n+    double normValue = norm(samples);\n+\n+    multiplier = static_cast<float>(sqrt(samples.total()) / normValue);\n+\n+    samples *= multiplier;\n+}\n+\n+void SVMSGDImpl::makeExtendedTrainSamples(const Mat &trainSamples, Mat &extendedTrainSamples, Mat &average, float &multiplier)\n+{\n+    Mat normalizedTrainSamples = trainSamples.clone();\n+    int samplesCount = normalizedTrainSamples.rows;\n+\n+    normalizeSamples(normalizedTrainSamples, average, multiplier);\n+\n+    Mat onesCol = Mat::ones(samplesCount, 1, CV_32F);\n+    cv::hconcat(normalizedTrainSamples, onesCol, extendedTrainSamples);\n+}\n+\n+void SVMSGDImpl::updateWeights(InputArray _sample, bool positive, float stepSize, Mat& weights)\n+{\n+    Mat sample = _sample.getMat();\n+\n+    int response = positive ? 1 : -1; // ensure that trainResponses are -1 or 1\n+\n+    if ( sample.dot(weights) * response > 1)\n+    {\n+        // Not a support vector, only apply weight decay\n+        weights *= (1.f - stepSize * params.marginRegularization);\n+    }\n+    else\n+    {\n+        // It's a support vector, add it to the weights\n+        weights -= (stepSize * params.marginRegularization) * weights - (stepSize * response) * sample;\n+    }\n+}\n+\n+float SVMSGDImpl::calcShift(InputArray _samples, InputArray _responses) const\n+{\n+    float margin[2] = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };\n+\n+    Mat trainSamples = _samples.getMat();\n+    int trainSamplesCount = trainSamples.rows;\n+\n+    Mat trainResponses = _responses.getMat();\n+\n+    CV_Assert(trainResponses.type() ==  CV_32FC1);\n+    for (int samplesIndex = 0; samplesIndex < trainSamplesCount; samplesIndex++)\n+    {\n+        Mat currentSample = trainSamples.row(samplesIndex);\n+        float dotProduct = static_cast<float>(currentSample.dot(weights_));\n+\n+        bool positive = isPositive(trainResponses.at<float>(samplesIndex));\n+        int index = positive ? 0 : 1;\n+        float signToMul = positive ? 1.f : -1.f;\n+        float curMargin = dotProduct * signToMul;\n+\n+        if (curMargin < margin[index])\n+        {\n+            margin[index] = curMargin;\n+        }\n+    }\n+\n+    return -(margin[0] - margin[1]) / 2.f;\n+}\n+\n+bool SVMSGDImpl::train(const Ptr<TrainData>& data, int)\n+{\n+    clear();\n+    CV_Assert( isClassifier() );   //toDo: consider\n+\n+    Mat trainSamples = data->getTrainSamples();\n+\n+    int featureCount = trainSamples.cols;\n+    Mat trainResponses = data->getTrainResponses();        // (trainSamplesCount x 1) matrix\n+\n+    CV_Assert(trainResponses.rows == trainSamples.rows);\n+\n+    if (trainResponses.empty())\n+    {\n+        return false;\n+    }\n+\n+    int positiveCount = countNonZero(trainResponses >= 0);\n+    int negativeCount = countNonZero(trainResponses < 0);\n+\n+    if ( positiveCount <= 0 || negativeCount <= 0 )\n+    {\n+        weights_ = Mat::zeros(1, featureCount, CV_32F);\n+        shift_ = (positiveCount > 0) ? 1.f : -1.f;\n+        return true;\n+    }\n+\n+    Mat extendedTrainSamples;\n+    Mat average;\n+    float multiplier = 0;\n+    makeExtendedTrainSamples(trainSamples, extendedTrainSamples, average, multiplier);\n+\n+    int extendedTrainSamplesCount = extendedTrainSamples.rows;\n+    int extendedFeatureCount = extendedTrainSamples.cols;\n+\n+    Mat extendedWeights = Mat::zeros(1, extendedFeatureCount, CV_32F);\n+    Mat previousWeights = Mat::zeros(1, extendedFeatureCount, CV_32F);\n+    Mat averageExtendedWeights;\n+    if (params.svmsgdType == ASGD)\n+    {\n+        averageExtendedWeights = Mat::zeros(1, extendedFeatureCount, CV_32F);\n+    }\n+\n+    RNG rng(0);\n+\n+    CV_Assert ((params.termCrit.type & TermCriteria::COUNT || params.termCrit.type & TermCriteria::EPS) && (trainResponses.type() == CV_32FC1));\n+    int maxCount = (params.termCrit.type & TermCriteria::COUNT) ? params.termCrit.maxCount : INT_MAX;\n+    double epsilon = (params.termCrit.type & TermCriteria::EPS) ? params.termCrit.epsilon : 0;\n+\n+    double err = DBL_MAX;\n+    // Stochastic gradient descent SVM\n+    for (int iter = 0; (iter < maxCount) && (err > epsilon); iter++)\n+    {\n+        int randomNumber = rng.uniform(0, extendedTrainSamplesCount);             //generate sample number\n+\n+        Mat currentSample = extendedTrainSamples.row(randomNumber);\n+\n+        float stepSize = params.initialStepSize * std::pow((1 + params.marginRegularization * params.initialStepSize * (float)iter), (-params.stepDecreasingPower));    //update stepSize\n+\n+        updateWeights( currentSample, isPositive(trainResponses.at<float>(randomNumber)), stepSize, extendedWeights );\n+\n+        //average weights (only for ASGD model)\n+        if (params.svmsgdType == ASGD)\n+        {\n+            averageExtendedWeights = ((float)iter/ (1 + (float)iter)) * averageExtendedWeights  + extendedWeights / (1 + (float) iter);\n+            err = norm(averageExtendedWeights - previousWeights);\n+            averageExtendedWeights.copyTo(previousWeights);\n+        }\n+        else\n+        {\n+             err = norm(extendedWeights - previousWeights);\n+             extendedWeights.copyTo(previousWeights);\n+        }\n+    }\n+\n+    if (params.svmsgdType == ASGD)\n+    {\n+        extendedWeights = averageExtendedWeights;\n+    }\n+\n+    Rect roi(0, 0, featureCount, 1);\n+    weights_ = extendedWeights(roi);\n+    weights_ *= multiplier;\n+\n+    CV_Assert((params.marginType == SOFT_MARGIN || params.marginType == HARD_MARGIN) && (extendedWeights.type() ==  CV_32FC1));\n+\n+    if (params.marginType == SOFT_MARGIN)\n+    {\n+        shift_ = extendedWeights.at<float>(featureCount) - static_cast<float>(weights_.dot(average));\n+    }\n+    else\n+    {\n+        shift_ = calcShift(trainSamples, trainResponses);\n+    }\n+\n+    return true;\n+}\n+\n+\n+float SVMSGDImpl::predict( InputArray _samples, OutputArray _results, int ) const\n+{\n+    float result = 0;\n+    cv::Mat samples = _samples.getMat();\n+    int nSamples = samples.rows;\n+    cv::Mat results;\n+\n+    CV_Assert( samples.cols == weights_.cols && samples.type() == CV_32FC1);\n+\n+    if( _results.needed() )\n+    {\n+        _results.create( nSamples, 1, samples.type() );\n+        results = _results.getMat();\n+    }\n+    else\n+    {\n+        CV_Assert( nSamples == 1 );\n+        results = Mat(1, 1, CV_32FC1, &result);\n+    }\n+\n+    for (int sampleIndex = 0; sampleIndex < nSamples; sampleIndex++)\n+    {\n+        Mat currentSample = samples.row(sampleIndex);\n+        float criterion = static_cast<float>(currentSample.dot(weights_)) + shift_;\n+        results.at<float>(sampleIndex) = (criterion >= 0) ? 1.f : -1.f;\n+    }\n+\n+    return result;\n+}\n+\n+bool SVMSGDImpl::isClassifier() const\n+{\n+    return (params.svmsgdType == SGD || params.svmsgdType == ASGD)\n+            &&\n+            (params.marginType == SOFT_MARGIN || params.marginType == HARD_MARGIN)\n+            &&\n+            (params.marginRegularization > 0) && (params.initialStepSize > 0) && (params.stepDecreasingPower >= 0);\n+}\n+\n+bool SVMSGDImpl::isTrained() const\n+{\n+    return !weights_.empty();\n+}\n+\n+void SVMSGDImpl::write(FileStorage& fs) const\n+{\n+    if( !isTrained() )\n+        CV_Error( CV_StsParseError, \"SVMSGD model data is invalid, it hasn't been trained\" );\n+\n+    writeParams( fs );\n+\n+    fs << \"weights\" << weights_;\n+    fs << \"shift\" << shift_;\n+}\n+\n+void SVMSGDImpl::writeParams( FileStorage& fs ) const\n+{\n+    String SvmsgdTypeStr;\n+\n+    switch (params.svmsgdType)\n+    {\n+    case SGD:\n+        SvmsgdTypeStr = \"SGD\";\n+        break;\n+    case ASGD:\n+        SvmsgdTypeStr = \"ASGD\";\n+        break;\n+    default:\n+        SvmsgdTypeStr = format(\"Unknown_%d\", params.svmsgdType);\n+    }\n+\n+    fs << \"svmsgdType\" << SvmsgdTypeStr;\n+\n+    String marginTypeStr;\n+\n+    switch (params.marginType)\n+    {\n+    case SOFT_MARGIN:\n+        marginTypeStr = \"SOFT_MARGIN\";\n+        break;\n+    case HARD_MARGIN:\n+        marginTypeStr = \"HARD_MARGIN\";\n+        break;\n+    default:\n+        marginTypeStr = format(\"Unknown_%d\", params.marginType);\n+    }\n+\n+    fs << \"marginType\" << marginTypeStr;\n+\n+    fs << \"marginRegularization\" << params.marginRegularization;\n+    fs << \"initialStepSize\" << params.initialStepSize;\n+    fs << \"stepDecreasingPower\" << params.stepDecreasingPower;\n+\n+    fs << \"term_criteria\" << \"{:\";\n+    if( params.termCrit.type & TermCriteria::EPS )\n+        fs << \"epsilon\" << params.termCrit.epsilon;\n+    if( params.termCrit.type & TermCriteria::COUNT )\n+        fs << \"iterations\" << params.termCrit.maxCount;\n+    fs << \"}\";\n+}\n+\n+void SVMSGDImpl::read(const FileNode& fn)\n+{\n+    clear();\n+\n+    readParams(fn);\n+\n+    fn[\"weights\"] >> weights_;\n+    fn[\"shift\"] >> shift_;\n+}\n+\n+void SVMSGDImpl::readParams( const FileNode& fn )\n+{\n+    String svmsgdTypeStr = (String)fn[\"svmsgdType\"];\n+    int svmsgdType =\n+            svmsgdTypeStr == \"SGD\" ? SGD :\n+                                     svmsgdTypeStr == \"ASGD\" ? ASGD : -1;\n+\n+    if( svmsgdType < 0 )\n+        CV_Error( CV_StsParseError, \"Missing or invalid SVMSGD type\" );\n+\n+    params.svmsgdType = svmsgdType;\n+\n+    String marginTypeStr = (String)fn[\"marginType\"];\n+    int marginType =\n+            marginTypeStr == \"SOFT_MARGIN\" ? SOFT_MARGIN :\n+                                     marginTypeStr == \"HARD_MARGIN\" ? HARD_MARGIN : -1;\n+\n+    if( marginType < 0 )\n+        CV_Error( CV_StsParseError, \"Missing or invalid margin type\" );\n+\n+    params.marginType = marginType;\n+\n+    CV_Assert ( fn[\"marginRegularization\"].isReal() );\n+    params.marginRegularization = (float)fn[\"marginRegularization\"];\n+\n+    CV_Assert ( fn[\"initialStepSize\"].isReal() );\n+    params.initialStepSize = (float)fn[\"initialStepSize\"];\n+\n+    CV_Assert ( fn[\"stepDecreasingPower\"].isReal() );\n+    params.stepDecreasingPower = (float)fn[\"stepDecreasingPower\"];\n+\n+    FileNode tcnode = fn[\"term_criteria\"];\n+    if( !tcnode.empty() )\n+    {\n+        params.termCrit.epsilon = (double)tcnode[\"epsilon\"];\n+        params.termCrit.maxCount = (int)tcnode[\"iterations\"];\n+        params.termCrit.type = (params.termCrit.epsilon > 0 ? TermCriteria::EPS : 0) +\n+                (params.termCrit.maxCount > 0 ? TermCriteria::COUNT : 0);\n+    }\n+    else\n+        params.termCrit = TermCriteria( TermCriteria::EPS + TermCriteria::COUNT, 100000, FLT_EPSILON );","path":"modules/ml/src/svmsgd.cpp","position":471,"original_position":471,"commit_id":"d484893839c568ceebd09fdc9e7ba15fb002dcd5","original_commit_id":"d484893839c568ceebd09fdc9e7ba15fb002dcd5","user":{"login":"snosov1","id":2784626,"avatar_url":"https://avatars.githubusercontent.com/u/2784626?v=3","gravatar_id":"","url":"https://api.github.com/users/snosov1","html_url":"https://github.com/snosov1","followers_url":"https://api.github.com/users/snosov1/followers","following_url":"https://api.github.com/users/snosov1/following{/other_user}","gists_url":"https://api.github.com/users/snosov1/gists{/gist_id}","starred_url":"https://api.github.com/users/snosov1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snosov1/subscriptions","organizations_url":"https://api.github.com/users/snosov1/orgs","repos_url":"https://api.github.com/users/snosov1/repos","events_url":"https://api.github.com/users/snosov1/events{/privacy}","received_events_url":"https://api.github.com/users/snosov1/received_events","type":"User","site_admin":false},"body":"I think a better idea is to call `setOptimalParameters` first. And do nothing if some of the parameters weren't set.","created_at":"2016-02-25T14:22:13Z","updated_at":"2016-02-25T14:22:13Z","html_url":"https://github.com/Itseez/opencv/pull/6096#discussion_r54100699","pull_request_url":"https://api.github.com/repos/Itseez/opencv/pulls/6096","_links":{"self":{"href":"https://api.github.com/repos/Itseez/opencv/pulls/comments/54100699"},"html":{"href":"https://github.com/Itseez/opencv/pull/6096#discussion_r54100699"},"pull_request":{"href":"https://api.github.com/repos/Itseez/opencv/pulls/6096"}}},"pull_request":{"url":"https://api.github.com/repos/Itseez/opencv/pulls/6096","id":58902512,"html_url":"https://github.com/Itseez/opencv/pull/6096","diff_url":"https://github.com/Itseez/opencv/pull/6096.diff","patch_url":"https://github.com/Itseez/opencv/pull/6096.patch","issue_url":"https://api.github.com/repos/Itseez/opencv/issues/6096","number":6096,"state":"open","locked":false,"title":"Mn/svmsgd to opencv3 0","user":{"login":"mnoskova","id":16774024,"avatar_url":"https://avatars.githubusercontent.com/u/16774024?v=3","gravatar_id":"","url":"https://api.github.com/users/mnoskova","html_url":"https://github.com/mnoskova","followers_url":"https://api.github.com/users/mnoskova/followers","following_url":"https://api.github.com/users/mnoskova/following{/other_user}","gists_url":"https://api.github.com/users/mnoskova/gists{/gist_id}","starred_url":"https://api.github.com/users/mnoskova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mnoskova/subscriptions","organizations_url":"https://api.github.com/users/mnoskova/orgs","repos_url":"https://api.github.com/users/mnoskova/repos","events_url":"https://api.github.com/users/mnoskova/events{/privacy}","received_events_url":"https://api.github.com/users/mnoskova/received_events","type":"User","site_admin":false},"body":"**Merge with extra**: https://github.com/Itseez/opencv_extra/pull/288\r\n\r\nImplemented SVMSGD classifier.","created_at":"2016-02-10T15:04:58Z","updated_at":"2016-02-25T14:22:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8d83a6e51750ced26d1e9e1eec3241d09a8afe59","assignee":{"login":"vpisarev","id":2110786,"avatar_url":"https://avatars.githubusercontent.com/u/2110786?v=3","gravatar_id":"","url":"https://api.github.com/users/vpisarev","html_url":"https://github.com/vpisarev","followers_url":"https://api.github.com/users/vpisarev/followers","following_url":"https://api.github.com/users/vpisarev/following{/other_user}","gists_url":"https://api.github.com/users/vpisarev/gists{/gist_id}","starred_url":"https://api.github.com/users/vpisarev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vpisarev/subscriptions","organizations_url":"https://api.github.com/users/vpisarev/orgs","repos_url":"https://api.github.com/users/vpisarev/repos","events_url":"https://api.github.com/users/vpisarev/events{/privacy}","received_events_url":"https://api.github.com/users/vpisarev/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/Itseez/opencv/pulls/6096/commits","review_comments_url":"https://api.github.com/repos/Itseez/opencv/pulls/6096/comments","review_comment_url":"https://api.github.com/repos/Itseez/opencv/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Itseez/opencv/issues/6096/comments","statuses_url":"https://api.github.com/repos/Itseez/opencv/statuses/d484893839c568ceebd09fdc9e7ba15fb002dcd5","head":{"label":"mnoskova:mn/SVMSGD_to_opencv3_0","ref":"mn/SVMSGD_to_opencv3_0","sha":"d484893839c568ceebd09fdc9e7ba15fb002dcd5","user":{"login":"mnoskova","id":16774024,"avatar_url":"https://avatars.githubusercontent.com/u/16774024?v=3","gravatar_id":"","url":"https://api.github.com/users/mnoskova","html_url":"https://github.com/mnoskova","followers_url":"https://api.github.com/users/mnoskova/followers","following_url":"https://api.github.com/users/mnoskova/following{/other_user}","gists_url":"https://api.github.com/users/mnoskova/gists{/gist_id}","starred_url":"https://api.github.com/users/mnoskova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mnoskova/subscriptions","organizations_url":"https://api.github.com/users/mnoskova/orgs","repos_url":"https://api.github.com/users/mnoskova/repos","events_url":"https://api.github.com/users/mnoskova/events{/privacy}","received_events_url":"https://api.github.com/users/mnoskova/received_events","type":"User","site_admin":false},"repo":{"id":51439598,"name":"opencv","full_name":"mnoskova/opencv","owner":{"login":"mnoskova","id":16774024,"avatar_url":"https://avatars.githubusercontent.com/u/16774024?v=3","gravatar_id":"","url":"https://api.github.com/users/mnoskova","html_url":"https://github.com/mnoskova","followers_url":"https://api.github.com/users/mnoskova/followers","following_url":"https://api.github.com/users/mnoskova/following{/other_user}","gists_url":"https://api.github.com/users/mnoskova/gists{/gist_id}","starred_url":"https://api.github.com/users/mnoskova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mnoskova/subscriptions","organizations_url":"https://api.github.com/users/mnoskova/orgs","repos_url":"https://api.github.com/users/mnoskova/repos","events_url":"https://api.github.com/users/mnoskova/events{/privacy}","received_events_url":"https://api.github.com/users/mnoskova/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mnoskova/opencv","description":"Open Source Computer Vision Library","fork":true,"url":"https://api.github.com/repos/mnoskova/opencv","forks_url":"https://api.github.com/repos/mnoskova/opencv/forks","keys_url":"https://api.github.com/repos/mnoskova/opencv/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mnoskova/opencv/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mnoskova/opencv/teams","hooks_url":"https://api.github.com/repos/mnoskova/opencv/hooks","issue_events_url":"https://api.github.com/repos/mnoskova/opencv/issues/events{/number}","events_url":"https://api.github.com/repos/mnoskova/opencv/events","assignees_url":"https://api.github.com/repos/mnoskova/opencv/assignees{/user}","branches_url":"https://api.github.com/repos/mnoskova/opencv/branches{/branch}","tags_url":"https://api.github.com/repos/mnoskova/opencv/tags","blobs_url":"https://api.github.com/repos/mnoskova/opencv/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mnoskova/opencv/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mnoskova/opencv/git/refs{/sha}","trees_url":"https://api.github.com/repos/mnoskova/opencv/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mnoskova/opencv/statuses/{sha}","languages_url":"https://api.github.com/repos/mnoskova/opencv/languages","stargazers_url":"https://api.github.com/repos/mnoskova/opencv/stargazers","contributors_url":"https://api.github.com/repos/mnoskova/opencv/contributors","subscribers_url":"https://api.github.com/repos/mnoskova/opencv/subscribers","subscription_url":"https://api.github.com/repos/mnoskova/opencv/subscription","commits_url":"https://api.github.com/repos/mnoskova/opencv/commits{/sha}","git_commits_url":"https://api.github.com/repos/mnoskova/opencv/git/commits{/sha}","comments_url":"https://api.github.com/repos/mnoskova/opencv/comments{/number}","issue_comment_url":"https://api.github.com/repos/mnoskova/opencv/issues/comments{/number}","contents_url":"https://api.github.com/repos/mnoskova/opencv/contents/{+path}","compare_url":"https://api.github.com/repos/mnoskova/opencv/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mnoskova/opencv/merges","archive_url":"https://api.github.com/repos/mnoskova/opencv/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mnoskova/opencv/downloads","issues_url":"https://api.github.com/repos/mnoskova/opencv/issues{/number}","pulls_url":"https://api.github.com/repos/mnoskova/opencv/pulls{/number}","milestones_url":"https://api.github.com/repos/mnoskova/opencv/milestones{/number}","notifications_url":"https://api.github.com/repos/mnoskova/opencv/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mnoskova/opencv/labels{/name}","releases_url":"https://api.github.com/repos/mnoskova/opencv/releases{/id}","deployments_url":"https://api.github.com/repos/mnoskova/opencv/deployments","created_at":"2016-02-10T12:25:36Z","updated_at":"2016-02-10T12:25:47Z","pushed_at":"2016-02-25T13:59:09Z","git_url":"git://github.com/mnoskova/opencv.git","ssh_url":"git@github.com:mnoskova/opencv.git","clone_url":"https://github.com/mnoskova/opencv.git","svn_url":"https://github.com/mnoskova/opencv","homepage":"opencv.org","size":417805,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Itseez:master","ref":"master","sha":"b529b37d06b73665305503dc7bf68fde0c12a917","user":{"login":"Itseez","id":1786446,"avatar_url":"https://avatars.githubusercontent.com/u/1786446?v=3","gravatar_id":"","url":"https://api.github.com/users/Itseez","html_url":"https://github.com/Itseez","followers_url":"https://api.github.com/users/Itseez/followers","following_url":"https://api.github.com/users/Itseez/following{/other_user}","gists_url":"https://api.github.com/users/Itseez/gists{/gist_id}","starred_url":"https://api.github.com/users/Itseez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Itseez/subscriptions","organizations_url":"https://api.github.com/users/Itseez/orgs","repos_url":"https://api.github.com/users/Itseez/repos","events_url":"https://api.github.com/users/Itseez/events{/privacy}","received_events_url":"https://api.github.com/users/Itseez/received_events","type":"Organization","site_admin":false},"repo":{"id":5108051,"name":"opencv","full_name":"Itseez/opencv","owner":{"login":"Itseez","id":1786446,"avatar_url":"https://avatars.githubusercontent.com/u/1786446?v=3","gravatar_id":"","url":"https://api.github.com/users/Itseez","html_url":"https://github.com/Itseez","followers_url":"https://api.github.com/users/Itseez/followers","following_url":"https://api.github.com/users/Itseez/following{/other_user}","gists_url":"https://api.github.com/users/Itseez/gists{/gist_id}","starred_url":"https://api.github.com/users/Itseez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Itseez/subscriptions","organizations_url":"https://api.github.com/users/Itseez/orgs","repos_url":"https://api.github.com/users/Itseez/repos","events_url":"https://api.github.com/users/Itseez/events{/privacy}","received_events_url":"https://api.github.com/users/Itseez/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Itseez/opencv","description":"Open Source Computer Vision Library","fork":false,"url":"https://api.github.com/repos/Itseez/opencv","forks_url":"https://api.github.com/repos/Itseez/opencv/forks","keys_url":"https://api.github.com/repos/Itseez/opencv/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Itseez/opencv/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Itseez/opencv/teams","hooks_url":"https://api.github.com/repos/Itseez/opencv/hooks","issue_events_url":"https://api.github.com/repos/Itseez/opencv/issues/events{/number}","events_url":"https://api.github.com/repos/Itseez/opencv/events","assignees_url":"https://api.github.com/repos/Itseez/opencv/assignees{/user}","branches_url":"https://api.github.com/repos/Itseez/opencv/branches{/branch}","tags_url":"https://api.github.com/repos/Itseez/opencv/tags","blobs_url":"https://api.github.com/repos/Itseez/opencv/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Itseez/opencv/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Itseez/opencv/git/refs{/sha}","trees_url":"https://api.github.com/repos/Itseez/opencv/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Itseez/opencv/statuses/{sha}","languages_url":"https://api.github.com/repos/Itseez/opencv/languages","stargazers_url":"https://api.github.com/repos/Itseez/opencv/stargazers","contributors_url":"https://api.github.com/repos/Itseez/opencv/contributors","subscribers_url":"https://api.github.com/repos/Itseez/opencv/subscribers","subscription_url":"https://api.github.com/repos/Itseez/opencv/subscription","commits_url":"https://api.github.com/repos/Itseez/opencv/commits{/sha}","git_commits_url":"https://api.github.com/repos/Itseez/opencv/git/commits{/sha}","comments_url":"https://api.github.com/repos/Itseez/opencv/comments{/number}","issue_comment_url":"https://api.github.com/repos/Itseez/opencv/issues/comments{/number}","contents_url":"https://api.github.com/repos/Itseez/opencv/contents/{+path}","compare_url":"https://api.github.com/repos/Itseez/opencv/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Itseez/opencv/merges","archive_url":"https://api.github.com/repos/Itseez/opencv/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Itseez/opencv/downloads","issues_url":"https://api.github.com/repos/Itseez/opencv/issues{/number}","pulls_url":"https://api.github.com/repos/Itseez/opencv/pulls{/number}","milestones_url":"https://api.github.com/repos/Itseez/opencv/milestones{/number}","notifications_url":"https://api.github.com/repos/Itseez/opencv/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Itseez/opencv/labels{/name}","releases_url":"https://api.github.com/repos/Itseez/opencv/releases{/id}","deployments_url":"https://api.github.com/repos/Itseez/opencv/deployments","created_at":"2012-07-19T09:40:17Z","updated_at":"2016-02-25T14:13:35Z","pushed_at":"2016-02-25T13:59:16Z","git_url":"git://github.com/Itseez/opencv.git","ssh_url":"git@github.com:Itseez/opencv.git","clone_url":"https://github.com/Itseez/opencv.git","svn_url":"https://github.com/Itseez/opencv","homepage":"opencv.org","size":1064029,"stargazers_count":8390,"watchers_count":8390,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7240,"mirror_url":null,"open_issues_count":949,"forks":7240,"open_issues":949,"watchers":8390,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Itseez/opencv/pulls/6096"},"html":{"href":"https://github.com/Itseez/opencv/pull/6096"},"issue":{"href":"https://api.github.com/repos/Itseez/opencv/issues/6096"},"comments":{"href":"https://api.github.com/repos/Itseez/opencv/issues/6096/comments"},"review_comments":{"href":"https://api.github.com/repos/Itseez/opencv/pulls/6096/comments"},"review_comment":{"href":"https://api.github.com/repos/Itseez/opencv/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Itseez/opencv/pulls/6096/commits"},"statuses":{"href":"https://api.github.com/repos/Itseez/opencv/statuses/d484893839c568ceebd09fdc9e7ba15fb002dcd5"}}}}