OpenCV 4.10.0-dev
Open Source Computer Vision
Loading...
Searching...
No Matches
Detecting colorcheckers using basic algorithms

In this tutorial you will learn how to use the 'mcc' module to detect colorcharts in a image. Here we will only use the basic detection algorithm. In the next tutorial you will see how you can improve detection accuracy using a neural network.

Building

When building OpenCV, run the following command to build all the contrib module:

cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/

Or only build the mcc module:

cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/mcc

Or make sure you check the mcc module in the GUI version of CMake: cmake-gui.

Source Code of the sample

run
<path_of_your_opencv_build_directory>/bin/example_mcc_chart_detection -t=<type_of_chart> -v=<optional_path_to_video_if_not_provided_webcam_will_be_used.mp4> --ci=<optional_camera_id_needed_only_if_video_not_provided> --nc=<optional_maximum_number_of_charts_to_look_for>
  • -t=# is the chart type where 0 (Standard), 1 (DigitalSG), 2 (Vinyl)
  • –ci=# is the camera ID where 0 (default is the main camera), 1 (secondary camera) etc
  • –nc=# By default its values is 1 which means only the best chart will be detected

Examples:

Run a movie on a standard macbeth chart:
/home/opencv/build/bin/example_mcc_chart_detection -t=0 -v=mcc24.mp4
Or run on a vinyl macbeth chart from camera 0:
/home/opencv/build/bin/example_mcc_chart_detection -t=2 --ci=0
Or run on a vinyl macbeth chart, detecting the best 5 charts(Detections can be less than 5 but never more):
/home/opencv/build/bin/example_mcc_chart_detection -t=2 --ci=0 --nc=5
1#include <opencv2/core.hpp>
2
3#include <opencv2/highgui.hpp>
4#include <opencv2/mcc.hpp>
5#include <iostream>
6
7using namespace std;
8using namespace cv;
9using namespace mcc;
10
11const char *about = "Basic chart detection";
12const char *keys = {
13 "{ help h usage ? | | show this message }"
14 "{t | | chartType: 0-Standard, 1-DigitalSG, 2-Vinyl }"
15 "{v | | Input from video file, if ommited, input comes from camera }"
16 "{ci | 0 | Camera id if input doesnt come from video (-v) }"
17 "{nc | 1 | Maximum number of charts in the image }"};
18
19int main(int argc, char *argv[])
20{
21
22 // ----------------------------------------------------------
23 // Scroll down a bit (~40 lines) to find actual relevant code
24 // ----------------------------------------------------------
25
26 CommandLineParser parser(argc, argv, keys);
27 parser.about(about);
28
29 int t = parser.get<int>("t");
30
31 CV_Assert(0 <= t && t <= 2);
32 TYPECHART chartType = TYPECHART(t);
33
34 int camId = parser.get<int>("ci");
35 int nc = parser.get<int>("nc");
36 String video;
37 if (parser.has("v"))
38 video = parser.get<String>("v");
39
40 if (!parser.check())
41 {
42 parser.printErrors();
43 return 0;
44 }
45
46 VideoCapture inputVideo;
47 int waitTime;
48 if (!video.empty())
49 {
50 inputVideo.open(video);
51 waitTime = 10;
52 }
53 else
54 {
55 inputVideo.open(camId);
56 waitTime = 10;
57 }
58
59 //--------------------------------------------------------------------------
60 //-------------------------Actual Relevant Code-----------------------------
61 //--------------------------------------------------------------------------
62
63 while (inputVideo.grab())
64 {
65
66 Mat image, imageCopy;
67 inputVideo.retrieve(image);
68 imageCopy = image.clone();
69 Ptr<CCheckerDetector> detector = CCheckerDetector::create();
70 // Marker type to detect
71 if (!detector->process(image, chartType, nc))
72 {
73 printf("ChartColor not detected \n");
74 }
75 else
76 {
77
78 // get checker
79 std::vector<Ptr<mcc::CChecker>> checkers = detector->getListColorChecker();
80
81 for (Ptr<mcc::CChecker> checker : checkers)
82 {
83 // current checker
84 Ptr<CCheckerDraw> cdraw = CCheckerDraw::create(checker);
85 cdraw->draw(image);
86 }
87 }
88 imshow("image result | q or esc to quit", image);
89 imshow("original", imageCopy);
90 char key = (char)waitKey(waitTime);
91 if (key == 27)
92 break;
93 }
94
95 return 0;
96}
Designed for command line parsing.
Definition utility.hpp:890
n-dimensional dense array class
Definition mat.hpp:829
CV_NODISCARD_STD Mat clone() const
Creates a full copy of the array and the underlying data.
Class for video capturing from video files, image sequences or cameras.
Definition videoio.hpp:747
virtual bool open(const String &filename, int apiPreference=CAP_ANY)
Opens a video file or a capturing device or an IP video stream for video capturing.
virtual bool retrieve(OutputArray image, int flag=0)
Decodes and returns the grabbed video frame.
virtual bool grab()
Grabs the next frame from video file or capturing device.
std::string String
Definition cvstd.hpp:151
std::shared_ptr< _Tp > Ptr
Definition cvstd_wrapper.hpp:23
#define CV_Assert(expr)
Checks a condition at runtime and throws exception if it fails.
Definition base.hpp:359
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
int waitKey(int delay=0)
Waits for a pressed key.
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3
Definition core.hpp:107
STL namespace.

Explanation

  1. Set header and namespaces

    #include <opencv2/mcc.hpp>
    using namespace std;
    using namespace cv;
    using namespace mcc;

    If you want you can set the namespace like the code above.

  2. Create the detector object

    Ptr<CCheckerDetector> detector = CCheckerDetector::create();

    This is just to create the object.

  3. Run the detector

    detector->process(image, chartType);

    If the detector successfully detects atleast one chart, it return true otherwise it returns false. In the above given code we print a failure message if no chart were detected. Otherwise if it were successful, the list of colorcharts is stored inside the detector itself, we will see in the next step on how to extract it. By default it will detect atmost one chart, but you can tune the third parameter, nc(maximum number of charts), for detecting more charts.

  4. Get List of ColorCheckers

    std::vector<cv::Ptr<mcc::CChecker>> checkers;
    detector->getListColorChecker(checkers);

    All the colorcheckers that were detected are now stored in the 'checkers' vector.

  5. Draw the colorcheckers back to the image

    for(Ptr<mcc::CChecker> checker : checkers)
    {
    // current checker
    Ptr<CCheckerDraw> cdraw = CCheckerDraw::create(checker);
    cdraw->draw(image);
    }

    Loop through all the checkers one by one and then draw them.