11.1 영상의 이진화
11.1.1 이진화
영상의 이진화 (binarization): 영상의 각 픽셀을 두 개의 부류로 나누는 작업. 이진화가 적용된 이진 영상은 보통 흰색과 검은색 픽셀로만 구성된다.
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type);
- src: 입력 영상
- dst: 출력 영상. 입력 영상과 같은 크기, 같은 타입을 갖는다
- thresh: 임계값
- maxval: THRESH_BINARY 또는 THRESH_BINARY_INV 방법을 사용할 때 결과 영상의 최댓값
- type: 임계값 연산 방법. THresholdTypes 열거형 상수를 지정
- 반환값: 사용된 임계값, THRESH_OTSU 또는 THRESH_TRIANGLE 방법을 사용할 때 자동으로 결정된 임계값을 반환
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
void on_threshold(int pos, void* userdata);
int main(int argc, char* argv[])
{
Mat src;
if (argc < 2)
src = imread("neutrophils.png", IMREAD_GRAYSCALE);
else
src = imread(argv[1], IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
imshow("src", src);
namedWindow("dst");
createTrackbar("Threshold", "dst", 0, 255, on_threshold, (void*)&src);
setTrackbarPos("Threshold", "dst", 128);
waitKey(0);
return 0;
}
void on_threshold(int pos, void* userdata)
{
Mat src = *(Mat*)userdata;
Mat dst;
threshold(src, dst, pos, 255, THRESH_BINARY);
imshow("dst", dst);
}
- 9행: 프로그램 실행 시 명령행 인자를 받을 수 있도록 main() 함수에 argc와 argv 인자를 지정
- 13~16행: 명령행 인자 개수가 2보다 작으면 neultrophils.png 파일을 입력 영상으로 사용. 만약 프로그램 실행 파일 이름 뒤에 사용할 영상 파일이름을 명시하면 해당 파일을 입력 영상으로 사용
- 26행: dst 창에 Threshold 이름의 트랙바를 생성. 트랙바의 최댓값은 255이고, 트랙바 콜백 함수 이름은 on_threshold임. 입력 영상 src 의 주소를 사용자 데이터로 전달
- 27행: 프로그램이 처음 실행될 때 트랙바 위치가 128이 되도록 설정하여 on_threshold() 함수가 처음에 한 번 실행되도록 함
- 35행: void* 타입의 인자 userdata를 Mat* 타입으로 형변환한 후 src 변수로 참조
- 38행: 사용자가 지정한 트랙바 위치를 이용하여 이진화를 수행하고 그 결과를 dst 영상에 저장
11.1.2 적응형 이진화
전역 이진화(gloabl binarization): 영상의 모든 픽셀에 같은 임계값을 적용하여 이진화를 수행하는 방식. 하지만 균일하지 않은 조명 환경에서 촬영된 영상과 같은 경우 전역 이진화를 수행하면 객체와 배경이 적절하게 분리되지 않는 경우가 발생
void adaptiveThreshold(InputArray src, OutputArray dst,
double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C);
- image: 입력 영상. CV_8UC1 또는 CV_8SC1
- dst: 출력 영상. src와 같은 크기, 같은 타입임
- maxValue: 이진화 결과 영상의 최댓값
- adaptiveMethod: 적응형 이진화에서 블록 평균 계산 방법 지정. ADAPTIVE_THRESH_MEAN_C 또는 ADAPTIVE_THRESH_GAUSSIAN_C 중 하나를 지정
- thresholdType: THRESH_BINARY 또는 THRESH_BINARY_INV 둘 중 하나를 지정
- blockSize: 임계값 계산 시 사용하는 블록 크기. 3보다 같거나 큰 홀수를 지정해야함
- C: 임계값 조정을 위한 상수. 블록 평균에서 C를 뺀 값을 임계값으로 사용
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
void on_trackbar(int pos, void* userdata);
int main()
{
Mat src = imread("sudoku.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
imshow("src", src);
namedWindow("dst");
createTrackbar("Block Size", "dst", 0, 200, on_trackbar, (void*)&src);
setTrackbarPos("Block Size", "dst", 11);
waitKey(0);
return 0;
}
void on_trackbar(int pos, void* userdata)
{
Mat src = *(Mat*)userdata;
int bsize = pos;
if (bsize % 2 == 0) bsize--;
if (bsize < 3) bsize = 3;
Mat dst;
adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY,
bsize, 2);
imshow("dst", dst);
}
- 21행: 적응형 이진화의 블록 크기 지정을 위한 트랙바를 생성
- 22행: 트랙바의 초기 위치를 11로 설정
- 33행: bsize: 값이 짝수이면 1을 빼서 홀수로 만듦
- 34행: bsize 값이 3보다 작으면 3으로 설정
- 37행: 트랙바에서 설정한 블록 크기를 이용하여 적응형 이진화를 수행. 가우시안 가중 평균을 사용, 블록 평균에서 5를 뺀 값을 임계값으로 사용
11.2 모폴로지 연산
11.2.1 이진 영상의 침식과 팽창
모폴로지(morphology): 형태 또는 모양에 관한 학문. 영상 처리 분야에서 모폴로지는 영상에서 객체의 형태 및 구조에 대해 분석하고 처리하는 기법을 의미한다. 모폴로지 기법은 그레이스케일 영상과 이진 영상에 대하여 모두 적용할 수 있지만, 주로 이진 영상에서 객체의 모양을 단순화시키거나 잡음을 제거하는 등 용도로 사용됨.
영상의 모폴로지 기법에서 가장 기본이 되는 연산은 침식(erosion)과 팽창(dilation). 이진 영상의 침식 연산은 객체 영역의 외곽을 골고루 깎아 내는 연산으로 전체적으로 객체 영역은 축소되고 배경은 확대된다.
Mat getStructuringElement(int shape, Size kszie, Point anchor = Point(-1, -1));
- shape: 구조 요소의 모양
- ksize: 구조 요소의 크기
- anchor: MORPH_CROSS 모양의 구조 요소에서 십자가 중심 좌표. Point(-1, -1)을 지정하면 구조 요소 중앙을 십자가 중심 좌표로 사용
- 반환값: 구조 요소 행렬
void erod(InputArray src, OutputArray dst,
InputArray kernel, Point anchor = Point(-1, -1), int iterations = 1,
int borderType = BOREDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue());
- src: 입력 영상
- dst: 출력 영상. src와 같은 크기, 같은 타입
- kernel: 구조 요소. 만약 Mat()을 지정하면 3x3 사각형 구조 요소를 사용. 그 외의 구조 요소는 getStructuringElement() 함수를 이용하여 만들 수 있음
- anchor: 고정점 위치 (-1, -1)을 지정하면 구조 요소 중앙을 고정점으로 사용
- itertations: 반복 횟수
- borderType: 가장자리 픽셀 확장 방식
- borderValue: borderType이 BORDER_CONSTANT인 경우, 확장된 가장자리 픽셀을 채울 값. 기본값으로 설정된 morphologyDefaultBorderValue() 함수는 모든 멤버 변수가 DBL_MAX로 채워진 Scalar 객체를 반환
void dilate (InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point (-1, -1),
int iterations = 1, int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue());
- src: 입력 영상
- dst: 출력 영상. src와 같은 크기, 같은 타입
- kernel: 구조 요소. 만약 Mat()을 지정하면 3x3 사각형 구조 요소를 사용. 그 외의 구조 요소는 getStructuringElement() 함수를 이용하여 만들 수 있음
- anchor: 고정점 위치. (-1, -1)을 지정하면 구조 요소 중앙을 고정점으로 사용
- iteration: 반복 횟수
- borderType: 가장자리 픽셀 확장 방식
- borderValue: borderType이 BORDER_CONSTANT인 경우, 확장된 가장자리 픽셀을 채울 값
void erode_dilate()
{
Mat src = imread("milkdrop.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return;
}
Mat bin;
threshold(src, bin, 0, 255, THRESH_BINARY | THRESH_OTSU);
Mat dst1, dst2;
erode(bin, dst1, Mat());
dilate(bin, dst2, Mat());
imshow("src", src);
imshow("bin", bin);
imshow("erode", dst1);
imshow("dilate", dst2);
waitKey();
destroyAllWindows();
}
- 3행: milkdrop.bmp 파일을 그레이스케일 영상 형식으로 불러와 src에 저장
- 11행: src 영상에 대해 오츠 알고리즘으로 자동 이진화를 수행하고, 그 결과를 bin에 저장
- 14행: bin 영상에 3x3 정방형 구조 요소를 이용하여 침식 연산을 수행하고, 그 결과를 dst1에 저장
- 15행: bin 영상에 3x3 정방형 구조 요소를 이용하여 팽창 연산을 수행하고, 그 결과를 dst2에 저장
11.2.2 이진 영상의 열기와 닫기
void morphologyEx(InputArray src, OutputArray dst, int op, InputArray kernel,
Point anchor = Point (-1, -1), int iterations = 1, int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue());
- src: 입력 영상
- dst: 출력 영상. src와 같은 크기, 같은 타입
- op: 모폴로지 연산 타입. MorphTypes 열거형 상수를 지정
- kernel: 구조 요소, getStructuringElement() 함수를 이용하여 생성
- anchor: 고정점 위치. (-1, -1)를 지정하면 구조 요소 중앙을 고정점으로 사용
- iterations: 반복 횟수
- borderType: 가장자리 픽셀 확장 방식
- borderValue: borderType이 BORDER_CONSTANT인 경우, 가장자리 픽셀값
void open_close()
{
Mat src = imread("milkdrop.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return;
}
Mat bin;
threshold(src, bin, 0, 255, THRESH_BINARY | THRESH_OTSU);
Mat dst1, dst2;
morphologyEx(bin, dst1, MORPH_OPEN, Mat());
morphologyEx(bin, dst2, MORPH_CLOSE, Mat());
imshow("src", src);
imshow("bin", bin);
imshow("opening", dst1);
imshow("closing", dst2);
waitKey();
destroyAllWindows();
}
- 3행: milkdrop.bmp 파일을 그레이스케일 영상 형식으로 불러와 src에 저장
- 11행: src 영상에 대해 오츠 알고리즘으로 자동 이진화를 수행하고, 그 결과를 bin에 저장
- 14행: bin 영상에 3x3 정방형 구조 요소를 이용하여 열기 연산을 수행하고, 그 결과를 dst1에 저장
- 15행: bin 영상에 3x3 정방형 구조 요소를 이용하여 닫기 연산을 수행하고, 그 결과를 dst2에 저장
'3학년 > OpenCV' 카테고리의 다른 글
[OpenCV] 13장 객체 검출 (0) | 2023.07.03 |
---|---|
[OpenCV] 12장 레이블링과 외곽선 검출 (0) | 2023.07.02 |
[OpenCV] 10장 컬러 영상 처리 (0) | 2023.07.02 |
[OpenCV] 9장 에지 검출과 응용 (0) | 2023.07.01 |
[OpenCV] 8장 영상의 기하학적 변환 (0) | 2023.07.01 |