본문 바로가기
카테고리 없음

영상 scale resize시키는 방법

by 구름갈대호수 2022. 3. 25.

결과 영상을 원하는 크기로 지정할 수 있는 매우 일반적인 cv::resize 함수가 있다. 이 함수는 크기를 지정해 간단하게 호출하며, 원 영상보다 작거나 크게 할 수 있다.

cv::Mat resizedImage; // 크기가 조절된 영상이 들어감 cv:: resize(image, resizedImage, cv:: Size(image.cols/3, image.rows/3)); // 1/3 줄이기

다른 옵션으로는 스케일 인자로 지정해 재조절하거나 재샘플링 과정에 사용하는 특정 보간법을 선택한다.

참고 사항

CV :: boxFilter 함수는 1로 구성 사각형 커널로 영상을 필터링한다. 평균 필터와 유사하지만, 계수의 개수로 결과를 나누지 않는다.

2장의 ‘이웃 접근으로 영상 조회’ 절의 부연 설명에서 cv:: filter2D 함수를 소개했다. 이 함수는 영상에 원하는 커널을 입력해 선형 필터를 적용한다.

중간값 필터를 이용한 영상 필터링

6장의 첫 번째 예제는 선형 필터의 개념을 소개했다. 또한 비선형 필터도 있는데, 영상처리에서 유용하게 사용할 수 있다. 이런 필터는 이번 예제에서 보여주는 중간값 필터다.

중간값 필터는 특히 소금 후추 잡음을 막는 데 유용하므로, 2장의 첫 번째 예제에서 만들었던 영상을 사용해 여기에서 다시 살펴본다.


싱글턴 디자인 패턴 사용


싱글턴은 클래스 인스턴스 접근을 용이하게 하며, 또한 프로그램이 실행하는 동안 해당 클래스의 인스턴스가 하나만 존재함을 보장하는 다른 인기 있는 디자인 패턴이다. 이 예제에서는 컨트롤러 객체에 접근하기 위해 싱글턴을 사용한다.


준비


이전 예제의 ColorDetectController 클래스를 사용한다. 싱글턴 클래스를 얻기 위해 수정한다.


예제 구현


처음에 할 일은 단일 클래스 인스턴스에 대한 참조를 갖는 private 정적 멤버 변수를 추가한다. 또한 클래스 인스턴스의 추가를 막으려면 생성자를 private으로 만든다.

