|
|
5장 연습문제
6. 다음 예시 코드는 컴파일 에러가 발생한다. 에러가 발생하는 부분을 수정하고 실행 결과를 적으시오.
(1)
(1) 수정한 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <opencv2/opencv.hpp> #include<iostream> #include<string> using namespace cv; using namespace std; int main(void) { Matx23f m1(1, 2, 3, 1, 2, 3); Matx23f m2(3, 3, 4, 2, 2, 3); Mat m3, m4; add(m1, m2, m3); // 배열 m1,m2 값 더해 m3에 저장 multiply(m1, m2, m4); // 배열 m1, m2 값 곱해 m4에 저장 cout << "[m1] = " << endl << m1 << endl; cout << "[m2] = " << endl << m2 << endl; cout << "[m3] = " << endl << m3 << endl; cout << "[m4] = " << endl << m4 << endl; } | cs |
(2)
(2) 수정된 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <opencv2/opencv.hpp> #include<iostream> #include<string> using namespace cv; using namespace std; int main(void) { int data[] = { 1,2,3,4,5,6,7,8,9,10 }; Mat m1(2, 3, CV_8UC2, data); vector<Mat> sp_mat; split(m1, sp_mat); cout << sp_mat[0] << endl; cout << sp_mat[1]<< endl; } | cs |
(3)
(3) 수정된 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <opencv2/opencv.hpp> #include<iostream> #include<string> using namespace cv; using namespace std; int main(void) { Mat_<uchar> m1(2, 3), m2(2, 3),m3,m4; m1 << 1, 1, 2, 2, 3, 3; m2 << 2, 1, 3, 1, 4, 1; subtract(m1, m2, m3); reduce(m1, m4, 0, REDUCE_MAX); // uchar 이므로 음수를 표현하지 못하기 때문에 // 뺄셈 결과가 음수면 0으로 클리핑 됨 cout << "[m3] = " << endl << m3 << endl; cout << "[m4] = " << endl << m4 << endl; cout << "sum(m1) = " << endl << sum(m1) << endl; cout << "mean(m2) = " << endl << mean(m2) << endl; } | cs |
7. 다음의 컬러 영상 파일(logo.jpg)을 입력 받아서 RGB의 3개 채널을 분리하고, 각 채널을 컬러 영상을 윈도우에 표시해보자. 즉, Red 채널은 빨간색으로, Green 채널은 초록색으로, Blue 채널은 파란색으로 표현되도록 다음의 프로그램을 완성하시오.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <opencv2/opencv.hpp> #include<iostream> #include<string> using namespace cv; using namespace std; int main(void) { Mat image = imread("3.jpg", IMREAD_COLOR); CV_Assert(image.data); Mat bgr[3]; Mat black(image.size(), CV_8UC1, Scalar(0)); split(image, bgr); Mat rcolor[] = { black, black, bgr[2]}; Mat gcolor[] = { black, bgr[1], black}; Mat bcolor[] = { bgr[0], black, black }; merge(rcolor,3,bgr[2]); merge(gcolor, 3, bgr[1]); merge(bcolor, 3, bgr[0]); imshow("image", image); imshow("Red 채널", bgr[2]); imshow("Green 채널", bgr[1]); imshow("Blue 채널", bgr[0]); waitKey(0); return 0; } | cs |
8. 다음 조선 수군의 영상에서 특정 영역의 타원만을 복사하여 새 창에 표시하는 프로그램을 완성하시오.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <opencv2/opencv.hpp> #include<iostream> #include<string> using namespace cv; using namespace std; int main(void) { Mat image = imread("3.jpg", IMREAD_COLOR); CV_Assert(image.data); // 새로운 크기 지정 Size newSize(600,400); // 600x400 // 이미지 크기 조정 Mat newImage; resize(image, newImage, newSize); // resize 함수로 image 사이즈 조절 Mat dst1; Mat mask(newImage.size(), CV_8UC3, Scalar(0,0,0)); Point center(400,150); ellipse(mask, center, Size(150, 200), 0, 0, 360, Scalar(255,255,255), -1); bitwise_and(newImage, mask, dst1); imshow("image", newImage); imshow("dst1", dst1); waitKey(0); return 0; } | cs |
9. 3행, 6열의 행렬을 생성하고, 행렬의 원소를 초기화한 후에 cv::reduce() 함수를 이용해서 가로 방향과 세로 방향으로 감축하여 평균을 구한 결과를 출력하시오.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <opencv2/opencv.hpp> #include<iostream> #include<string> using namespace cv; using namespace std; int main(void) { uchar data[] = { 1,2,3,4,5,6, 7,8,9,10,11,12, 13,14,15,16,17,18,19 }; Mat m_reduce1, m_reduce2; Mat m1(3, 6,CV_8UC1,data); reduce(m1, m_reduce1, 1, REDUCE_AVG); reduce(m1, m_reduce2, 0, REDUCE_AVG); cout << "행렬 가로방향 평균: " <<endl<< m_reduce1 << endl; cout << "행렬 세로방향 평균: " << m_reduce2 << endl; return 0; } | cs |
10. PC 카메라로 영상을 읽어서 특정 부분(관심영역)의 합과 평균을 구하는 프로그램을 작성하시오.
| 1) 관심영역은 200, 100 좌표에서 200x100 크기로 구한다. 2) mean() 함수를 사용하여 평균을 구하시오. 3) mean() 함수를 사용하지 않고 영상 순회 방법으로 평균을 구하시오. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(void) { VideoCapture capture(0); if (!capture.isOpened()) { cout << "카메라가 연결되지 않았습니다." << endl; exit(1); } Rect rec(200, 100, 200, 100); for (;;) { Mat frame; capture.read(frame); Mat result = frame(rec); Scalar mean_value = mean(result); // 픽셀 값을 직접 순회하여 평균 계산 Vec3d sum = { 0, 0, 0 }; // BGR 채널 합 int count = 0; for (int y = 0; y < result.rows; y++) { for (int x = 0; x < result.cols; x++) { Vec3b pixel = result.at<Vec3b>(y, x); // 픽셀 값 (BGR) sum[0] += pixel[0]; // Blue 채널 합산 sum[1] += pixel[1]; // Green 채널 합산 sum[2] += pixel[2]; // Red 채널 합산 count++; } } Vec3d no_mean_value = sum / count; // 평균 계산 imshow("영상보기", frame); cout << "mean 함수 사용하여 구한 평균 값: " << mean_value << endl; cout << "mean 함수 사용하지 않고 구한 평균 값: " << no_mean_value << endl; if (waitKey(30) >= 0) break; } return 0; } | cs |
11. PC 카메라로 영상을 받아들여서 다음과 같이 윈도우의 특정 영역에서 재생하시오.
| 1) 메인 윈도우는 400x300 크기로 한다. 2) 관심영역은 30,30 좌표에서 320x240 크기로 한다. 3) 관심영역에 빨간색 테두리를 두른다. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(void) { VideoCapture capture(0); if (!capture.isOpened()) { cout << "카메라가 연결되지 않았습니다." << endl; return -1; } // 관심 영역 설정 Rect rec(30, 30, 320, 240); for (;;) { Mat frame,resizeFrame, mask, result; capture >> frame; resize(frame, resizeFrame, Size(400, 300)); // 마스크 생성 (ROI 부분만 흰색) mask = Mat::zeros(resizeFrame.size(), CV_8UC3); rectangle(mask, rec, Scalar(255, 255,255), -1); // 관심 영역 흰색 rectangle(resizeFrame, rec, Scalar(0, 0, 255), 3); // 빨간색 테두리 bitwise_and(resizeFrame, mask, result); imshow("메인 윈도우", result); if (waitKey(30) >= 0) break; } return 0; } | cs |
12. 영상 파일을 읽어서 메인 윈도우에 다음과 같이 출력하시오.
| 1) 메인 윈도우의 정 부분 2곳을 관심영역으로 지정한다. 2) 관심영역1는 영상의 밝기를 50만큼 밝게 한다. 3) 관심영역2은 영상의 화소대비를 증가시킨다. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(void) { Mat image = imread("4.jpg", IMREAD_COLOR); CV_Assert(image.data); // 관심 영역 설정 Rect rec1(30, 30, 200, 200); Rect rec2(300, 30, 200, 200); Mat resizeImage; resize(image, resizeImage, Size(600, 400)); rectangle(resizeImage, rec1, Scalar(0, 0, 255), 3); // 빨간색 테두리 rectangle(resizeImage, rec2, Scalar(0, 0, 255), 3); // 빨간색 테두리 resizeImage(rec1) += 50; resizeImage(rec2) *= 1.5; imshow("메인 윈도우", resizeImage); waitKey(); return 0; } | cs |
13. cv::sortIdx() 함수를 활용해서 다음의 조건에 부합하도록 벡터의 원소를 정렬하시오.
| 1) 벡터의 원소는 Rect 객체이다. 2) 벡터의 원소는 임의로 지정한다. 3) 정렬의 기준은 Rect 객체의 크기이다, 4) 오름차순으로 정렬하여 콘솔창에 출력한다. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(void) { vector<Rect>v; Mat_<int>vSort,rectSize; for (int i = 0; i < 4; i++) { v.push_back(Rect(i * 10, i * 10, 100*i, 100*i)); rectSize.push_back(v[i].area()); } sortIdx(rectSize, vSort, SORT_EVERY_COLUMN); for (int i = 0; i < 4; i++) { cout << v[vSort.at<int>(i)] << endl; } return 0; } | cs |
15. 5.6절에서 예제_5.6.2의 삭각형 회전하기 예제를 확장하여 그 사각형의 중심점을 기준으로 45도 회전시키는 프로그램을 완성하시오.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(void) { vector<Point3f>rect_pt1, rect_pt2; rect_pt1.push_back(Point3f(200, 50,1)); rect_pt1.push_back(Point3f(400, 50,1)); rect_pt1.push_back(Point3f(400, 250,1)); rect_pt1.push_back(Point3f(200, 250,1)); float theta = 45 * CV_PI / 180; Matx33f m(cos(theta), -sin(theta),0, sin(theta), cos(theta),0,0,0,1); Mat t1 = Mat::eye(3, 3, CV_32F); Mat t2 = Mat::eye(3, 3, CV_32F); Point3f delta = (rect_pt1[2] - rect_pt1[0]) / 2.0f; Point3f center = rect_pt1[0] + delta; // 원점으로 이동 (사각형의 중심을 원점으로 맞추기) for (int i = 0; i < 4; i++) { rect_pt1[i] = rect_pt1[i] - center; } // 회전 변환 적용 transform(rect_pt1, rect_pt2, m); // 원래 위치로 되돌리기 for (int i = 0; i < 4; i++) { rect_pt2[i] = rect_pt2[i] + center; rect_pt1[i] = rect_pt1[i] + center; } Mat image(400, 500, CV_8UC3, Scalar(255, 255, 255)); for (int i = 0; i < 4; i++) { Point pt1(rect_pt1[i].x, rect_pt1[i].y); Point pt2(rect_pt1[(i + 1) % 4].x, rect_pt1[(i + 1) % 4].y); Point pt3(rect_pt2[i].x, rect_pt2[i].y); Point pt4(rect_pt2[(i + 1) % 4].x, rect_pt2[(i + 1) % 4].y); line(image, pt1, pt2, Scalar(0, 0, 0), 2); line(image, pt3, pt4, Scalar(255, 0, 0), 2); cout << "rect_pt1[" << to_string(i) + "=]" << rect_pt1[i] << "\t"; cout << "rect_pt2[" << to_string(i) + "=]" << rect_pt2[i] << endl; } imshow("image", image); waitKey(); return 0; } | cs |
