<p dir="auto">Transferred from <a href="http://code.opencv.org/issues/4455" rel="nofollow">http://code.opencv.org/issues/4455</a></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="|| Jens Garstka on 2015-07-01 08:32
|| Priority: Normal
|| Affected: branch 'master' (3.0-dev)
|| Category: ml
|| Tracker: Bug
|| Difficulty: Easy
|| PR: 
|| Platform: x64 / Linux"><pre class="notranslate"><code class="notranslate">|| Jens Garstka on 2015-07-01 08:32
|| Priority: Normal
|| Affected: branch 'master' (3.0-dev)
|| Category: ml
|| Tracker: Bug
|| Difficulty: Easy
|| PR: 
|| Platform: x64 / Linux
</code></pre></div>
<h2 dir="auto">SVM write/load problems with kernels other than linear</h2>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Within the implementation of the SVMs write and read methods (modules/ml/src/svm.cpp, lines 2022 ff and 2139 ff), the author makes the assumption, that support vector indices are not required in 2-class problems. That is probably correct if a linear kernel is used (i.e., when you have only one support vector). But with other kernels (in my case with an RBF kernel), the support vector indices are definitly required.

I've added a git diff where this questionable conditions are commented out. Without these lines everything works fine. 

IMHO the lines should be removed."><pre class="notranslate"><code class="notranslate">Within the implementation of the SVMs write and read methods (modules/ml/src/svm.cpp, lines 2022 ff and 2139 ff), the author makes the assumption, that support vector indices are not required in 2-class problems. That is probably correct if a linear kernel is used (i.e., when you have only one support vector). But with other kernels (in my case with an RBF kernel), the support vector indices are definitly required.

I've added a git diff where this questionable conditions are commented out. Without these lines everything works fine. 

IMHO the lines should be removed.
</code></pre></div>
<h2 dir="auto">History</h2>
<h5 dir="auto">Hyunjun Kim on 2015-07-03 07:35</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Hi, I was able to reproduce the error. I confirmed that cv::Algorithm::load() works well only with SVM::LINEAR kernel.

&lt;pre&gt;
#include &lt;opencv2/core.hpp&gt;
#include &lt;opencv2/imgproc.hpp&gt;
#include &quot;opencv2/imgcodecs.hpp&quot;
#include &lt;opencv2/highgui.hpp&gt;
#include &lt;opencv2/ml.hpp&gt;

using namespace cv;
using namespace cv::ml;

int main(int, char**)
{
    // Data for visual representation
    int width = 512, height = 512;
    Mat image = Mat::zeros(height, width, CV_8UC3);

    // Set up training data
    int labels[4] = {1, -1, -1, -1};
    Mat labelsMat(4, 1, CV_32SC1, labels);

    float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
    Mat trainingDataMat(4, 2, CV_32FC1, trainingData);

    // Set up SVM's parameters
    Ptr&lt;ml::SVM&gt; svm = ml::SVM::create();
    svm-&gt;setType(ml::SVM::C_SVC);
    svm-&gt;setKernel(SVM::INTER); // Algorithm::load() works well with SVM::LINEAR
    svm-&gt;setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

    // Train the SVM
    svm-&gt;train(ml::TrainData::create(trainingDataMat, ml::ROW_SAMPLE, labelsMat));

    // Save and load SVM
    svm-&gt;save(&quot;ex_svm.xml&quot;);
    svm= cv::Algorithm::load&lt;ml::SVM&gt;(&quot;ex_svm.xml&quot;); // something is wrong


    Vec3b green(0,255,0), blue (255,0,0);
    // Show the decision regions given by the SVM
    for (int i = 0; i &lt; image.rows; ++i)
        for (int j = 0; j &lt; image.cols; ++j)
        {
            Mat sampleMat = (Mat_&lt;float&gt;(1,2) &lt;&lt; j,i);
            float response = svm-&gt;predict(sampleMat);

            if (response == 1)
                image.at&lt;Vec3b&gt;(i,j)  = green;
            else if (response == -1)
                image.at&lt;Vec3b&gt;(i,j)  = blue;
        }

    // Show the training data
    int thickness = -1;
    int lineType = 8;
    circle( image, Point(501,  10), 5, Scalar(  0,   0,   0), thickness, lineType );
    circle( image, Point(255,  10), 5, Scalar(255, 255, 255), thickness, lineType );
    circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType );
    circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType );

    // Show support vectors
    thickness = 2;
    lineType  = 8;

    Mat sv = svm-&gt;getSupportVectors();

    for (int i = 0; i &lt; sv.rows; ++i)
    {
        const float* v = sv.ptr&lt;float&gt;(i);
        circle( image,  Point( (int) v[0], (int) v[1]),   6,  Scalar(128, 128, 128), thickness, lineType);
    }

    imwrite(&quot;result.png&quot;, image);        // save the image

    imshow(&quot;SVM Simple Example&quot;, image); // show it to the user
    waitKey(0);

}
&lt;/pre&gt;"><pre class="notranslate"><code class="notranslate">Hi, I was able to reproduce the error. I confirmed that cv::Algorithm::load() works well only with SVM::LINEAR kernel.

&lt;pre&gt;
#include &lt;opencv2/core.hpp&gt;
#include &lt;opencv2/imgproc.hpp&gt;
#include "opencv2/imgcodecs.hpp"
#include &lt;opencv2/highgui.hpp&gt;
#include &lt;opencv2/ml.hpp&gt;

