[OpenCV]OpenCVペイント、イベント処理、ROI&マスク計算
描画
💜 直線()ちょくせん()ちょくせん()
💜 長方形()ちょうほうけい()ちょうほうけい:長方形を描画ちょうほうけいをえがく
💜 circle()circle()circle()circle()circle()circle()circle()circle()circle()circle()circle()circle()circle()circle()circle
💜 ポリライン()ポリライン():ポリゴンを描画ぽりごんをぺいん
💜 putText():文字列を挿入VideoCapture cap("test_video.mp4");
if (!cap.isOpened()) {
cerr << "Video open failed!" << endl;
return -1;
}
Mat frame;
while (true) {
cap >> frame;
if (frame.empty()) {
cerr << "Empty frame!" << endl;
break;
}
line(frame, Point(570, 280), Point(0, 560), Scalar(255, 0, 0), 2);
line(frame, Point(570, 280), Point(1024, 720), Scalar(255, 0, 0), 2);
int pos = cvRound(cap.get(CAP_PROP_POS_FRAMES)); // 현재 프레임 번호
String text = format("frame number: %d", pos);
putText(frame, text, Point(20, 50), FONT_HERSHEY_SIMPLEX, 0.7, Scalar(0, 0, 255), 1, LINE_AA);
imshow("frame", frame);
if (waitKey(10) == 27)
break;
}
cap.release();
destroyAllWindows();
イベントの処理
キーボードイベント
💜 waitKey():キーボード入力待ち
パラメータdelay
はミリ秒単位のヒステリシス時間であり、default値は0に設定される.0以下は無限待ちです.キーボード入力を受信すると、押したキー値はint型に戻り、そうでない場合は-1に戻ります.
正常に動作するにはOpenCVウィンドウが必要です.imshow()
関数が呼び出された後にのみ、画面にビデオが表示されます.
特殊キー(矢印、Fnキーなど)は、waitKeyEx()
関数を使用します.
マウスイベント
💜 setMouseCallback():マウスイベントを処理するコールバック関数を登録
コールバック関数はtypedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata)
形式で定義する必要があります.Mat src;
// main과 callback 함수 모두에서 쓰기 위해 전역변수 선언
Point ptOld;
void on_mouse(int event, int x, int y, int flags, void*);
int main(void)
{
src = imread("lenna.bmp");
namedWindow("src");
setMouseCallback("src", on_mouse); // 창 이름이 먼저 지정되어 있어야 namedWindow를 위에 먼저 선언해줌
imshow("src", src);
waitKey();
}
void on_mouse(int event, int x, int y, int flags, void*) //사용자 지정 데이터인 userdata를 쓰지 않을 예정이라 void* 뒤 이름 선언 안함
{
switch (event) {
case EVENT_LBUTTONDOWN: // 왼 버튼이 눌리면
ptOld = Point(x, y);
cout << "EVENT_LBUTTONDOWN: " << x << ", " << y << endl;
break;
case EVENT_LBUTTONUP: // 왼 버튼이 눌렸다 떼어지면
cout << "EVENT_LBUTTONUP: " << x << ", " << y << endl;
break;
case EVENT_MOUSEMOVE: // 마우스가 움직이면
if (flags & EVENT_FLAG_LBUTTON) {
cout << "EVENT_MOUSEMOVE: " << x << ", " << y << endl;
line(src, ptOld, Point(x, y), Scalar(0, 255, 255), 3, LINE_AA);
ptOld = Point(x, y);
imshow("src", src);
}
break;
default:
break;
}
}
グローバル変数src
として宣言したが、コールバック関数にuserdata
因子を加えるように設定した場合、main()
で宣言して領域変数として使用することができる.if (flags & EVENT_FLAG_LBUTTON)
から==
までの演算子をflags == EVENT_FLAG_LBUTTON
と書くこともできますが、EVENT_FLAG_LBUTTON
は1として定義されているので、flag
と&
(and)演算でTrueを返すかどうかを確認することが望ましいです.==
と書けば、ctrl
キーのようにマウスを押すと動かなくなります.ctrl
の身長は8なのでtrueではありません.
マウスイベントの速度が遅いため、マウスの前の位置を記録し、前の点から現在の点まで直線を描画する必要があります.これがptOld
変数と書かれている理由です.この処理がなければ,線は断続的に出てくる.
トラックバー(スライダコントロール)トラックバースライダコントロール
💜 createTrackbar():trackbar作成関数trackbarさくせいかんすう
trackbarの位置が変化するたびに、呼び出されるコールバック関数はtypedef void (*TrackbarCallback)(int pos, void* userdata)
フォーマットであるべきである.void on_level_change(int pos, void* userdata);
int main(void)
{
Mat img = Mat::zeros(400, 400, CV_8UC1);
namedWindow("image");
createTrackbar("level", "image", 0, 16, on_level_change, (void*)&img);
// 세 번째 인자인 value(값을 받아올 곳)을 0(Null)로 하면 반드시 callback 함수를 지정해야 함
imshow("image", img);
waitKey();
}
void on_level_change(int pos, void* userdata)
{
Mat img = *(Mat*)userdata; // 원본과 동일한 영상 데이터를 가리킴
img.setTo(pos * 16); //256이 255보다 크기 때문에 255(white)로 출력이 됨
imshow("image", img);
}
関心領域とマスク演算
対象領域(ROI)は、任意の演算を行う任意の領域です.ROI機能をサポートするOpenCV関数を記述するために、マスクビデオをパラメータとして渡す必要がある場合があります.マスク画像は、階調CV 8 UC 1タイプであり、通常、0または255(黒または白)の画素値を持つバイナリ画像(バイナリ画像)が用いられる.
例えば、copyTo()
関数は、2番目のパラメータmask
に1つのマスク画像を与えることができ、マスク画像のゼロ以外の部分でのみcopyが発生する.Mat src = imread("airplane.bmp", IMREAD_COLOR);
Mat mask = imread("mask_plane.bmp", IMREAD_GRAYSCALE);
Mat dst = imread("field.bmp", IMREAD_COLOR);
src.copyTo(dst, mask); //또는 copyTo(src, dst, mask);
上図左からsrc
、mask
、dst
の映像です.飛行機部分のみをマスク演算し、dst
に貼り付け、以下に示す.
Alphaチャネルを持つpngファイルを使用してマスク演算を練習します.pngファイルは、B、G、R、Aの4チャネル画像であり、alphaチャネルは0であり、RGB値のない透明な空間が埋め込まれ、色があれば255である.したがって、alphaチャネルをマスクとして使用することができる.Mat src = imread("cat.bmp", IMREAD_COLOR);
Mat logo = imread("opencv-logo-white.png", IMREAD_UNCHANGED);
vector<Mat> planes;
split(logo, planes); // 채널 분할
Mat mask = planes[3]; //알파 채널이 4번째
merge(vector<Mat>(planes.begin(), planes.begin() + 3), logo);
// 앞에서 3개만 따다가 새로운 vec<Mat> 객체를 만듦. BGR 만 있을 것. 그것을 logo라는 Mat 객체로 만듦
Mat crop = src(Rect(10, 10, logo.cols, logo.rows));
// cat 영상이 더 크니까 로고 들어갈 부분만 잘라서 저장해둠. 참조이므로 이것을 변경하면 원본도 변경됨
logo.copyTo(crop, mask); // 둘이 크기와 타입이 같으므로 새로 만들어지는 것이 아니라 crop에 직접 픽셀 들어감
Reference
この問題について([OpenCV]OpenCVペイント、イベント処理、ROI&マスク計算), 我々は、より多くの情報をここで見つけました
https://velog.io/@717lumos/OpenCV-OpenCV-그리기-이벤트-처리-ROI-마스크-연산
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
VideoCapture cap("test_video.mp4");
if (!cap.isOpened()) {
cerr << "Video open failed!" << endl;
return -1;
}
Mat frame;
while (true) {
cap >> frame;
if (frame.empty()) {
cerr << "Empty frame!" << endl;
break;
}
line(frame, Point(570, 280), Point(0, 560), Scalar(255, 0, 0), 2);
line(frame, Point(570, 280), Point(1024, 720), Scalar(255, 0, 0), 2);
int pos = cvRound(cap.get(CAP_PROP_POS_FRAMES)); // 현재 프레임 번호
String text = format("frame number: %d", pos);
putText(frame, text, Point(20, 50), FONT_HERSHEY_SIMPLEX, 0.7, Scalar(0, 0, 255), 1, LINE_AA);
imshow("frame", frame);
if (waitKey(10) == 27)
break;
}
cap.release();
destroyAllWindows();
キーボードイベント
💜 waitKey():キーボード入力待ち
パラメータ
delay
はミリ秒単位のヒステリシス時間であり、default値は0に設定される.0以下は無限待ちです.キーボード入力を受信すると、押したキー値はint型に戻り、そうでない場合は-1に戻ります.正常に動作するにはOpenCVウィンドウが必要です.
imshow()
関数が呼び出された後にのみ、画面にビデオが表示されます.特殊キー(矢印、Fnキーなど)は、
waitKeyEx()
関数を使用します.マウスイベント
💜 setMouseCallback():マウスイベントを処理するコールバック関数を登録
コールバック関数は
typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata)
形式で定義する必要があります.Mat src;
// main과 callback 함수 모두에서 쓰기 위해 전역변수 선언
Point ptOld;
void on_mouse(int event, int x, int y, int flags, void*);
int main(void)
{
src = imread("lenna.bmp");
namedWindow("src");
setMouseCallback("src", on_mouse); // 창 이름이 먼저 지정되어 있어야 namedWindow를 위에 먼저 선언해줌
imshow("src", src);
waitKey();
}
void on_mouse(int event, int x, int y, int flags, void*) //사용자 지정 데이터인 userdata를 쓰지 않을 예정이라 void* 뒤 이름 선언 안함
{
switch (event) {
case EVENT_LBUTTONDOWN: // 왼 버튼이 눌리면
ptOld = Point(x, y);
cout << "EVENT_LBUTTONDOWN: " << x << ", " << y << endl;
break;
case EVENT_LBUTTONUP: // 왼 버튼이 눌렸다 떼어지면
cout << "EVENT_LBUTTONUP: " << x << ", " << y << endl;
break;
case EVENT_MOUSEMOVE: // 마우스가 움직이면
if (flags & EVENT_FLAG_LBUTTON) {
cout << "EVENT_MOUSEMOVE: " << x << ", " << y << endl;
line(src, ptOld, Point(x, y), Scalar(0, 255, 255), 3, LINE_AA);
ptOld = Point(x, y);
imshow("src", src);
}
break;
default:
break;
}
}
グローバル変数src
として宣言したが、コールバック関数にuserdata
因子を加えるように設定した場合、main()
で宣言して領域変数として使用することができる.if (flags & EVENT_FLAG_LBUTTON)
から==
までの演算子をflags == EVENT_FLAG_LBUTTON
と書くこともできますが、EVENT_FLAG_LBUTTON
は1として定義されているので、flag
と&
(and)演算でTrueを返すかどうかを確認することが望ましいです.==
と書けば、ctrl
キーのようにマウスを押すと動かなくなります.ctrl
の身長は8なのでtrueではありません.マウスイベントの速度が遅いため、マウスの前の位置を記録し、前の点から現在の点まで直線を描画する必要があります.これが
ptOld
変数と書かれている理由です.この処理がなければ,線は断続的に出てくる.トラックバー(スライダコントロール)トラックバースライダコントロール
💜 createTrackbar():trackbar作成関数trackbarさくせいかんすう
trackbarの位置が変化するたびに、呼び出されるコールバック関数は
typedef void (*TrackbarCallback)(int pos, void* userdata)
フォーマットであるべきである.void on_level_change(int pos, void* userdata);
int main(void)
{
Mat img = Mat::zeros(400, 400, CV_8UC1);
namedWindow("image");
createTrackbar("level", "image", 0, 16, on_level_change, (void*)&img);
// 세 번째 인자인 value(값을 받아올 곳)을 0(Null)로 하면 반드시 callback 함수를 지정해야 함
imshow("image", img);
waitKey();
}
void on_level_change(int pos, void* userdata)
{
Mat img = *(Mat*)userdata; // 원본과 동일한 영상 데이터를 가리킴
img.setTo(pos * 16); //256이 255보다 크기 때문에 255(white)로 출력이 됨
imshow("image", img);
}
関心領域とマスク演算
対象領域(ROI)は、任意の演算を行う任意の領域です.ROI機能をサポートするOpenCV関数を記述するために、マスクビデオをパラメータとして渡す必要がある場合があります.マスク画像は、階調CV 8 UC 1タイプであり、通常、0または255(黒または白)の画素値を持つバイナリ画像(バイナリ画像)が用いられる.
例えば、copyTo()
関数は、2番目のパラメータmask
に1つのマスク画像を与えることができ、マスク画像のゼロ以外の部分でのみcopyが発生する.Mat src = imread("airplane.bmp", IMREAD_COLOR);
Mat mask = imread("mask_plane.bmp", IMREAD_GRAYSCALE);
Mat dst = imread("field.bmp", IMREAD_COLOR);
src.copyTo(dst, mask); //또는 copyTo(src, dst, mask);
上図左からsrc
、mask
、dst
の映像です.飛行機部分のみをマスク演算し、dst
に貼り付け、以下に示す.
Alphaチャネルを持つpngファイルを使用してマスク演算を練習します.pngファイルは、B、G、R、Aの4チャネル画像であり、alphaチャネルは0であり、RGB値のない透明な空間が埋め込まれ、色があれば255である.したがって、alphaチャネルをマスクとして使用することができる.Mat src = imread("cat.bmp", IMREAD_COLOR);
Mat logo = imread("opencv-logo-white.png", IMREAD_UNCHANGED);
vector<Mat> planes;
split(logo, planes); // 채널 분할
Mat mask = planes[3]; //알파 채널이 4번째
merge(vector<Mat>(planes.begin(), planes.begin() + 3), logo);
// 앞에서 3개만 따다가 새로운 vec<Mat> 객체를 만듦. BGR 만 있을 것. 그것을 logo라는 Mat 객체로 만듦
Mat crop = src(Rect(10, 10, logo.cols, logo.rows));
// cat 영상이 더 크니까 로고 들어갈 부분만 잘라서 저장해둠. 참조이므로 이것을 변경하면 원본도 변경됨
logo.copyTo(crop, mask); // 둘이 크기와 타입이 같으므로 새로 만들어지는 것이 아니라 crop에 직접 픽셀 들어감
Reference
この問題について([OpenCV]OpenCVペイント、イベント処理、ROI&マスク計算), 我々は、より多くの情報をここで見つけました
https://velog.io/@717lumos/OpenCV-OpenCV-그리기-이벤트-처리-ROI-마스크-연산
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Mat src = imread("airplane.bmp", IMREAD_COLOR);
Mat mask = imread("mask_plane.bmp", IMREAD_GRAYSCALE);
Mat dst = imread("field.bmp", IMREAD_COLOR);
src.copyTo(dst, mask); //또는 copyTo(src, dst, mask);
Mat src = imread("cat.bmp", IMREAD_COLOR);
Mat logo = imread("opencv-logo-white.png", IMREAD_UNCHANGED);
vector<Mat> planes;
split(logo, planes); // 채널 분할
Mat mask = planes[3]; //알파 채널이 4번째
merge(vector<Mat>(planes.begin(), planes.begin() + 3), logo);
// 앞에서 3개만 따다가 새로운 vec<Mat> 객체를 만듦. BGR 만 있을 것. 그것을 logo라는 Mat 객체로 만듦
Mat crop = src(Rect(10, 10, logo.cols, logo.rows));
// cat 영상이 더 크니까 로고 들어갈 부분만 잘라서 저장해둠. 참조이므로 이것을 변경하면 원본도 변경됨
logo.copyTo(crop, mask); // 둘이 크기와 타입이 같으므로 새로 만들어지는 것이 아니라 crop에 직접 픽셀 들어감
Reference
この問題について([OpenCV]OpenCVペイント、イベント処理、ROI&マスク計算), 我々は、より多くの情報をここで見つけました https://velog.io/@717lumos/OpenCV-OpenCV-그리기-이벤트-처리-ROI-마스크-연산テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol