[w5d2] OpenCV 영상 처리

16410 단어 opencvopencv

(Ubuntu 18.04.6 LTS)
2022.03.15
C++, VS code 사용
프로그래머스 자율주행 데브코스

영상 파일 불러와서 출력하기 (전체 코드)

기본적인 구조는 암기 필요!

#include <iostream>
#include "opencv2/opencv.hpp"

int main()
{
    cv::Mat img = cv::imread("./resources/lenna.bmp",cv::IMREAD_COLOR);

    if (img.empty()){
        std::cerr << "Image load failed!" << std::endl;
        return -1;
    }

    cv::namedWindow("image");
    cv::imshow("image",img);
    cv::waitKey();
    cv::destroyAllWindows();
    return 0;
}

cv::, std:: 부분을 생략하고 싶으면 아래의 코드를 main 함수 이전에 넣어줄 수 있다.

using namespace std;
using namespace cv;

코드 분석

#include <iostream>
#include "opencv2/opencv.hpp"

헤더 파일을 include. OpenCV 사용 위해서는 opencv2/opencv.hpp를 include 해야함.

int main()
{
    cv::Mat img = cv::imread("./resources/lenna.bmp",cv::IMREAD_COLOR);

cv::Mat은 행렬 형태 클래스. cv::imread는 파일을 읽어오는 함수.
Mat cv::imread(const String& filename,int flags= IMREAD_COLOR )
flag에 따라서 어떤 형태로 불러올지 결정할 수 있음.

  • IMREAD_UNCHANGED: 투명도까지 불러옴.
  • IMREAD_GRAYSCALE: Gray scale image로 불러옴.
  • IMREAD_COLOR: True color image로 불러옴. 디폴트.

cv::Mat img: Mat type 변수 img 생성.
"./resources/lenna.bmp": 현재 폴더의 resources 폴더 내 lenna.bmp를 불러옴.
cv::IMREAD_COLOR: True color image로.

    if (img.empty()){
        std::cerr << "Image load failed!" << std::endl;
        return -1;
    }

에러 검출 코드.
img.empty(): Mat 타입 변수 img가 비어있을 경우 true.
img가 비어있을 경우 "Image load failed"가 출력되며 return 값 -1과 함께 종료.

    cv::namedWindow("image");

빈 창을 생성. 창의 이름은 "image"

    cv::imshow("image",img);

void cv::imshow ( const String & winname, InputArray mat )
"image"라는 창에, img 객체를 출력함.

    cv::waitKey();

키보드 입력을 기다림. 위에서 imshow만 한 경우에 창을 볼 수 없는데, waitKey를 하면서 볼 수 있음. 안에 숫자가 들어가는 경우에 그 시간동안 Key 입력을 기다리며, 생략하거나 0이면 계속 기다림.
ASCII 코드로, ESC를 받고 싶으면 27.

    cv::destroyAllWindows();

모든 창을 닫음.

주요 클래스


Point - Point(x,y) 형태로 사용.
Size - Size(width,height) 형태로 사용.
Rect - Rect(x,y,width,height) 형태로 사용.
String - 문자열. OpenCV 4.x 버전부터 std::string 클래스와 동일.
Vec - 같은 자료형 원소 여러개로 구성된 데이터 형식.
Scalar: 4개의 double형을 가지는 자료형. (4개 원소 벡터)

Mat - 행렬

Channel: 원소 하나가 구성되어있는 개수.

  • gray scale은 하나의 밝기. true color는 rgb 3개의 데이터

Depth: 행렬 원소가 사용하는 자료형 정보.

  • 8U: 8 bit, unsigned char
  • 8S: 8 bit, sigend char
  • 32F: 32 bit, float

Type: Depth + Channel,대표적인 예시는 아래와 같다.

  • CV_8UC1: 8bit unsigned char, channel 1 == Gray scale image
  • CV_8UC3: 8bit unsigned char, channel 3 == True color image

Mat 객체 초기화

cv::Mat img1(height,width,CV_8UC1);
cv::Mat img2(Size(width,height),CV_8UC3);

단순하게 Mat 객체 생성.

cv::Mat img3(height,width,CV_8UC1,255);
cv::Mat img4(height,width,CV_8UC3,Scalar(0,0,255));

img3은 gray scale image 생성, 원소 모두 255 (흰색)
img4는 true color image 생성, OpenCV에서는 BGR 순서로 데이터를 저장하므로 붉은 색 255, 나머지는 0.

cv::Mat img5 = Mat::zeros(3,3,CV_32SC1);
cv::Mat img6 = Mat::ones(3,3,CV_32FC1);

img5는 0, img6은 1로 채워져있음.

cv::Mat img1 = cv::imread("lenna.bmp");
cv::Mat img2 = img1

cv::Mat img3 = img1.clone();
cv::Mat img4;
img1.copyTo(img4);

img2는 얕은 복사와 유사. img1와 img2는 같은 대상을 가리키며, 하나를 바꿀 시 다른 것도 바뀜.
img3, img4는 깊은 복사와 유사. 복사하여 다른 대상 생성.

픽셀 접근

//at 사용
cv::Mat img1 = cv::imread("lenna.bmp",cv::IMREAD_GRAYSCALE);
for (int y=0;y<img1.rows;y++){
	for (int x=0;x<img1.cols;x++{
    	img1.at<uchar>(y,x)++;
    }
}

Mat 객체.at<Type.>(y,x)와 같은 형태로 개별 픽셀에 접근할 수 있음.
위의 코드는 1씩 밝기를 증가하는 코드.

//ptr 사용
cv::Mat img1= cv::imread("lenna.bmp",cv::IMREAD_GRAYSCALE);
for (int y=0;y<img1.rows;y++){
	uchar* p = img1.ptr<uchar>(y);
	for (int x=0;x<img1.cols;x++{
    	p[x]++;
    }
}

<Type.>* p = Mat 객체.ptr<Type.>(y) 형태로 p는 y row를 가르키며 값은 p[x] 꼴로 불러올 수 있음. 0부터 시작.
행단위 접근에 유리한 측면을 가지고 있음.

좋은 웹페이지 즐겨찾기