연결된 카메라 확인
#pragma once
#include <opencv2/opencv.hpp>
static void on_mouse(int, int, int, int, void*);
static void on_level_changed(int, void*);
void show_camera() {
cv::VideoCapture cap(0);
if (cap.isOpened()) {
std::cout << "Connected" << std::endl;
}
else {
std::cout << "Error Occured" << std::endl;
return;
}
std::cout << "Frame width " << cvRound(cap.get(cv::CAP_PROP_FRAME_WIDTH)) << std::endl;
std::cout << "Frame Height " << cvRound(cap.get(cv::CAP_PROP_FRAME_HEIGHT)) << std::endl;
cv::Mat frame;
cv::Mat inversed_frame;
cv::namedWindow("FRAME", cv::WINDOW_NORMAL);
cv::namedWindow("INVERSE", cv::WINDOW_NORMAL);
while (true) {
cap >> frame;
if (frame.empty()) break;
inversed_frame = ~frame;
imshow("FRAME", frame);
imshow("INVERSE", inversed_frame);
if(cv::waitKey(10) == 27) break;
}
cv::destroyAllWindows();
}
연결된 카메라 영상연결
void show_movie() {
cv::VideoCapture cap("stopwatch.avi");
if (cap.isOpened())
{
std::cout << "video is connected" << std::endl;
}
else {
std::cout << "There is no Video" << std::endl;
return;
}
std::cout << cvRound(cap.get(cv::CAP_PROP_FRAME_WIDTH)) << std::endl;
std::cout << cvRound(cap.get(cv::CAP_PROP_FRAME_HEIGHT)) << std::endl;
double fps = cap.get(cv::CAP_PROP_FPS);
std::cout << "FPS : " << fps << std::endl;
int delay = cvRound(1'000 / fps);
cv::namedWindow("STOPWATCH", cv::WINDOW_NORMAL);
cv::Mat frame;
cv::namedWindow("INVERSE", cv::WINDOW_NORMAL);
while (true) {
cap >> frame;
if (frame.empty()) break;
cv::imshow("STOPWATCH", frame);
cv::imshow("INVERSED", ~frame);
cv::waitKey(delay);
}
cv::destroyAllWindows();
}
연결된 카메라를 통한 녹화 진행
void show_video_record() {
cv::VideoCapture cap(0);
if (cap.isOpened())
{
std::cout << "Camera is Connected" << std::endl;
}
else {
std::cout << "Camera is Unconnected" << std::endl;
return;
}
double fps = (cap.get(cv::CAP_PROP_FPS));
int delay = cvRound(1000 / fps);
int fourcc = cv::VideoWriter::fourcc('X', '2', '6', '4');
cv::Mat frame;
cv::Mat inversed;
cv::VideoWriter output("recording.mp4", fourcc, 30,
cv::Size(cap.get(cv::CAP_PROP_FRAME_WIDTH),cap.get(cv::CAP_PROP_FRAME_HEIGHT)));
if (output.isOpened()) {
std::cout << "Recording is ready" << std::endl;
}
else {
std::cout << "Recording is not ready" << std::endl;
return;
}
cv::namedWindow("RECORDING");
while (true) {
cap >> frame;
inversed = ~frame;
if (frame.empty()) break;
output << inversed;
cv::imshow("RECORDING", frame);
if (cv::waitKey(30) == 27) break;
}
cv::destroyAllWindows();
}
선 그리기
void show_draw_lines() {
cv::Mat canvas(800, 800, CV_8UC3, cv::Scalar(255,255,255));
cv::line(canvas, cv::Point(50, 50), cv::Point(200, 50), cv::Scalar(0, 0, 255), 10);
cv::line(canvas, cv::Point(50, 50), cv::Point(200, 100), cv::Scalar(255, 0, 255), 1);
cv::arrowedLine(canvas, cv::Point(50, 200), cv::Point(150, 200), cv::Scalar(0, 255, 0), 2);
cv::drawMarker(canvas, cv::Point(30,250),cv::Scalar(0,0,255),cv::MARKER_CROSS);
cv::namedWindow("CANVAS", cv::WINDOW_NORMAL);
cv::imshow("CANVAS", canvas);
cv::waitKey();
cv::destroyWindow("CANVAS");
}
도형 그리기
void show_draw_polygons(){
cv::Mat canvas = cv::Mat(500,500,CV_8UC3,cv::Scalar(255,255,255));
cv::rectangle(canvas, cv::Rect(50, 50, 150, 50),cv::Scalar(0,0,255),3);
cv::rectangle(canvas, cv::Rect(50, 150, 100, 50),cv::Scalar(0,0,255), -1);
cv::circle(canvas, cv::Point(300, 120), 60, cv::Scalar(255, 255, 0), -1, cv::LINE_AA);
cv::ellipse(canvas,cv::Point(120,300),cv::Size(60,30),20,0,270,cv::Scalar(0,255,0),-1,cv::LINE_AA);
std::vector<cv::Point>points;
points.push_back(cv::Point(250, 250));
points.push_back(cv::Point(300, 250));
points.push_back(cv::Point(300, 300));
points.push_back(cv::Point(350, 300));
points.push_back(cv::Point(350, 350));
points.push_back(cv::Point(250, 350));
cv::polylines(canvas, points, true, cv::Scalar(255, 0, 255), 5, -1);
cv::namedWindow("CANVAS", cv::WINDOW_NORMAL);
cv::imshow("CANVAS", canvas);
cv::waitKey();
cv::destroyAllWindows();
}
텍스트 삽입
void show_draw_text(){
cv::Mat canvas = cv::imread("lenna.bmp");
cv::putText(canvas, "LENNA",cv::Point(250,450),cv::FONT_HERSHEY_TRIPLEX | \
cv::FONT_ITALIC,2,cv::Scalar(255,0,0),5,-1);
cv::namedWindow("LENNA", cv::WINDOW_NORMAL);
cv::imshow("LENNA", canvas);
cv::waitKey();
cv::destroyAllWindows;
}
키보드 입력에 대한 이벤트 (종료)
void keyboard_event(int key) {
if (key == 27) {
std::cout << "ESC 키 눌림. 프로그램 종료." << std::endl;
}
}
마우스에 입력에 대한 이벤트
static cv::Mat img;
static cv::Point pt_old;
void mouse_event(int event, int x, int y, int flags, void* userdata) {
if (event == cv::EVENT_LBUTTONDOWN) {
pt_old = cv::Point(x, y);
}
else if (event == cv::EVENT_LBUTTONUP) {
cv::Point pt_new(x, y);
cv::line(img, pt_old, pt_new, cv::Scalar(0, 0, 255), 2);
cv::imshow("Image", img);
}
}
마우스를 따라 이벤트
void on_mouse(int mouse_event, int mouse_x, int mouse_y, int flags, void* param) {
if (mouse_event == cv::EVENT_LBUTTONDOWN) {
pt_old = cv::Point(mouse_x, mouse_y);
}
else if (mouse_event == cv::EVENT_LBUTTONUP) {
cv::Point pt_new(mouse_x, mouse_y);
cv::line(img, pt_old, pt_new, cv::Scalar(0, 0, 255), 2);
cv::imshow("Image", img);
}
}
출력 이미지 상단에 Trackbar 생성
void trackbar_event() {
cv::Mat canvas(800, 800, CV_8UC1);
cv::namedWindow("CANVAS");
cv::createTrackbar("Level", "CANVAS", nullptr, 16, on_level_changed, (void*)&canvas);
cv::imshow("CANVAS", canvas);
cv::waitKey();
cv::destroyAllWindows();
}
Trackbar 와 연동해서 레벨에 따라 바뀌도록 함
void on_level_changed(int positition, void* userdata) {
cv::Mat img = *(static_cast<cv::Mat*>(userdata));
img.setTo(positition * 16);
cv::imshow("CANVAS", img);
}
특정 영역의 색을 바꿈
void mask_setTo() {
cv::Mat src = cv::imread("lenna.bmp");
cv::Mat mask = cv::imread("mask_smile.bmp",cv::IMREAD_GRAYSCALE);
if (src.empty() or mask.empty()) return;
src.setTo(cv::Scalar(0, 255, 0), mask);
cv::imshow("SRC", src);
cv::imshow("MASK", mask);
cv::waitKey();
cv::destroyAllWindows();
}
OpenCV를 통한 이미지 합성
void mask_copyTo() {
cv::Mat src = cv::imread("airplane.bmp");
cv::Mat mask = cv::imread("mask_plane.bmp", cv::IMREAD_GRAYSCALE);
cv::Mat dst = cv::imread("field.bmp");
if (src.empty() or mask.empty() or dst.empty()) return;
cv::imshow("ORIGINAL", dst);
cv::imshow("SRC", src);
cv::imshow("MASK", mask);
src.copyTo(dst, mask);
cv::imshow("CHANGED", dst);
cv::waitKey();
cv::destroyAllWindows();
}
실행 소요 시간 측정
void time_inverse(){
cv::Mat img = cv::imread("lenna.bmp", cv::IMREAD_GRAYSCALE);
if (img.empty()) return;
cv::Mat dst(img.rows, img.cols, img.type());
cv::TickMeter tick;
tick.start();
for (int i = 0; i < img.rows; ++i) {
for (int j = 0; j < img.cols; ++j) {
dst.at<uchar>(i, j) = 255 - img.at<uchar>(i, j);
}
}
tick.stop();
std::cout << "걸린 시간 : " << tick.getTimeSec() << "초" << std::endl;
cv::imshow("IMG", img);
cv::imshow("DST", dst);
cv::waitKey();
cv::destroyAllWindows();
}
min & max 함수
void useful_funtions() {
cv::Mat src = cv::imread("lenna.bmp", cv::IMREAD_GRAYSCALE);
std::cout << static_cast<int>(cv::sum(src)[0]) << std::endl;
std::cout << static_cast<int>(cv::mean(src)[0]) << std::endl;
double min_value = 0.0;
double max_value = 0.0;
cv::Point min_point;
cv::Point max_point;
std::cout << "Min : " << min_value << " , " << "Max : " << max_value << std::endl;
cv::minMaxLoc(src, &min_value, &max_value, &min_point, &max_point);
std::cout << "Min : " << min_value << " , " << "Max : " << max_value << std::endl;
std::cout << "Min Poisition X: " << min_point.x << " , " << "Min Position: " << min_point.y << std::endl;
std::cout << "Max Poisition X: " << max_point.x << " , " << "Max Position: " << max_point.y << std::endl;
}