class Color Detect Controller { private: // 싱글턴에 대한 포인터 static ColorDetectController *singleton; ColorDetector *cdetect; // private 생성자 ColorDetectController() { // 애플리케이션 설정 cdetect= new Color Detector(); }

또한 복사 생성자와 싱글턴 고유 인스턴스의 복사본을 생성하지 못하게 하는 operator=를 만들 수 있다. 클래스를 사용하는 사용자가 클래스의 인스턴스가 필요할 때마다 명령을 내리면 싱글턴 객체가 만들어진다. 존재하지 않으면 인스

이름에서 보듯 MVC 패턴은 세 가지 컴포넌트를 갖는다. 각 역할을 살펴보면다음과 같다.

모델은 애플리케이션에 관련된 정보를 포함한다. 애플리케이션이 처리하는모든 데이터를 갖는다. 새로운 데이터가 만들어질 때 컨트롤러에게 알려주면새로운 결과를 띄우기 위한 뷰를 요청한다. 가끔은 모델이 여러 알고리즘을 함께 묶는데, 전략 패턴에 따라 구현 가능하다. 모든 알고리즘은 모델의 일부이다.

뷰는 사용자 인터페이스에 대응한다. 사용자에게 데이터를 보여주고 애플리케이션과 상호 작동하는 위젯들로 구성된다. 뷰의 역할 중 하나는 사용자가 내린 명령을 컨트롤러에게 전달하는 것이다. 새로운 데이터를 사용할 땐 새로운정보를 출력하기 위해 스스로 새로 고친다.

컨트롤러는 뷰와 모델을 함께 이어주는 모듈이다. 뷰의 요청을 받고 모델내 적절한 메소드에 전달한다. 또한 모델의 상태를 바꿨을 때 통지함에 따라새로운 정보를 출력하기 위해 새로 고치도록 뷰에 요청한다.

 


컨트롤러와 view와 model의 merging model

 


이전 예제에서 했던 그대로 ColorDetect 클래스를 사용한다. 이번에는 모델에애플리케이션 로직과 기본 데이터를 포함한다. 또한 컨트롤러를 구현하는데,ColorDetectController 클래스다. 그러면 가장 적합한 위젯이 들어간 매우정교한 GUI를 구축하기가 쉬워진다. 예를 들어 Qt를 사용하면 다음 인터페이스처럼 만들 수 있다.

cv:: Mat resulting

Color DetectController::getInstance () ->getLastResult(); if (!resulting.empty())

displayMat (resulting);

사실 Qt의 GUI 라이브러리는 MVC 패턴을 광범위하게 사용한다. 데이터모델과 동기화된 GUI의 모든 위젯을 유지하기 위한 시그널의 개념을 사용한다.


MVC 패턴 구현 algorithm


Qt 온라인 문서는 Qt의 MVC 패턴 구현에 대한 자세한 내용을 배우는 데 도움이 될 수 있다.

1장, ‘Qt를 이용한 GUI 애플리케이션 생성을 절의 예제에서는 Qt의 GUI 프레임워크와 시그널과 슬롯 모델을 간단하게 설명했다.


컬러 공간 변환


3장에서는 알고리즘을 클래스로 캡슐화하는 방법을 알려줬다. 이와 같이 간단한 인터페이스를 통해 알고리즘을 사용하기 쉬워진다. 또한 캡슐화는 사용하는클래스에 영향을 주지 않은 채 구현된 알고리즘을 수정할 수 있다. 이번 예제에서는 원리를 보여주고 다른 컬러 공간을 사용하기 위한 ColorDetector 클래스알고리즘을 수정한다. 그러므로 이번 예제는 OpenCV로 컬러 변환을 소개할수 있는 기회다.

준비

RGB 컬러 공간(BGR는 컬러가 저장된 순서에 따름)은 빨강, 녹색, 파랑 가산 원색을사용하는 데 기반을 둔다. 조합하면 서로 다른 컬러에 대한 넓은 컬러 재현 범위를 만들 수 있기 때문에 선택했다. 사실 인간의 시각 시스템은 빨강, 녹색, 파랑스펙트럼 주변을 느끼는 원추세포 감도에 따른 컬러 삼원색 지각에 기반을 둔

 


영상처리 클래스 구현 video rendering image class implementation method

 


부연 설명

저주피 필터는 영상을 감축할 때도 사용한다. 영상의 크기를 1/2로 줄이길 원한다고 가정하자. 영상의 행과 열을 제거해 처리할 수 있다고 생각할 것이다. 불행이도 결과 영상은 보기엔 그다지 좋지 않다. 예를 들어 원 영상 내의 비스듬한에지는 감축한 영상에서 계단 모양으로 나타난다. 다른 들쭉날쭉한 뒤틀림이명상의 곡선과 질감 부분에서 보인다. 원치도 않았던 인위적인 산물은 공간 앨리어싱이라고 하는 현상 때문에 나온 것이며, 영상 내의 고주파 컴포넌트에 너무 작고 높은 컴포넌트를 포함시키려고 할 때 발생한다. 사실 매우 작은 영상(즉,대우 적은 화소를 갖는 영상)은 높은 해상도 영상(고해상도 TV와 옛 TV 간의 차이점 생각)만큼의 깨끗한 질감과 날카로운 에지를 정확히 표현할 수 없다. 영상의 세밀한부분은 고주파에 대응하므로 영상의 크기를 감축하기 전에 고주파 컴포넌트를제거할 필요가 있다. 이번 예제에서 배운 그대로 저주파 필터를 적용한다. 따라서 성가신 인위적인 산물을 추가하지 않은 채 영상의 크기를 절반으로 줄이려면먼저 원 영상에 저주파 필터를 반드시 적용한 후 한 개의 행과 열을 모두 버린다. 이 작업은 cv::pyrDown 함수로 하는 것이 정확하다.

cv:: Mat reducedImage; // 감축된 영상이 들어감

cv:: pyr Down (image, reducedImage); // 절반으로 영상 크기 감축

5×5 가우시안 필터를 사용해 저주파 영상을 얻는다. 영상의 크기를 두 배로확대하는 상호적인 cv::pyrup 함수가 있다. 물론 영상을 줄이거나 늘린다면원 영상을 정확하게 복구할 수 없다. 줄이는 과정에서 발생하는 손실을 복구할수 없다. 두 함수는 영상 피라미드를 만들기 위해 사용한다. 영상 피라미드는다른 크기(종종 각 단계는 이전 단계의 절반 크기)를 갖는 영상의 스택 버전으로 구성한다. 예를 들어 영상 내의 객체를 감지하길 원할 때 피라미드의 맨 위에 있는작은 영상에서 처음으로 감지를 수행할 수 있고, 관심 객체를 찾으면 영상의고해상도 버전을 갖는 피라미드의 하위 레벨로 이동해 검색 범위를 확장할 수있다.


low path filer image filering 영상 필터링 효과

 

디지털 영상의 기본 컬러 공간인 이유는 취득하는 방법 때문으로, 빨강, 녹색, 파랑 필터를 통과하는 빛을 획득한다. 또한 디지털 영상에서 빨강, 녹색, 파랑 채널을 동일한 양으로 조합하면 그레이레벨의 명암도를 얻는다. 이건 검은색 (0,0,0)에서 흰색(255,255,255)이다.

low path filter 그래프
low path filter 그래프 


불행히도 RGB 컬러 공간을 사용해 거리를 계산하는 방법은 주어진 두 컬러간의 유사도를 측정하는 가장 좋은 방법이 아니다. 사실 RGB는 지각적으로 균일한 컬러 공간이 아니다. 즉, 동일한 거리로 구분한 두 개의 다른 컬러가 매우 다른 반면, 주어진 거리에서의 두 컬러가 매우 비슷할 수 있음을 의미한다.

이런 문제를 해결하기 위해 지각적으로 균일한 컬러 공간의 속성을 갖는 다른 컬러 공간이 등장했다. 특히 CIE L*a*b*는 해당 컬러 공간 중 하나다. 영상을 이 공간으로 변환하면 영상 화소와 대상 컬러 간의 유클리디안 거리는 다음 두 컬러의 시각적인 유사도의 측정을 의미한다. 이번 예제에서는 CIE L*a*b*로 작업하기 위해 이전 애플리케이션을 수정하는 방법을 보여준다.

예제 구현

OpenCV 함수인 cv:cvtColor를 사용해 각 컬러 공간을 쉽게 변환한다. 처리 메소드 시작 부분에서 입력 영상을 CIE L*a*b* 컬러 공간으로 변환해보자.

cv::Mat ColorDetector::process (const cv::Mat &image) {

// 필요하면 이진 맵으로 다시 할당// 입력 영상과 같은 크기이지만, 1채널임result.create (image.rows, image.cols, CV_8U);// 필요하면 중간 영상을 다시 할당 converted.create (image.rows, image.cols, image.type ());// Lab 컬러 공간으로 변환 cv::cvtColor (image, converted, CV_BGR2 Lab);// 변환한 영상에서 반복자를 가져오기

CV:: Mat <cv::Vec3b>::iterator itu

converted.begin<cv::Vec3b>();

 

필터의 화소를 고려한 image filtering method 효과

 

 

필터는 화소를 이웃 화소의 가중치 합으로 교체함으로써 대응하게 적용한 경우에 선형이라고 한다. 이것은 박스 필터의 경우로, 각 화소를 직사각형 이웃의 모든 합에 이웃의 크기로 나눈(평균값을 얻기 위한) 값으로 교체한다. 화소의 총개수의 1로 각 이웃 화소를 곱한 것과 같으며, 모든 값을 합한다. 필터의 서로 다른 가중치는 이웃을 고려한 각 화소 위치와 관련된 곱셈 요소를 보여주는 행렬을 사용해 표현할 수 있다. 행렬 중심 계수는 현재 적용하는 필터에서 처리하는 화소에 해당한다. 이와 같은 행렬을 때로는 커널 또는 마스크라고 한다. 3×3박스 필터에 대한 해당 커널은 다음과 같다.

1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9

선형 필터를 적용하면 영상의 화소마다 커널을 이동하고 연계된 가중치를 대응하는 화소와 곱한다. 수학적으로 이 연산은 회선이라고 한다.

이번 예제에서 만든 결과 영상을 보면 저주파 필터의 그물 효과는 영상을 흐리게 하거나 부드럽게 함을 알 수 있다. 이 필터는 객체의 에지에서 빠르게 변하는 시각적인 부분에 대응하는 고주파 컴포넌트를 완화시키기 때문에 놀라운 일이 아니다.

가우시안 필터의 경우에 화소별 가중치는 중심 화소부터 거리에 비례한다. 다음 형식을 갖는 1차원 가우시안 함수를 호출한다.

분할에는 화소에 대한 새로운 레이블이 있다. 클러스터링 과정을 반복하며 다시 새롭게 최적화를 거친 분할을 찾는 과정 등을 반복할 수 있다. 그러므로 그랩컷은 분할 결과를 점진적으로 개선할 때까지의 과정을 되풀이한다. 장면이 복잡한지 여부에 달려 있다는 전제하에서 좋은 해결 방법은 반복을 많이 하거나 반복을 적게 한다(쉬운 예로 반복 한 번만으로 충분하다!).

cv::grabCut 함수의 다섯 번째 인자를 설명하자면 사용자가 반복 횟수를 지정한다. 알고리즘이 관리하는 두 내부 모델은 함수의 인자로 넘겨지고 그리고 반환) 추가 반복으로 수행한 분할 결과를 개선하기 원한다면 마지막에 실행했던 모델 함수를 다시 호출할 수 있다.


형태학 연산을 이용한 영상 변환

워터쉐드를 이용한 영상 분할


워터쉐드vatershed 변환은 영상을 빨리 분할해 동일한 영역으로 만들기 위해 사용하는 인기 있는 영상처리 알고리즘이다. 영상이 위상적 입체감을 보여준다는아이디어에 따르는데, 동일한 영역은 상대적으로 급격한 에지로 기술된 평탄한분지에 대응한다. 결과를 간단하게 말하면 워터쉐드 알고리즘의 원래 버전이영상을 과도하게 분할해 여러 개의 작은 영역을 만들어 버린다. OpenCV는 이알고리즘의 변형을 제안하는 이유이며, 영상 분할에 대한 정의를 유도하는 미리정의된 마커 집합을 사용한다.

 


예제 구현


워터쉐드 분할은 cv::watershed 함수를 사용해 얻는다. 이 함수의 입력은 32비트 부호 있는 정수 마커 영상으로, 레이블을 대표하는 넌제로 화소로 구성한다.이 아이디어는 영상 내의 확실히 특정 영역에 속하는 것으로 알려진 일부 화소를마크한다. 초기 레이블링에서 워터쉐드 알고리즘이 다른 화소가 속할 영역을 결정한다. 이번 예제에서는 먼저 그레이레벨 영상인 마커 영상을 생성한 후 정수형영상으로 변환한다. 편하게 하기 위해 이 단계를 watershedSegmenter 클래스에 캡슐화한다.

 


형태학 operation을 이용한 영상 변환 image transformation

 

이전 예제의 애플리케이션을 수정한 클래스를 컴파일하면 CIE L*a*b* 컬러공간을 사용해 대상 컬러의 화소값을 이제 추출한다.


영상이 한 컬러 공간을 다른 컬러 공간으로 변환하면 각 입력 화소에 선형 또는비선형 변환을 적용해 결과 화소를 만든다. 결과 영상의 화소 타입은 입력 영상과 일치한다. 대부분 8비트 화소로 작업했더라도 물론 부동소수점(이런 경우 화소값은 일반적으로 0.0과 1.0 사이의 범위로 간주) 영상이나 정수형(화소는 일반적으로 0과65535 사이의 범위) 영상으로 컬러 변환할 수 있다. 그러나 화소값의 범위는 특정컬러 공간에 따른다. 예를 들어 CIE L*a*b 컬러 공간이라면 L 채널은 0과 100사이이고, a와 b 색도 컴포넌트는 -127과 127이다.

가장 일반적으로 사용하는 컬러 공간을 이용할 수 있다. 단지 OpenCV 함수에 정확한 마스크를 제공함에 따른 문제만 존재한다. 그 중 하나는 YCrCb인데,JPEG 압축에서 사용하는 컬러 공간이다. BGR를 YCrCb로 변환하기 위한 마스크는 CV BGR2YCrCh이다. 세 가지 정규 기본 컬러를 표현하려면 빨강, 녹색,파랑만 RGB 순서나 BGR 순서에서 사용할 수 있다.

HSV와 HLS 컬러 공간은 역시 흥미롭다. 컬러를 색상과 채도 컴포넌트에더해 명도나 광도 컴포넌트로 분리하며, 사람에게 컬러를 설명할 때 매우 자연스럽기 때문이다.

또한 컬러 영상을 그레이레벨 영상으로 변환할 수 있다. 결과는 1채널 영상이다.

CV::cvtColor (color, gray, CV_BGR2Gray);

물론 역으로 변환할 수 있다. 하지만 결과 컬러 영상의 3채널은 그레이레벨영상의 모두 동일한 값으로 채우게 된다.

 

 

 

댓글