OpenCV_2)

한우진·2023년 5월 20일
0

OS support : Window, Linux, MacOS, iOS, Android
Language : C, C++, Java, Python

OpenCV가 동작하기 위해선
소스 형태 File

  • 헤더 소스 File
  • 사전에 학습된 사물인식 설정File

이진형태 file

  • 라이브러리(실행 시)
  • 라이브러리 (컴파일 및 링크시)
  • 동영상 디코더 라이브러리

개발 환경에서 설정해주는 사항(공통)

  • openCV용 include 파일들의 경로 : include/opencv/opencv2/opencv.hpp
  • 소스 파일을 가져와 직접 컴파일, 링크해서 라이브러리를 이진파일로 만들기(Linux에서 적용)

윈도우에서는 Visual Studio와 openCV를 다운받아서 같이 사용해줘야함
그러나 나는 Linux 환경에서 ROS에 작동시킬 거라 visual studio는 받지 않고 진행하겠다


Mat

OpenCV에서 하나의 이미지를 기본으로 표현하는 자료구조
Mat은 header와 채널이 몇개인지 정보가 담겨있음

  • 채널의 순서는 특이하게 RGB순이 아니라 RBG순이다

행렬 원소 자료형

Mat Class는 int, float, double, char, short(unsigned 포함)의 자료형을 지원한다. 이 정보를 Depth라고 일컫으며 다음과 같이 표현할 수 있다

  • CV_8U: 8-bit unsigned integers (0 to 255)
  • CV_8S: 8-bit signed integers (-128 to 127)
  • CV_16U: 16-bit unsigned integers (0 to 65535)
  • CV_16S: 16-bit signed integers (-32768 to 32767)
  • CV_32S: 32-bit signed integers (-2147483648 to 2147483647)
  • CV_32F: 32-bit floating-point numbers
  • CV_64F: 64-bit floating-point numbers

ex1) CV_8UC3 : 3개의 채널을 가지고 8-bit의 픽셀을 각각 가지고 있다
ex2) CV_8UC1 : 싱글 채널을 가지고 8-bit의 픽셀을 가지고 있다

초기화

cv::Mat M;
//빈 행렬 객체 M 생성
cv::Mat M(rows, colums, pixel_type);
//열, 행, 픽셀 타입을 가지는 객체 M 초기화
cv::Mat M(rows, colums, pixel_type, initial_value);
cv::Mat M(Size(width, height), pixel_type, initial_value);

예제

cv::Mat M;
// 빈 행렬 생성
cv::Mat M(3, 3, CV_32F, cv::Scalar(0));
// 3x3 크기의 행렬을 생성, 타입은 32비트 실수형 (0으로 초기화)
float data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// 실수형태의 배열 data
cv::Mat M(3, 3, CV_32F, data);
// M 값 데이터 직접 넣어서 행렬 생성해주기


Mat_<float> mat_(2,3);
mat_ << 1, 2, 3, 4, 5, 6;
Mat mat = mat_;

Mat Size

Mat 객체의 사이즈(bits) = colums rows channels * channel depth

ex) Mat M(10, 15, CV_8UC3)의 크기 = 10 rows 20 cols 3ch/pixel * 8 bits/ch = 4800bits

Mat.elemSize1()

  • 한 픽셀의 채널 당 바이트수
  • 위의 예제에서는 3개의 채널이고 1픽셀이 8bit를 가진다 8bit은 2byte니까 2를 반환한다

Mat.elemSize()

  • 한 픽셀 당 바이트 수의 채널을 곱한 값
  • 위의 예제는 한 픽셀이 8bit의 크기를 가지면서 3개의 채널로 구성되어 있으니 24를 4로 나눈 6을 반환한다
  • elemSize1(), elemSize() 모두 데이터 타입은 값의 영향을 미치지 않고 한 픽셀이 몇바이트의 값을 가지고 채널이 몇개인지만 신경써주면 된다

이미지 처리 함수

