OpenCV 5.0.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 5.0.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
カラーチェッカーの検出

このチュートリアルでは、'mcc' モジュールを使って画像内のカラーチャートを検出する方法を学ぶ。ここでは基本的な検出アルゴリズムと、ニューラルネットワークを用いて精度を向上させた改良版のみを使用する。

サンプルのソースコード

run
<path_of_your_opencv_build_directory>/bin/example_cpp_macbeth_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=# はチャートの種類で、0 (Standard)、1 (DigitalSG)、2 (Vinyl)
  • –ci=# はカメラIDで、0 (デフォルトはメインカメラ)、1 (セカンダリカメラ) など
  • –nc=# デフォルト値は1で、最良のチャートのみを検出することを意味する

例:

Run a movie on a standard macbeth chart:
/home/opencv/build/bin/example_cpp_macbeth_chart_detection -t=0 -v=mcc24.mp4
Or run on a vinyl macbeth chart from camera 0:
/home/opencv/build/bin/example_cpp_macbeth_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_cpp_macbeth_chart_detection -t=2 --ci=0 --nc=5
Simple run on CPU with neural network (GPU wont be used)
/home/opencv/build/bin/example_cpp_macbeth_chart_detection -t=0 -m=/home/model.pb --pb=/home/model.pbtxt -v=mcc24.mp4
To run on GPU with neural network
/home/opencv/build/bin/example_cpp_macbeth_chart_detection -t=0 -m=/home/model.pb --pb=/home/model.pbtxt -v=mcc24.mp4 --use_gpu
To run on GPU with neural network and detect the best 5 charts (Detections can be less than 5 but not more than 5)
/home/opencv/build/bin/example_cpp_macbeth_chart_detection -t=0 -m=/home/model.pb --pb=/home/model.pbtxt -v=mcc24.mp4 --use_gpu --nc=5
1#include <opencv2/core.hpp>
2#include <opencv2/highgui.hpp>
4#ifdef HAVE_OPENCV_DNN
5#include <opencv2/dnn.hpp>
6#include "../dnn/common.hpp"
7#endif
8#include <iostream>
9
10using namespace std;
11using namespace cv;
12#ifdef HAVE_OPENCV_DNN
13using namespace cv::dnn;
14#endif
15using namespace mcc;
16
17const string about =
18 "This sample demonstrates mcc checker detection with DNN based model and thresholding (default) techniques.\n\n"
19 "To run default:\n"
20 "\t ./example_cpp_macbeth_chart_detection --input=path/to/your/input/image/or/video (don't give --input flag if want to use device camera)\n"
21#ifdef HAVE_OPENCV_DNN
22 "With DNN model:\n"
23 "\t ./example_cpp_macbeth_chart_detection mcc --input=path/to/your/input/image/or/video\n\n"
24 "Model path can also be specified using --model argument. And config path can be specified using --config. Download it using python download_models.py mcc from dnn samples directory\n\n"
25#else
26 "Note: DNN-based detection is not available in this build.\n\n"
27#endif
28 ;
29
30const string param_keys =
31 "{ help h | | Print help message. }"
32#ifdef HAVE_OPENCV_DNN
33 "{ @alias | | An alias name of model to extract preprocessing parameters from models.yml file. }"
34 "{ zoo | ../dnn/models.yml | An optional path to file with preprocessing parameters }"
35#endif
36 "{ input i | | Path to input image or video file. Skip this argument to capture frames from a camera.}"
37 "{ type | 0 | chartType: 0-Standard, 1-DigitalSG, 2-Vinyl, default:0 }"
38 "{ num_charts | 1 | Maximum number of charts in the image }"
39#ifdef HAVE_OPENCV_DNN
40 "{ model | | Path to the model file for using dnn model. }";
41#else
42 ;
43#endif
44
45#ifdef HAVE_OPENCV_DNN
46const string backend_keys = format(
47 "{ backend | default | Choose one of computation backends: "
48 "default: automatically (by default), "
49 "openvino: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
50 "opencv: OpenCV implementation, "
51 "vkcom: VKCOM, "
52 "cuda: CUDA, "
53 "webnn: WebNN }");
54
55const string target_keys = format(
56 "{ target | cpu | Choose one of target computation devices: "
57 "cpu: CPU target (by default), "
58 "opencl: OpenCL, "
59 "opencl_fp16: OpenCL fp16 (half-float precision), "
60 "vpu: VPU, "
61 "vulkan: Vulkan, "
62 "cuda: CUDA, "
63 "cuda_fp16: CUDA fp16 (half-float preprocess) }");
64#endif
65
66// Initialize keys before use
67string keys = param_keys;
68static void initKeys() {
69#ifdef HAVE_OPENCV_DNN
70 keys += backend_keys + target_keys;
71#endif
72}
73
74static bool processFrame(const Mat& frame, Ptr<CCheckerDetector> detector, Mat& src, Mat& tgt, int nc){
75 Mat imageCopy = frame.clone();
76 if (!detector->process(frame, nc))
77 {
78 return false;
79 }
80 vector<Ptr<CChecker>> checkers = detector->getListColorChecker();
81 detector->draw(checkers, frame);
82 src = checkers[0]->getChartsRGB(false);
83 tgt = detector->getRefColors();
84
85 imshow("Image result", frame);
86 imshow("Original", imageCopy);
87
88 return true;
89}
90
91int main(int argc, char *argv[])
92{
93 initKeys();
94 CommandLineParser parser(argc, argv, keys);
95 parser.about(about);
96
97 if (parser.has("help"))
98 {
99 cout << about << endl;
100 parser.printMessage();
101 return -1;
102 }
103
104#ifdef HAVE_OPENCV_DNN
105 string modelName = parser.get<String>("@alias");
106 string zooFile = parser.get<String>("zoo");
107 const char* path = getenv("OPENCV_SAMPLES_DATA_PATH");
108 if ((path != NULL) || parser.has("@alias") || (parser.get<String>("model") != "")) {
109 zooFile = findFile(zooFile);
110 }
111 else{
112 cout<<"[WARN] set the environment variables or pass the arguments --model, --config and models.yml file using --zoo for using dnn based detector. Continuing with default detector.\n\n";
113 }
114
115 keys += genPreprocArguments(modelName, zooFile);
116 parser = CommandLineParser(argc, argv, keys);
117#endif
118
119 int t = parser.get<int>("type");
120
121 CV_Assert(0 <= t && t <= 2);
122 ColorChart chartType = ColorChart(t);
123
124#ifdef HAVE_OPENCV_DNN
125 const string sha1 = parser.get<String>("sha1");
126 const string model_path = findModel(parser.get<string>("model"), sha1);
127 const string config_sha1 = parser.get<String>("config_sha1");
128 const string pbtxt_path = findModel(parser.get<string>("config"), config_sha1);
129 const string backend = parser.get<String>("backend");
130 const string target = parser.get<String>("target");
131#endif
132
133 int nc = parser.get<int>("num_charts");
134
135 Ptr<CCheckerDetector> detector;
136#ifdef HAVE_OPENCV_DNN
137 if (model_path != "" && pbtxt_path != ""){
138 EngineType engine = ENGINE_AUTO;
139 if (backend != "default" || target != "cpu"){
140 engine = ENGINE_CLASSIC;
141 }
142 Net net = readNetFromTensorflow(model_path, pbtxt_path, engine);
143 net.setPreferableBackend(getBackendID(backend));
144 net.setPreferableTarget(getTargetID(target));
145
146 detector = CCheckerDetector::create(net);
147 cout<<"Detecting checkers using neural network."<<endl;
148 }
149 else{
150 detector = CCheckerDetector::create();
151 }
152#else
153 detector = CCheckerDetector::create();
154#endif
155 detector->setColorChartType(chartType);
156
157 bool isVideo = true;
158 Mat image;
159 VideoCapture cap;
160
161 if (parser.has("input")){
162 const string inputFile = parser.get<String>("input");
163 image = imread(findFile(inputFile));
164 if (!image.empty())
165 {
166 isVideo = false;
167 }
168 else
169 {
170 // Not an image, so try opening it as a video.
171 cap.open(findFile(inputFile));
172 if (!cap.isOpened())
173 {
174 cout << "[ERROR] Could not open file as an image or video: " << inputFile << endl;
175 return -1;
176 }
177 }
178 }
179 else
180 cap.open(0);
181
182 Mat src, tgt;
183 bool found = false;
184 if (isVideo){
185 cout<<"To print the actual colors and reference colors for current frame press SPACEBAR. To resume press SPACEBAR again"<<endl;
186
187 while (cap.grab())
188 {
189 Mat frame;
190 cap.retrieve(frame);
191
192 found = processFrame(frame, detector, src, tgt, nc);
193
194 int key = waitKey(10);
195 if (key == ' '){
196 if(found){
197 cout<<"Reference colors: "<<tgt<<endl<<"--------------------"<<endl;
198 cout<<"Actual colors: "<<src<<endl<<endl;
199 cout<<"Press spacebar to resume."<<endl;
200
201 waitKey(0);
202 cout << "Resumed! Processing continues..." << endl;
203 }
204 else{
205 cout<<"No color chart detected!!"<<endl;
206 }
207 }
208 else if (key == 27) exit(0);
209 }
210 if(found){
211 cout<<"Reference colors: "<<tgt<<endl<<"--------------------"<<endl;
212 cout<<"Actual colors: "<<src<<endl<<endl;
213 }
214 }
215 else{
216 found = processFrame(image, detector, src, tgt, nc);
217 if(found){
218 cout<<"Reference colors: "<<tgt<<endl<<"--------------------"<<endl;
219 cout<<"Actual colors: "<<src<<endl<<endl;
220 waitKey(0);
221 }
222 else{
223 cout<<"No chart detected!!"<<endl;
224 }
225 }
226 return 0;
227}
Designed for command line parsing.
Definition utility.hpp:915
Comma-separated Matrix Initializer.
Definition mat.hpp:964
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:790
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 isOpened() const
Returns true if video capturing has been initialized already.
virtual bool grab()
Grabs the next frame from video file or capturing device.
This class allows to create and manipulate comprehensive artificial neural networks.
Definition dnn.hpp:558
void setPreferableBackend(int backendId)
Ask network to use specific computation backend where it supported.
void setPreferableTarget(int targetId)
Ask network to make computations on specific target device.
std::string String
Definition cvstd.hpp:151
std::shared_ptr< _Tp > Ptr
Definition cvstd_wrapper.hpp:23
cv::String findFile(const cv::String &relative_path, bool required=true, bool silentMode=false)
Try to find requested data file.
#define CV_Assert(expr)
Checks a condition at runtime and throws exception if it fails.
Definition exception.hpp:198
Net readNetFromTensorflow(CV_WRAP_FILE_PATH const String &model, CV_WRAP_FILE_PATH const String &config=String(), int engine=ENGINE_AUTO, const std::vector< String > &extraOutputs=std::vector< String >())
Reads a network model stored in TensorFlow framework's format.
EngineType
Definition dnn.hpp:1085
@ ENGINE_CLASSIC
Force use the old dnn engine similar to 4.x branch.
Definition dnn.hpp:1086
@ ENGINE_AUTO
Try to use the new engine and then fall back to the classic version.
Definition dnn.hpp:1088
cv::gapi::GBackend backend()
Get a reference to CPU (OpenCV) backend.
int waitKey(int delay=0)
Waits for a pressed key.
Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
Loads an image from a file.
ColorChart
enum to hold the type of the checker
Definition mcc_checker_detector.hpp:53
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3
Definition all_layers.hpp:47
Definition core.hpp:107
STL namespace.

解説

  1. ヘッダと名前空間を設定する

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

    必要であれば、上記のコードのように名前空間を設定できる。

  2. 検出器オブジェクトを作成する
    Ptr<CCheckerDetector> detector = CCheckerDetector::create();
  3. または、ニューラルネットワークを用いて検出器オブジェクトを作成する

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

    これは単にオブジェクトを生成するだけである。

  4. 検出器を実行する

    detector->process(image, chartType);

    検出器が少なくとも1つのチャートを検出できた場合はtrueを返し、そうでなければfalseを返す。上記のコードでは、チャートが検出されなかった場合に失敗メッセージを表示している。検出に成功した場合は、カラーチャートのリストが検出器自身の内部に格納される。次のステップでその抽出方法を説明する。デフォルトでは最大1つのチャートを検出するが、第3引数のnc(チャートの最大数)を調整することで、より多くのチャートを検出できる。

  5. ColorCheckerの一覧を取得する

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

    検出されたすべてのcolorcheckerが、これで 'checkers' ベクトルに格納される。

  6. カラーチェッカーを画像上に描き戻す
    detector->draw(checkers, image);