C++함수 pyrUp 과 pyrDown 으로 이미지 피라미드 기능 구현

6423 단어 opencvpyrupc + +
목표.
이 문 서 는 다음 과 같은 문 제 를 풀 려 고 합 니 다.
어떻게 OpenCV 함수 pyrUp 과 pyrDown 을 사용 하여 그림 을 위로,아래로 샘플링 합 니까?
의 원리
Note 아래 내용 은 Bradski 와 Kaehler 의 대작 인 Learning OpenCV 에서 나온다.
그림 을 다른 크기 로 변환 해 야 할 때 두 가지 가능성 이 있 습 니 다.
그림 확대 또는
그림 축소.
비록 OpenCV 기하학 적 변환 부분 은 진정한 의미 의 이미지 크기 조정 함수(resize,앞으로 의 튜 토리 얼 에서 배 울 수 있 습 니 다)를 제공 하지만 이 편 에서 우 리 는 먼저 이미지 피 라 미 드 를 사용 하여 이미지 크기 를 조정 하 는 것 을 배 웁 니 다.이미지 피 라 미 드 는 시각 적 운용 에서 광범 위 하 게 사용 되 는 기술 입 니 다.
이미지 피라미드
하나의 이미지 피 라 미 드 는 일련의 이미지 의 집합 입 니 다.-모든 그림 은 같은 원본 이미지 에서 기원 합 니 다.-계단 을 통 해 아래로 샘플링 을 통 해 얻 을 수 있 습 니 다.특정한 종료 조건 에 이 르 러 서 야 샘플링 을 중단 합 니 다.
두 가지 유형의 이미지 피 라 미 드 는 문헌 과 응용 에 자주 나타난다.
가우스 피라미드(Gaussian pyramid):아래로 샘플링 하기
라 프 라 스 피라미드(Laplacian pyramid):피라미드 저층 이미지 에서 상부 샘플링 되 지 않 은 이미 지 를 재 구축 하 는 데 사용 합 니 다.
이 문서 에서 우 리 는 고 스 피 라 미 드 를 사용 할 것 이다.
가우스 피라미드
피 라 미 드 는 한 층 한 층 의 그림 으로 층 이 높 을 수록 그림 이 작다.

각 층 마다 아래 에서 위로 번호,등급(i+1)(G {로 표시)i+1}크기 가 등급 i 보다 작 음(G {i}))。
(i+1)등급 의 피라미드 이미 지 를 얻 기 위해 다음 과 같은 방법 을 사용 합 니 다.
G {i}고 스 커 널 볼 륨:

모든 짝수 줄 과 열 을 제거 합 니 다.
결 과 는 그림 의 4 분 의 1 에 불과 하 다 는 것 을 알 수 있다.그림%1 개의 캡 션 을 편 집 했 습 니 다.0}(원본 이미지)이상 의 절 차 를 반복 하면 피라미드 전 체 를 얻 을 수 있 습 니 다.
위의 과정 은 그림 을 아래로 샘플링 하 는 것 을 설명 합 니 다.그림 을 크게 만 들 면?:
우선 그림 을 각 방향 에서 원래 의 두 배로 확대 하고 새로 추 가 된 줄 과 열 을 0 으로 채 웁 니 다(0).
이전 과 같은 커 널(곱 하기 4)과 확 대 된 이미지 볼 륨 을 사용 하여'새로 추 가 된 픽 셀'의 유사 치 를 얻 을 수 있 습 니 다.
이 두 단계(아래 와 위로 샘플링)는 각각 OpenCV 함수 pyrUp 과 pyrDown 을 통 해 이 루어 집 니 다.우 리 는 아래 의 예제 에서 이 두 함 수 를 어떻게 사용 하 는 지 보 여 드릴 것 입 니 다.
Note 우리 가 아래로 샘플링 하여 그림 을 축소 할 때,우 리 는 실제로 약간의 정 보 를 잃 어 버 렸 다.
소스 코드
본 튜 토리 얼 의 소스 코드 는 아래 와 같 으 니,너 도 여기에서 다운로드 할 수 있다.

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
///     
Mat src, dst, tmp;
char* window_name = "Pyramids Demo";
/**
 * @   main
 */