imread()

  • cv::imread(const String& filename, int flags = IMREAD_COLOR)
  • 이미지 파일을 읽는 함수
  • 첫 번째 인자는 이미지 파일의 경로, 두 번째 인자는 이미지를 어떻게 읽을지를 결정하는 플래그
  • 이미지 파일의 경로가 " "형태라면 상대 경로로 지정이 되어있는데 경로는 환경마다 다르다. xcode에서는 직접 workspace를 정해주고 window의 visual studio 같은 경우는 project 폴더로 지정이 되어있다한다
  • flags 변수는 0, 1, -1이 될 수 있다. 0은 흑백 이미지, 1은 컬러 이미지, -1은 원본 이미지이다

imwrite()

  • cv::imwrite(const String& filename, InputArray img, const std::vector& params = std::vector())
  • 이미지 파일을 쓰는 함수
  • 첫 번째 인자는 저장할 파일의 경로이며, 두 번째 인자는 저장할 이미지이다

imshow()

  • cv::imshow(const String& winname, InputArray mat)
  • 이미지를 화면에 표시하는 함수. 첫 번째 인자는 창의 이름이며, 두 번째 인자는 표시할 이미지이다

waitKey()

  • cv::waitKey(int delay = 0)
  • 키보드 이벤트를 대기하는 함수
  • 인자는 대기 시간을 밀리초 단위로 지정하며, 0은 무한히 대기하 겠다는 의미로 이 함수는 사용자가 키를 누를 때까지 프로그램을 일시 중지시킨다

namedWindow()

  • cv::namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE)
  • 이미지를 표시하기 위한 창을 생성하는 함수

destroyAllWindows()

  • 모든 OpenCV 창을 닫는 함수
  
#include <opencv2/opencv.hpp>

int main() {
    // 이미지를 컬러 이미지로 읽습니다. cv::IMREAD_COLOR 부분은 1이 들어가도 되지만 코드의 가독성을 위해 이렇게 사용
    cv::Mat img = cv::imread("image.jpg", cv::IMREAD_COLOR);

    if (img.empty()) {
        std::cout << "Could not open or find the image" << std::endl;
        return -1;
    }

    // 이미지를 Display window라는 창의 화면에 표시합니다.
    cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);
    cv::imshow("Display window", img);

    // 키 입력을 대기합니다.
    cv::waitKey(0);

    // 아무 키 입력이 들어오면 이미지를 output.jpg라는 이름으로 저장합니다.
    cv::imwrite("output.jpg", img);

    return 0;
}

  

도형 그리기 함수

cv::line()

  • 이미지에 직선을 그림
  • cv::line(cv::Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
  • img: 이미지, pt1과 pt2: 직선의 시작점과 끝점, color: 선의 색상, thickness: 선의 두께

cv::rectangle()

  • 이미지에 사각형을 그림
  • cv::rectangle(cv::Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
  • img: 이미지, pt1과 pt2: 사각형의 왼쪽 위와 오른쪽 아래, color: 선의 색상, thickness: 선의 두께

cv::circle()

  • 이미지에 원을 그림
  • cv::circle(cv::Mat& img, Point center, int radius, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
  • img: 이미지, center: 원의 중심, radius: 원의 반지름, color: 원의 색상, thickness: 원의 두께

cv::ellipse()

  • 타원 그리는 함수
  • cv::ellipse(cv::Mat& img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
  • img: 이미지, center: 타원의 중심, axes: 주축의 길이, angle: 타원의 기울기, startAngle와 endAngle: 타원 호의 시작 각도와 끝 각도, color: 타원의 색상, thickness: 타원의 두께

cv::polylines()

  • 다각형 그려주는 함수

cv::putText()

  • 이미지에 텍스트를 그려주는 함수

Mat.type()

  • 행렬의 데이터 타입을 반환. 행렬의 깊이와 채널 수를 포함하는 정수로 위에서 봤던 CV_8UC3, CV_32FC1과 같은 형태로 반환된다

Mat.depth()

Mat::zeros()

  • 새로운 행렬을 생성할 때 모든 원소 값을 0으로 초기화하는 경우에 사용

Mat::ones()

  • 모든 원소가 1로 초기화된 행렬을 생성하는 경우에 사용

Mat::eye()

  • 단위 행렬을 생성할때 사용

img.clone()

  • 이미지를 복사

img.copyTo(Mat M)

  • 이미지의 카피본을 M 객체가 가르키도록

0개의 댓글