본문 바로가기
opencv

(opencv) 이미지 저장형태, 액서스

by 꼰대코더 2023. 11. 25.

1. opencv에 있어서 이미지는 어떻게 저장되어 있을까?

프로그램이 실행될 때 사용되는 메모리는 여러 영역으로 구분됩니다. 대표적으로, 일시적으로 사용하는 로컬 변수는 스택 메모리를 사용하며, new 연산자를 통해 동적으로 할당되는 메모리는 힙 메모리를 사용합니다. 스택 메모리는 일반적으로 1MB 정도로 제한되어 있어 대용량 데이터(예: 이미지)를 저장하기에는 적합하지 않으므로, 이러한 데이터는 힙 메모리에 저장해야 합니다. 이를 통해 스택 오버플로우 에러를 방지할 수 있습니다.

OpenCV에는 Mat이라는 클래스가 있습니다. 이 클래스는 이미지의 정보(예: 너비, 높이, 타입 등)와 이미지 데이터가 저장된 힙 메모리의 주소를 저장하는 변수들을 포함하고 있습니다. Mat 변수를 단순히 선언할 경우, 이미지 정보와 메모리 주소에는 초기값이 할당됩니다.

만약 imread() 함수를 사용하여 이미지를 불러오면, 반환된 Mat 변수는 이미지 정보와 함께 읽어들인 이미지 데이터의 힙 메모리 주소를 저장합니다.

Mat 변수가 선언된 블록을 벗어나면 해당 변수는 스택 메모리에서 자동으로 삭제됩니다. 그러나 힙 메모리에 저장된 이미지 데이터는 어떻게 될까요? Mat 클래스는 이미지 데이터가 참조하는 카운트(reference count)를 관리하며, 로컬 변수가 소멸할 때 이 카운트가 0이 되면 해당 메모리 영역이 자동으로 해제됩니다. 따라서 프로그래머는 메모리 관리를 걱정할 필요가 없습니다.

OpenCV의 변환 및 이미지 처리 함수의 결과를 저장할 Mat 객체는 결과 정보를 미리 입력할 필요 없이, 단순히 로컬 변수를 선언하여 함수의 파라미터로 전달하면, 해당 함수가 자동으로 정보와 변환된 이미지 데이터를 위한 메모리를 할당하고 그 주소를 반환합니다.

 

예) Color 를 Gray 로 변환

cv::Mat img;
img = cv::imread("color.jpg");

cv::Mat img2;
// 새로운 img2 에 변환된 gray 를 보존
cv::cvtColor(img, img2, cv::COLOR_BGR2GRAY);

// 원래 img 에 변환된 gray 를 보존 -> 기존 칼라 정보와 메모리는 자동 삭제
cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);

메모리 설명 참조 힙영역 vs 스택 영역


2. 액세스 
    cv::Mat img = cv::imread("color.jpg");
 기본정보

넓이 img.cols
높이 img.rows
타입(색구성) img.type()
  PC 에서 주로 사용하는 타입
- CV_8UC1 : 8bits Unsinged Char 1 색 (=그레이)
- CV_8UC3 : 8bits Unsigned Char 3 색 (= BGR 칼라)
힙 메모리 데이터 존재 유무 img.empty()


 이미지 데이터 액서스
 (1) 직접 메모리 액서스
       (opencv) pixel access time
 (2) Mat 메서드를 이용한 방법
      * 메서드와 함수의 차이점 : 개념적인 문제로 클래스의 멤버 함수를 메서드로 부른다.

          블랙 사각형을 전체 이미지 cv::Mat image = ..... 라 하고
          A 영역 cv::Rect A( ...) , B 영역 cv::Rect B( ...) 을 액서스 하고자  한다면,

  • A 영역을 참조하기
    cv::Mat matA = image(A);
    이미지처리 함수에 matA를 파라미터로 지정을 하면 A 영역 부분만 변경되는 역효과가 발생하니 주의
         -> A 영역을 따로 복사해서 사용
  • A 영역을 복사하기
    cv::Mat matA;
    image(A).copyTo(matA); 
  • B 영역을 참조하기
    cv::Mat matB = image(B);
     이미지영역을 벗어나기 때문에 예외 에러가 발생
         아래와 같이 체크를 하여 겹치는 부분만 지정
    cv::Rect rectImage(0, 0, image.cols, image.rows);
    cv::Rect intersect = rectImage & rectB;
    cv::Mat matB = image(intersect);

'opencv' 카테고리의 다른 글

스캔문서의 기울기 알아보기 - 2  (0) 2023.11.27
스캔문서의 기울기 알아보기  (0) 2023.11.26
(opencv) Rectangle 간의 조작에 관해  (1) 2023.11.23
(opencv) pixel access time  (0) 2023.08.09
(opencv) Mat 의 기초  (0) 2023.08.05