Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP [GSoC 2020] Macbeth Chart detection #2532

Merged
merged 22 commits into from
Aug 3, 2020
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions modules/mcc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
set(the_description "Macbeth Chart")
ocv_define_module(mcc opencv_core opencv_imgproc opencv_highgui opencv_calib3d opencv_photo opencv_dnn WRAP python)
garybradski marked this conversation as resolved.
Show resolved Hide resolved
67 changes: 67 additions & 0 deletions modules/mcc/include/opencv2/mcc.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
garybradski marked this conversation as resolved.
Show resolved Hide resolved
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#ifndef __OPENCV_MCC_HPP__
#define __OPENCV_MCC_HPP__

#include "mcc/checker_detector.hpp"
#include "mcc/checker_model.hpp"

/** @defgroup mcc Macbeth Chart module

Introduction
------------

ColorCharts are a tool for calibrating the color profile of camera, which not
only depends on the intrinsic and extrinsic parameters of camera but also on the
lighting conditions. This is done by taking the image of a chart, such that the
value of its colors present in it known, in the image the color values changes
depeding on many variables, this gives us the colors initially present and the
colors that are present in the image, based on this information we can apply any
suitable algorithm to find the actual color of all the objects present in the
image.


*/


#endif
122 changes: 122 additions & 0 deletions modules/mcc/include/opencv2/mcc/checker_detector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#ifndef __OPENCV_MCC_CHECKER_DETECTOR_HPP__
garybradski marked this conversation as resolved.
Show resolved Hide resolved
#define __OPENCV_MCC_CHECKER_DETECTOR_HPP__
#include <opencv2/core.hpp>
#include "checker_model.hpp"
#include <opencv2/dnn.hpp>

//uncomment the following two lines to view debugging output
// #define _DEBUG
// #define SHOW_DEBUG_IMAGES

namespace cv{
namespace mcc{
using namespace dnn;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using namespace is not allowed in public headers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dnn is used for Net. If I replaced using namespace by dnn::Net, python wrapper was giving the error that dnn_Net was not declared. I have added a typedef in misc/pyopencv_cchecker.hpp, but I am not sure if its the best way to solve it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We not sure what the right way to do this? Is this correct @alalek ?

//! @addtogroup mcc
//! @{



/**
* @brief Parameters for the detectMarker process:
*/
struct CV_EXPORTS_W DetectorParameters {

DetectorParameters();

CV_WRAP static Ptr<DetectorParameters> create();

CV_PROP_RW int adaptiveThreshWinSizeMin; ///<minimum window size for adaptive thresholding before finding contours (default 83).
CV_PROP_RW int adaptiveThreshWinSizeMax; ///<maximum window size for adaptive thresholding before finding contours (default 153).
CV_PROP_RW int adaptiveThreshWinSizeStep;///<increments from adaptiveThreshWinSizeMin to adaptiveThreshWinSizeMax during the thresholding (default 10).
CV_PROP_RW double adaptiveThreshConstant; ///<constant for adaptive thresholding before finding contours (default 0)
CV_PROP_RW double minContoursAreaRate;///<determine minimum area for marker contour to be detected. This is defined as a rate respect to the area of the input image. Used only if neural network is used (default 0.003).
CV_PROP_RW double minContoursArea;///<determine minimum area for marker contour to be detected. This is defined as the actual area. Used only if neural network is not used (default 200).
CV_PROP_RW double confidenceThreshold;///<minimum confidence for a bounding box detected by neural network to classify as detection. (default 0.5) (0<=confidenceThreshold<=1)
garybradski marked this conversation as resolved.
Show resolved Hide resolved
CV_PROP_RW double minContourSolidity;///<minimum solidity of a contour for it be detected as a square in the chart. (default 0.9).
CV_PROP_RW double findCandidatesApproxPolyDPEpsMultiplier;///<multipler to be used in cv::ApproxPolyDP function (default 0.05)
CV_PROP_RW int borderWidth;///<width of the padding used to pass the inital neural network detection in the succeeding system.(default 0)
CV_PROP_RW float B0factor;///< distance between two neighbours squares of the same chart. Defined as the ratio between distance and large dimension of square (default 1.25)
CV_PROP_RW float maxError;///<maximum allowed error in the detection of a chart. default(0.1)
CV_PROP_RW int minContourPointsAllowed;///< minium points in a detected contour. default(4)
CV_PROP_RW int minContourLengthAllowed;///<minimum length of a countour. default(100)
CV_PROP_RW int minInterContourDistance;///< minimum distance between two contours. default(100)
CV_PROP_RW int minInterCheckerDistance;///<minimum distance between two checkers. default(10000)
CV_PROP_RW int minImageSize;///<minimum size of the smaller dimension of the image. default(2000)
CV_PROP_RW unsigned minGroupSize;///<minimum number of a squared of a chart that must be detected. default(4)

};



/** @brief A class to find the positions of the ColorCharts in the image.
*/

class CV_EXPORTS_W CCheckerDetector: public Algorithm
{
public:

/** \brief Set the net which will be used to find the approximate
* bounding boxes for the color charts.
*
* It is not necessary to use this, but this usually results in
* better detection rate.
*
* \param net the neural network, if the network in empty, then
* the function will return false.
* \return true if it was able to set the detector's network,
* false otherwise.
*/


CV_WRAP virtual bool setNet(Net net) = 0;

/** \brief Find the ColorCharts in the given image.
*
* The found charts are not returned but instead stored in the
* detector, these can be accessed later on using getBestColorChecker()
* and getListColorChecker()
* \param image image in color space BGR
* \param chartType type of the chart to detect
* \param nc number of charts in the image, if you don't know the exact
* then keeping this number high helps.
* \param useNet if it is true the network provided using the setNet()
* is used for preliminary search for regions where chart
* could be present, inside the regionsOfInterest provied.
* \param params parameters of the detection system. More information
* about them can be found in the struct DetectorParameters.
* \param regionsOfInterest regions of image to look for the chart, if
* it is empty, charts are looked for in the
* entire image
* \return true if atleast one chart is detected otherwise false
*/

CV_WRAP virtual bool
process(const cv::Mat &image, const TYPECHART chartType, const int nc = 1,
garybradski marked this conversation as resolved.
Show resolved Hide resolved
bool useNet=false,
const Ptr<DetectorParameters> &params = DetectorParameters::create(),
std::vector<Rect> regionsOfInterest = std::vector<cv::Rect>()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"const reference" for std::vector

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Earlier I was adding an element corresponding to full image if the original vector was emtpy, so couldn't use const. Now I have replaced it by two overloaded functions, with const reference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alalek Is over loading a good solution to this?

) = 0 ;

/** \brief Get the best color checker. By the best it means the one
* detected with the highest confidence.
* \param checker [out] A single colorchecker
*/
CV_WRAP virtual void getBestColorChecker(Ptr<mcc::CChecker> &checker) = 0;
garybradski marked this conversation as resolved.
Show resolved Hide resolved

/** \brief Get the list of all detected colorcheckers
* \param checkers [out] vector of colorcheckers
*/
CV_WRAP virtual void getListColorChecker(std::vector<Ptr<CChecker>> &checkers) = 0;

/** \brief Returns the implementation of the CCheckerDetector.
*
*/
CV_WRAP static Ptr<CCheckerDetector> create();
};

//! @} mcc

} // namespace mcc
} // namespace cv

#endif
96 changes: 96 additions & 0 deletions modules/mcc/include/opencv2/mcc/checker_model.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@

#ifndef __OPENCV_MCC_CHECKER_MODEL_HPP__
#define __OPENCV_MCC_CHECKER_MODEL_HPP__
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
namespace cv
{
namespace mcc
{

//! @addtogroup mcc
//! @{

/** TYPECHART
*
* \brief enum to hold the type of the checker
*
*/
enum TYPECHART
{
MCC24=0, ///< Standard Macbeth Chart with 24 squares
SG140, ///< DigitalSG with 140 squares
VINYL18,///< DKK color chart with 12 squares and 6 rectangle

};

/** CChecker
*
* \brief checker object
*
* This class contains the information about the detected checkers,i.e, their
* type, the corners of the chart, the color profile, the cost, centers chart,
* etc.
*
*/

class CV_EXPORTS_W CChecker
{
public:
CChecker(){}
~CChecker(){}
/** \brief Create a new CChecker object.
* \return A pointer to the implementation of the CChecker
*/

CV_WRAP static Ptr<CChecker> create();

public:
CV_PROP_RW TYPECHART target; ///< type of checkercolor
CV_PROP_RW std::vector<cv::Point2f> box; ///< positions of the corners
CV_PROP_RW cv::Mat charts_rgb; ///< charts profile in rgb color space
CV_PROP_RW cv::Mat charts_ycbcr; ///< charts profile in YCbCr color space
CV_PROP_RW float cost; ///< cost to aproximate
CV_PROP_RW cv::Point2f center; ///< center of the chart.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal implementation details should not be exposed in public headers.

Public API should contain interfaces, with several "get"/"set" virtual methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Should I do the same for DetectorParameters also?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alalek This is fixed, but is the DetectorParameters correct also (no functions are in this, just variables) ... so this is resolved, correct?

};

/** \brief checker draw
*
* This class contains the functions for drawing a detected chart. This
* class expects a pointer to the checker which will be drawn by this
* object in the constructor and then later on whenever the draw function
* is called the checker will be drawn. Remember that it is not possible
* to change the checkers which will be draw by a given object, as it is
* decided in the constructor itself. If you want to draw some other
* object you can create a new CCheckerDraw instance.
*
* The reason for this type of design is that in some videos we can
* assume that the checker is always in the same position, even if the
* image changes, so the drawing will always take place at the same position.
*/
class CV_EXPORTS_W CCheckerDraw
{

public:
virtual ~CCheckerDraw() {}
/** \brief Draws the checker to the given image.
* \param img image in color space BGR
* \return void
*/
CV_WRAP virtual void draw(cv::Mat &img) = 0;
garybradski marked this conversation as resolved.
Show resolved Hide resolved
/** \brief Create a new CCheckerDraw object.
* \param pChecker The checker which will be drawn by this object.
* \param color The color by with which the squares of the checker
* will be drawn
* \param thickness The thickness with which the sqaures will be
* drawn
* \return A pointer to the implementation of the CCheckerDraw
*/
CV_WRAP static Ptr<CCheckerDraw> create(Ptr<CChecker> pChecker, cv::Scalar color = CV_RGB(0, 250, 0), int thickness = 2);
};

//! @} mcc
} // namespace mcc
} // namespace cv

#endif
15 changes: 15 additions & 0 deletions modules/mcc/misc/python/pyopencv_CChecker.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "opencv2/mcc.hpp"
garybradski marked this conversation as resolved.
Show resolved Hide resolved

template<> struct pyopencvVecConverter<Ptr<mcc::CChecker>>
{
static bool to(PyObject* obj, std::vector<Ptr<mcc::CChecker>>& value, const ArgInfo& info)
{
return pyopencv_to_generic_vec(obj, value, info);
}

static PyObject* from(const std::vector<Ptr<mcc::CChecker>>& value)
{
return pyopencv_from_generic_vec(value);
}
};
typedef std::vector<cv::Ptr<mcc::CChecker>> vector_Ptr_CChecker;
Loading