Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does cv::circle() only display on a 3D matrix for certain RGB values?

Tags:

c++

opencv

I'm seeing some weird behaviour that I wasn't expecting. On a pure white matrix of type CV_64FC3 (3 channels, floating point values), I'm drawing a coloured circle. The unexpected behaviour is that the circle only actually displays for certain RGB values. Here is sample output for my program for two different colours:

printing a red circle

printing a gray circle

Clearly, the gray circle is missing. My question: Why? And how can I make it appear? Below is my sample code in a small program that you can run.

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

void main()
{
    const unsigned int diam = 200;
    cv::namedWindow("test_window");
    cv::Mat mat(diam, diam, CV_64FC3);

    // force assignment of each pixel to white.
    for (unsigned row = 0; row < diam; ++row)
    {
        for (unsigned col = 0; col < diam; ++col)
        {
            mat.at<cv::Vec3d>(row, col)[0] = 255;
            mat.at<cv::Vec3d>(row, col)[1] = 255;
            mat.at<cv::Vec3d>(row, col)[2] = 255;
        }
    }

    // big gray circle.
    cv::circle(mat, cv::Point(diam/2, diam/2), (diam/2) - 5, CV_RGB(169, 169, 169), -1, CV_AA);

    cv::imshow("test_window", mat);
    cv::waitKey();
}
like image 445
Chris Avatar asked Dec 17 '12 16:12

Chris


1 Answers

You are using float matrix type. From opencv docs:

If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255].

Here is the working code:

#include <opencv2/opencv.hpp>

void main()
{
    const unsigned int diam = 200;
    cv::namedWindow("test_window");
    // force assignment of each pixel to white.
    cv::Mat3b mat = cv::Mat3b(diam, diam, cv::Vec3b(255,255,255));

    // big gray circle.
    cv::circle(mat, cv::Point(diam/2, diam/2), (diam/2) - 5, CV_RGB(169, 169, 169), -1, CV_AA);

    cv::imshow("test_window", mat);
    cv::waitKey();
}

Result:

screenshot

upd.

  1. Do not use loops for matrices filling. Mat::zeros(), Mat::ones() and constructor from example above looks much better.U
  2. Use special cv::MatXY types to prevent runtime errors with wrong types.
like image 185
Rasim Avatar answered Nov 17 '22 13:11

Rasim