using namespace cv;
using namespace cv::ml;

int main(int, char**)
{
    // Data for visual representation
    int width = 512, height = 512;
    Mat image = Mat::zeros(height, width, CV_8UC3);

    // Set up training data
    int labels[4] = {1, -1, -1, -1};
    Mat labelsMat(4, 1, CV_32SC1, labels);

    float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
    Mat trainingDataMat(4, 2, CV_32FC1, trainingData);

    // Set up SVM's parameters
    Ptr&lt;ml::SVM&gt; svm = ml::SVM::create();
    svm-&gt;setType(ml::SVM::C_SVC);
    svm-&gt;setKernel(SVM::INTER); // Algorithm::load() works well with SVM::LINEAR
    svm-&gt;setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

    // Train the SVM
    svm-&gt;train(ml::TrainData::create(trainingDataMat, ml::ROW_SAMPLE, labelsMat));

    // Save and load SVM
    svm-&gt;save("ex_svm.xml");
    svm= cv::Algorithm::load&lt;ml::SVM&gt;("ex_svm.xml"); // something is wrong


    Vec3b green(0,255,0), blue (255,0,0);
    // Show the decision regions given by the SVM
    for (int i = 0; i &lt; image.rows; ++i)
        for (int j = 0; j &lt; image.cols; ++j)
        {
            Mat sampleMat = (Mat_&lt;float&gt;(1,2) &lt;&lt; j,i);
            float response = svm-&gt;predict(sampleMat);

            if (response == 1)
                image.at&lt;Vec3b&gt;(i,j)  = green;
            else if (response == -1)
                image.at&lt;Vec3b&gt;(i,j)  = blue;
        }

    // Show the training data
    int thickness = -1;
    int lineType = 8;
    circle( image, Point(501,  10), 5, Scalar(  0,   0,   0), thickness, lineType );
    circle( image, Point(255,  10), 5, Scalar(255, 255, 255), thickness, lineType );
    circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType );
    circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType );

    // Show support vectors
    thickness = 2;
    lineType  = 8;

    Mat sv = svm-&gt;getSupportVectors();

    for (int i = 0; i &lt; sv.rows; ++i)
    {
        const float* v = sv.ptr&lt;float&gt;(i);
        circle( image,  Point( (int) v[0], (int) v[1]),   6,  Scalar(128, 128, 128), thickness, lineType);
    }

    imwrite("result.png", image);        // save the image

    imshow("SVM Simple Example", image); // show it to the user
    waitKey(0);

}
&lt;/pre&gt;
</code></pre></div>
<h5 dir="auto">Maksim Shabunin on 2015-07-13 08:56</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="-   Assignee set to Maksim Shabunin"><pre class="notranslate"><code class="notranslate">-   Assignee set to Maksim Shabunin
</code></pre></div>
<h5 dir="auto">System information (version)</h5>

<ul dir="auto">
<li>OpenCV =&gt; 4.1.1</li>
<li>Operating System / Platform =&gt; Windows 10 64bit</li>
<li>Compiler =&gt; Visual Studio 2019 16.2.0</li>
</ul>
<h5 dir="auto">Detailed description</h5>
<p dir="auto">I have an original image in green tones:<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/42886604/62464462-570d2480-b795-11e9-8773-86ff3e6953fd.png"><img src="https://user-images.githubusercontent.com/42886604/62464462-570d2480-b795-11e9-8773-86ff3e6953fd.png" alt="raw" style="max-width: 100%;"></a><br>
In legacy code with OpenCV 3.1.0 it was converted to normal colors with:<br>
<code class="notranslate">cv::cvtColor(Mat(size.height, size.width, CV_16UC1, rawRight.data), frameRight, color);	// convert CV_8UC2 to CV_16UC1</code><br>
And it's work ok.<br>
But when I update OpenCV 4.1.1. And it began to work with problems. Instead of the image with normal colors received:<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/42886604/62464713-ff22ed80-b795-11e9-8a0a-7c8aebe3dec6.jpg"><img src="https://user-images.githubusercontent.com/42886604/62464713-ff22ed80-b795-11e9-8a0a-7c8aebe3dec6.jpg" alt="vBlahj5N1Vk" style="max-width: 100%;"></a><br>
I tried sorting through all the methods from enum:<br>
<a href="https://docs.opencv.org/4.1.1/d8/d01/group__imgproc__color__conversions.html#ga4e0972be5de079fed4e3a10e24ef5ef0" rel="nofollow">https://docs.opencv.org/4.1.1/d8/d01/group__imgproc__color__conversions.html#ga4e0972be5de079fed4e3a10e24ef5ef0</a><br>
but not one made the colors right.<br>
OpenCV gives the following image information:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[i] channels:  3
[i] pixel depth: 0 bits
[i] elemSize:       3 bytes
[i] elemSize1:       1 bytes
[i] type: CV_8UC3"><pre class="notranslate"><code class="notranslate">[i] channels:  3
[i] pixel depth: 0 bits
[i] elemSize:       3 bytes
[i] elemSize1:       1 bytes
[i] type: CV_8UC3
</code></pre></div>
<p dir="auto">I would be grateful for any help.</p>