Home OpenCV 픽셀 참조
Post
Cancel

OpenCV 픽셀 참조

해당 포스팅은 OpenCV 4로 배우는 컴퓨터 비전과 머신러닝 (황선규 저)를 보고 공부하며 개인적인 용도를 위해 정리한 글이다.

cv::Mat::at()

  • 가장 직관적이며 행과 열을 나타내는 두 개의 정수를 인자로 받아 해당 위치의 픽셀값을 참조
  • 템플릿으로 재정의해야하므로 항상 자료형을 정의해야함
  • RGB를 갖는 3채널의 자료형은 cv::Vec3b이다
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>

int main(void)
{
    cv::Mat img = cv::imread("./path/to/image");

    cv::Vec3b pix = img.at<cv::Vec3b>(100, 100);

    // 행렬을 순환해가며 픽셀 값 참조하기
    for(int i = 0; i < img.rows; i ++)
    {
        for(int j = 0; j < img.cols; j++)
        {
            std::cout << "at pixel value(" << i << ", " << j << "): " << img.at<cv::Vec3b>(i, j) << std::endl;
        }
    }  // i, j 값을 통해 행렬 전체를 순환해가며 픽셀값을 반환한다

    return 0;
}

cv::Mat::ptr()

  • 특정 행의 첫 번째 원소의 주소값을 반환
  • 해당 함수는 행 단위로 행렬을 순환한다
  • cv::Mat::at()과 마찬가지로 3채널의 자료형은 cv::Vec3b이다.
    • 1채널을 갖는 (그레이스케일) 행렬은 uchar.
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>

int main(void)
{
    cv::Mat img = cv::imread("./path/to/image");

    cv::Vec3b *ptr = img.ptr<cv::Vec3b>(100);  // 행값만 입력하면 해당 행 전체 중 첫 번째 픽셀값의 주소값만 반환
    cv::Vec3b ptr100 = ptr[100];  // 100번째 행의 100번째 열의 픽셀값

    // 행렬을 순환해가며 픽셀 값 참조하기
    for(i = 0; i < img.rows; i++)
    {
        cv::Vec3b *ptr = img.ptr<cv::Vec3b>(i);  // 행 지정
        for(int j = 0; j < img.cols; j++)
        {
            std::cout << "ptr pixel value(" << i << ", " << j << "): " << ptr[j] << std::endl;
        }
    }

    return 0;
}

행 단위의 접근은 ptr이 훨씬 빠르지만 임의의 픽셀 접근은 at이 더 편리하다.

cv::MatIterator_

  • cv::Mat::at()cv::Mat::ptr()은 행렬의 범위를 벗어나면 에러 발생
  • 이를 방지하기 위해 OpenCv에선 반복자iterator를 지원
  • 행렬의 beginend를 통해 접근하므로 범위를 벗어날 염려가 없음
  • 행렬 전체를 순차적으로 순회하기 때문에 ptr보단 느리고 at보단 자유도가 낮아 사용성이 높지 않음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "opencv2/opencv.hpp"

#include <iostream>

int main(void)
{
    cv::Mat img = cv::imread("./path/to/image");

    for(cv::MatIterator_<cv::Vec3b> i = img.begin<cv::Vec3b>(); i != img.end<cv::Vec3b>(); ++i)
    {
        std::cout << "iter pixel value: " << *i << std::endl;
    }

    return 0;
}
  • ibegin에서 시작해 end가 아닐 때까지 행렬 전체를 순환한다
This post is licensed under CC BY 4.0 by the author.

OpenCV 행렬 범위 참조

OpenCV 행렬 변환