컴퓨터 비전

OpenCV 영상의 특징 추출

Jagbbum 2023. 10. 25. 11:12

에지 검출과  소벨 필터

에지

- 영상의 픽셀의 밝기 값이 급격하게 변하는 부분

 

기본적인 에지 검출 방법

- 영상을 x,y 변호의 함수로 간주했을 때 함수의 1차 미분 값이 크게 나타나는 부분을 검출

 

가우시안 블러와 에지 검출

- 입력 영상에 가우시안 블러를 적용하여 잡음 제거 후 에지 검출

 

OpenCV 에지 검출

for (int y = 1; y < src.rows - 1; y++) {
	for (int x = 1; x < src.cols - 1; x++) {
		int v1 = src.at<uchar>(y - 1, x + 1)
			+ src.at<uchar>(y, x + 1) * 2
			+ src.at<uchar>(y + 1, x + 1)
			- src.at<uchar>(y - 1, x - 1)
			- src.at<uchar>(y, x - 1) * 2
			- src.at<uchar>(y + 1, x - 1);
		dx.at<uchar>(y, x) = saturate_cast<uchar>(v1 + 128);
	}
}// 간단한 필터 마스크 제작

그래디언트

- 함수 f(x,y)를 x축과 y축으로 각각 편미분하여 벡터 형태로 표현한 것

- 그래디언트 크기: 픽셀 값의 차이 정도, 변화량

- 그래디언트 방향: 픽셀 값이 가장 급격하게 증가하는 방향

for (int y = 1; y < src.rows - 1; y++) {
	for (int x = 1; x < src.cols - 1; x++) {
		int v1 = src.at<uchar>(y - 1, x + 1)
			+ src.at<uchar>(y, x + 1) * 2
			+ src.at<uchar>(y + 1, x + 1)
			- src.at<uchar>(y - 1, x - 1)
			- src.at<uchar>(y, x - 1) * 2
			- src.at<uchar>(y + 1, x - 1);
		int v2 = src.at<uchar>(y + 1, x + 1)
			+ src.at<uchar>(y + 1, x) * 2
			+ src.at<uchar>(y + 1, x + 1)
			- src.at<uchar>(y - 1, x + 1)
			- src.at<uchar>(y - 1, x) * 2
			- src.at<uchar>(y - 1, x + 1);
		dx.at<uchar>(y, x) = saturate_cast<uchar>(v1 + 128);
		dy.at<uchar>(y, x) = saturate_cast<uchar>(v2 + 128);
		mag.at<uchar>(y, x) = saturate_cast<uchar>(sqrt(v1 * v1 + v2 * v2)); // 그래디언트 계산
	}
}

Mat edge = mag > 120; // 임계값 120

OpenCV Sobel 연산자

void Sobel( InputArray src, OutputArray dst, int ddepth,
                         int dx, int dy, int ksize = 3,
                         double scale = 1, double delta = 0,
                         int borderType = BORDER_DEFAULT );
Mat dx, dy;
Sobel(src, dx, CV_32FC1, 1, 0); // x방향 미분
Sobel(src, dy, CV_32FC1, 0, 1); // y방향 미분

Mat mag;
magnitude(dx, dy, mag); // 그래디언트 계산
mag.convertTo(mag, CV_8UC1);

Mat edge = mag > 150; // 임계값 조정

케니 에지 검출

케니 에지

- 정확한 검출: 에지가 아닌 점을 에지로 찾거나 에지를 검출하지 못하는 확률 최소화

- 정확한 위치: 실제 에지의 중심 검출

- 단일 에지: 하나의 에지는 하나의 점으로 표현

 

케니 에지 검출 방법

1. 가우시안 필터링

2. 그래디언트 계산(크기&방향)

3. 비최대 억제 - 하나의 에지가 여러 개의 픽셀로 표현되는 현상을 없애기 위해 국지적 최대인 픽셀만 에지로 설정

4. 이중 임계값을 이용한 히스테리시스 에지 트래킹

 - 강한 에지: 무조건 최종 에지로 선정

 - 약한 에지: 강한 에지와 연결된 픽셀만 최종 에지로 선정

 

OpenCV 케니 에지 검출기

void Canny( InputArray image, OutputArray edges,
                         double threshold1, double threshold2,
                         int apertureSize = 3, bool L2gradient = false );

하프 변환 직선 검출과 원 검출

하프 변환 직선 검출

- 2차원 영산 좌표에서의 직선의 방정식을 파라미터 공간으로 변환하여 직선을 찾는 알고리즘

방정식 : xcos θ  + ysin θ  = p

 

허프 변환 직선 검출 함수

void HoughLines( InputArray image, OutputArray lines,
                              double rho, double theta, int threshold,
                              double srn = 0, double stn = 0,
                              double min_theta = 0, double max_theta = CV_PI );
                              
void HoughLinesP( InputArray image, OutputArray lines,
                               double rho, double theta, int threshold,
                               double minLineLength = 0, double maxLineGap = 0 ); 
                               // 확률적 허프 변환에 의한 선분 검출 함수

허프 변환 원 검출

- 속도 향상을 위해 Hough gradient method 사용

  - 입력 영상과 동일한 2차원 평면 공간에서 축적 영상을 생성

  - 에지 픽셀에서 그래디언트 계산

  - 그래디언트 방향에 따라 직선을 그리면서 값을 누적

  - 원의 중심을 먼저 찾고, 적절한 반지름 검출

 

허프 변환 원 검출 함수

void HoughCircles( InputArray image, OutputArray circles,
                               int method, double dp, double minDist,
                               double param1 = 100, double param2 = 100,
                               int minRadius = 0, int maxRadius = 0 );

코너 검출

코너

- 두 에지의 교차점. 서로 다른 방향의 에지가 공존하는 점

- 평탄한 영역과 에지 영역은 고유한 위치를 찾기 어려움

- 코너는 변별력이 높은 편이며 영상의 이동 및 회전 변환에 강인함

 

해리스 코너 검출 방법

- 영상 내에 정의된 윈도우 안의 픽셀 값이 상하좌우 방향으로 급격하게 변하는 위치를 코너로 구정

void cornerHarris( InputArray src, OutputArray dst, int blockSize,
                                int ksize, double k,
                                int borderType = BORDER_DEFAULT );

 

Good features to track

- 해리스 코너 검출 방법을 향상시킨 코너 검출 방법

void goodFeaturesToTrack( InputArray image, OutputArray corners,
                                     int maxCorners, double qualityLevel, double minDistance,
                                     InputArray mask = noArray(), int blockSize = 3,
                                     bool useHarrisDetector = false, double k = 0.04 );

 

FAST(Features from Accelerated Segment Test) 코너 검출 방법

- 각각의 픽셀에 대해 주면 16개 픽셀 값 크기를 분석하여 해당 픽셀보다 충분히 밝거나 어더운 픽셀이 n개이상 연속으로 나타나면 코너로 인식

void FAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
                      int threshold, bool nonmaxSuppression=true );

'컴퓨터 비전' 카테고리의 다른 글

OpenCV 영상 분할과 객체 검출  (0) 2023.10.27
OpenCV 이진 영상 처리  (0) 2023.10.26
OpenCV 컬러 영상 처리  (1) 2023.10.24
OpenCV 특정점 검출과 매칭  (1) 2023.10.23
OpenCV 필터링  (0) 2023.10.20