int main( int argc, char** argv )
{
 ///     
 printf( "
Zoom In-Out demo
" ); printf( "------------------
" ); printf( " * [u] -> Zoom in
" ); printf( " * [d] -> Zoom out
" ); printf( " * [ESC] -> Close program

" ); /// - 2^{n} src = imread( "../images/chicky_512.jpg" ); if( !src.data ) { printf(" No data! -- Exiting the program
"); return -1; } tmp = src; dst = tmp; /// namedWindow( window_name, CV_WINDOW_AUTOSIZE ); imshow( window_name, dst ); /// while( true ) { int c; c = waitKey(10); if( (char)c == 27 ) { break; } if( (char)c == 'u' ) { pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) ); printf( "** Zoom In: Image x 2
" ); } else if( (char)c == 'd' ) { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) ); printf( "** Zoom Out: Image / 2
" ); } imshow( window_name, dst ); tmp = dst; } return 0; }
해명 하 다.
이 프로그램의 전체적인 절 차 를 살 펴 보 자.
그림 불 러 오기(이 경 로 는 프로그램 에서 설정 합 니 다.사용 자 는 그림 경 로 를 매개 변수 로 입력 할 필요 가 없습니다)

///      -        2^{n}   
src = imread( "../images/chicky_512.jpg" );
if( !src.data )
 { printf(" No data! -- Exiting the program 
"); return -1; }
두 개의 Mat 인 스 턴 스 를 만 듭 니 다.하 나 는 작업 결과(dst)를 저장 하고 다른 하 나 는 0 결 과 를 저장 합 니 다(tmp).

Mat src, dst, tmp;
/* ... */
tmp = src;
dst = tmp;
창 만 들 기 결과 보이 기

namedWindow( window_name, CV_WINDOW_AUTOSIZE );
imshow( window_name, dst );
사용자 의 입력 을 기다 리 며 무한 순환 을 실행 합 니 다.

while( true )
{
 int c;
 c = waitKey(10);
 if( (char)c == 27 )
 { break; }
 if( (char)c == 'u' )
 { pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
  printf( "** Zoom In: Image x 2 
" ); } else if( (char)c == 'd' ) { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) ); printf( "** Zoom Out: Image / 2
" ); } imshow( window_name, dst ); tmp = dst; }
사용자 가 ESC 키 프로그램 을 누 르 면 종료 합 니 다.그 밖 에 두 가지 옵션 도 제공 합 니 다.
위로 샘플링('u'누 르 기)

pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 )
함수 pyrUp 은 3 개의 인 자 를 받 아 들 였 습 니 다:
tmp:현재 그림,원본 그림 src 로 초기 화 합 니 다.
dst:목적 그림(그림 표시,그림 입력 의 두 배)
Size(tmp.cols*2,tmp.rows*2):목적 이미지 크기,우리 가 위로 샘플링 을 하 는 이상 pyrUp 은 입력 이미지(tmp)의 두 배 크기 를 기대 합 니 다.
아래로 샘플링('d'누 르 기)

pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 )
pyrUp 과 유사 하 며 함수 pyrDown 도 3 개의 인 자 를 받 아 들 였 습 니 다:
tmp:현재 그림,원본 그림 src 로 초기 화 합 니 다.
dst:목적 그림(그림 표시,그림 의 절반 입력)
Size(tmp.cols/2,tmp.rows/2):목적 이미지 크기 입 니 다.아래 샘플링 을 하 는 이상 pyrDown 은 입력 이미지(tmp)의 절반 크기 를 기대 합 니 다.
그림 의 크기(두 방향)를 입력 하려 면 2 의 명 이 어야 합 니 다.그렇지 않 으 면 오류 가 표 시 됩 니 다.
마지막 으로 입력 한 이미지 tmp 를 현재 디 스 플레이 이미지 로 업데이트 합 니 다.이 후속 작업 은 업 데 이 트 된 이미지 에 사 용 됩 니 다.
tmp = dst;
결실
위의 코드 를 컴 파일 한 후에 우 리 는 결 과 를 실행 할 수 있다.프로그램 이 이미지 chicky 를 호출 하 였 습 니 다.512.jpg,tutorialcode/image 폴 더 를 찾 았 습 니 다.그림 크기 가 512\\times 512 이 므 로 아래로 샘플링 하 는 데 오류 가 발생 하지 않 습 니 다(512=2^{9}).원본 그림 은 다음 과 같 습 니 다.

먼저 두 번'd'를 누 르 고 두 번 연속 으로 pyrDown 을 샘플링 합 니 다.결 과 는 그림 과 같 습 니 다.

우리 가 그림 을 줄 였 기 때문에,우 리 는 이 로 인해 약간의 정 보 를 잃 어 버 렸 다.연속 으로'u'를 두 번 누 르 고 위로 두 번 샘플링 하면 이미지 가 약간 일 그 러 진 것 이 분명 합 니 다.

위 에서 말 한 것 은 소 편 이 소개 한 C+함수 pyrUp 과 pyrDown 으로 이미지 피라미드 기능 을 실현 하 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기