Android OpenCV 기반 이미지 피라미드 구현

이미지 피라미드
이미지 피 라 미 드 는 이미지 에서 다 차원 적 으로 표현 하 는 것 으로 이미지 의 분할 에 가장 많이 사용 되 며 다 해상도 로 이미지 의 효과 적 이지 만 개념 이 간단 한 구조 이다.
이미지 피 라 미 드 는 처음에 기계 시각 과 이미지 압축 에 사용 되 었 고 한 폭 의 이미지 피 라 미 드 는 피라미드 모양 으로 배 열 된 해상도 가 점점 낮 아 졌 으 며 같은 원시 그림 의 이미지 집합 에서 기원 되 었 다.그것 은 계단식 샘플링 을 통 해 얻 을 수 있 으 며,어떤 종료 조건 에 도달 할 때 까지 샘플링 을 멈 출 수 있다.
피라미드 의 밑부분 은 처리 대상 이미지 의 고해상도 표시 이 고 윗부분 은 낮은 해상도 와 비슷 하 다.
우 리 는 한 층 한 층 의 이미 지 를 피라미드 에 비유 하여 등급 이 높 을 수록 이미지 가 작고 해상도 가 낮다.
가우스 피라미드
가우스 피라미드 의 밑 층 은 원시 이미지 이 고 위로 올 라 갈 때마다 가우스 필터 와 1/2 샘플링 을 통 해 얻 을 수 있다(짝수 줄 과 열 제거).다음 샘플링 을 통 해 이미지 의 사 이 즈 를 계속 줄 이 고 피라미드 에 여러 개의 척도 의 이미 지 를 포함한다.일반적인 상황 에서 고 스 피라미드 의 맨 밑 층 은 이미지 의 원 도 이 고 윗 층 마다 아래 샘플링 을 통 해 이미지 의 사 이 즈 를 축소 한다.보통 상황 의 사 이 즈 는 원래 의 절반 으로 줄 어 들 지만 특별한 수요 가 있 으 면축 소 된 사이즈 도 실제 상황 에 맞 게 조정 할 수 있다.매번 이미지 의 크기 가 원래 의 절반 으로 줄 어 들 고 이미지 척 의 축소 속도 가 매우 빠 르 기 때문에 흔히 볼 수 있 는 고 스 피라미드 의 층 수 는 3 층 에서 6 층 이다.
가우스 필 터 는 저 통 필터 로 볼 수 있다.그러면 한 번 의 가우스 필 터 를 거 칠 때마다 이미지 에 특정한 주파수 이하 의 주파수 부분 만 유지 할 수 있 기 때문에 가우스 피 라 미 드 는 저 통 피라미드(각 단 계 는 특정한 주파수 이하 의 성분 만 유지)로 볼 수 있다.

라 프 라 스 피라미드
라 프 라 스 피 라 미 드 는 고 스 피라미드 와 정반 대 이다.고 스 피 라 미 드 는 밑바닥 이미 지 를 통 해 상층 이미 지 를 구축 하고 라 프 라 스 는 상층 작은 사이즈 의 이미 지 를 통 해 하층 큰 사이즈 의 이미 지 를 구축한다.라 프 라 스 피 라 미 드 는 잔 차 를 예측 하 는 역할 을 하기 때문에 고 스 피라미드 와 공동으로 사용 해 야 한다.만약 에 우리 가 고 스 이미지 피 라 미 드 를 가지 고 있다 고 가정 하면 그 중의 i 층 이미지(고 스 피라미드 맨 아래 는 0 층)에 대해 먼저 다음 샘플링 을 통 해 한 사이즈 로 반 으로 줄 인 이미 지 를 얻 을 수 있다.즉,고 스 피라미드 중의 i+1 층 또는 고 스 피라미드 에 없 거나그 다음 에 이 그림 을 샘플링 하여 이미지 사 이 즈 를 i 층 이미지 의 크기 로 복원 하고 마지막 으로 고 스 피라미드 i 층 이미지 와 샘플링 을 통 해 얻 은 이미지 의 차이 점 이미 지 를 구 합 니 다.이 차이 점 이미 지 는 라 프 라 스 피라미드 의 i 층 이미지 입 니 다.

API
샘플링

public static void pyrDown(Mat src, Mat dst, Size dstsize, int borderType) 
4.567917.매개 변수 1:src,샘플링 할 그림 을 입력 하 십시오4.567917.매개 변수 2:dst,출력 에서 샘플링 한 이미지,이미지 사 이 즈 는 지정 할 수 있 지만 데이터 형식 과 채널 수 는 src 와 같 습 니 다.4.567918.
4.567917.매개 변수 3:dstsize,출력 이미지 크기,부족 할 수 있 습 니 다4
  • 매개 변수 4:borderType,픽 셀 경계 외부 추천 방법의 표지
  • 
    // C++: enum BorderTypes
    public static final int
            BORDER_CONSTANT = 0,
            BORDER_REPLICATE = 1,
            BORDER_REFLECT = 2,
            BORDER_WRAP = 3,
            BORDER_REFLECT_101 = 4,
            BORDER_TRANSPARENT = 5,
            BORDER_REFLECT101 = BORDER_REFLECT_101,
            BORDER_DEFAULT = BORDER_REFLECT_101,
            BORDER_ISOLATED = 16;
    기본 상태 에서 함수 출력 이미지 의 사 이 즈 는 입력 이미지 크기 의 절반 이지 만 dstsize 매개 변 수 를 통 해 출력 이미지 의 크기 를 설정 할 수 있 습 니 다.출력 크기 가 얼마 든 아래 식 의 조건 을 만족 시 켜 야 합 니 다.이 함 수 는 먼저 원 이미지 와 커 널 행렬 을 볼 륨 으로 하고 커 널 행렬 은 다음 과 같 습 니 다.그 다음 에 짝수 줄 과 열 을 사용 하지 않 는 방식 으로 그림 을 샘플링 하여 크기 가 줄 어 든 샘플링 이미 지 를 실현 합 니 다.


    샘플링
    
    public static void pyrUp(Mat src, Mat dst, Size dstsize, int borderType) 
    4.567917.매개 변수 1:src,샘플링 할 그림 을 입력 하 십시오
  • 매개 변수 2:dst,출력 에서 샘플링 한 이미지,이미지 사 이 즈 는 지정 할 수 있 지만 데이터 형식 과 채널 수 는 src 와 같 습 니 다
  • 4.567917.매개 변수 3:dstsize,출력 이미지 크기,부족 할 수 있 습 니 다4
  • 매개 변수 4:borderType,픽 셀 경계 외부 추천 방법의 표지
  • 조작 하 다.
    
    class GLPyramidActivity : CardGalleryActivity() {
    
        override fun buildCards() {
            val bgr = Utils.loadResource(this, R.drawable.lena)
            val rgb = Mat()
            Imgproc.cvtColor(bgr, rgb, Imgproc.COLOR_BGR2RGB)
            bgr.release()
            buildGauss(rgb)
            rgb.release()
        }
    
        private fun buildGauss(source: Mat) {
            val gaussList = arrayListOf<Mat>()
            gaussList.add(source)
            for (i in 0..2) {
                val gauss = Mat()
                Imgproc.pyrDown(gaussList[i], gauss)
                gaussList.add(gauss)
            }
    
            for (i in gaussList.indices) {
                val bitmap = Bitmap.createBitmap(
                    gaussList[i].width(),
                    gaussList[i].height(),
                    Bitmap.Config.ARGB_8888
                )
                Utils.matToBitmap(gaussList[i], bitmap)
                cards.add(Card("Gauss${i}", bitmap))
            }
            buildLaplace(gaussList)
        }
    
        private fun buildLaplace(gaussList: List<Mat>) {
            val laplaceList = arrayListOf<Mat>()
            for (i in gaussList.size - 1 downTo 1) {
                val lap = Mat()
                val upGauss = Mat()
                if (i == gaussList.size - 1) {
                    val down = Mat()
                    Imgproc.pyrDown(gaussList[i], down)
                    Imgproc.pyrUp(down, upGauss)
                    Core.subtract(gaussList[i], upGauss, lap)
                    laplaceList.add(lap.clone())
                }
                Imgproc.pyrUp(gaussList[i], upGauss)
                Core.subtract(gaussList[i - 1], upGauss, lap)
                laplaceList.add(lap.clone())
            }
    
            for (i in laplaceList.indices) {
                val bitmap = Bitmap.createBitmap(
                    laplaceList[i].width(),
                    laplaceList[i].height(),
                    Bitmap.Config.ARGB_8888
                )
                Utils.matToBitmap(laplaceList[i], bitmap)
                cards.add(Card("Laplace${i}", bitmap))
            }
    
            for (gauss in gaussList) {
                gauss.release()
            }
            for (lap in laplaceList) {
                lap.release()
            }
        }
    }
    조작 하 다.
    
    class GLPyramidActivity : CardGalleryActivity() {
    
        override fun buildCards() {
            val bgr = Utils.loadResource(this, R.drawable.lena)
            val rgb = Mat()
            Imgproc.cvtColor(bgr, rgb, Imgproc.COLOR_BGR2RGB)
            bgr.release()
            buildGauss(rgb)
            rgb.release()
        }
    
        private fun buildGauss(source: Mat) {
            val gaussList = arrayListOf<Mat>()
            gaussList.add(source)
            for (i in 0..2) {
                val gauss = Mat()
                Imgproc.pyrDown(gaussList[i], gauss)
                gaussList.add(gauss)
            }
    
            for (i in gaussList.indices) {
                val bitmap = Bitmap.createBitmap(
                    gaussList[i].width(),
                    gaussList[i].height(),
                    Bitmap.Config.ARGB_8888
                )
                Utils.matToBitmap(gaussList[i], bitmap)
                cards.add(Card("Gauss${i}", bitmap))
            }
            buildLaplace(gaussList)
        }
    
        private fun buildLaplace(gaussList: List<Mat>) {
            val laplaceList = arrayListOf<Mat>()
            for (i in gaussList.size - 1 downTo 1) {
                val lap = Mat()
                val upGauss = Mat()
                if (i == gaussList.size - 1) {
                    val down = Mat()
                    Imgproc.pyrDown(gaussList[i], down)
                    Imgproc.pyrUp(down, upGauss)
                    Core.subtract(gaussList[i], upGauss, lap)
                    laplaceList.add(lap.clone())
                }
                Imgproc.pyrUp(gaussList[i], upGauss)
                Core.subtract(gaussList[i - 1], upGauss, lap)
                laplaceList.add(lap.clone())
            }
    
            for (i in laplaceList.indices) {
                val bitmap = Bitmap.createBitmap(
                    laplaceList[i].width(),
                    laplaceList[i].height(),
                    Bitmap.Config.ARGB_8888
                )
                Utils.matToBitmap(laplaceList[i], bitmap)
                cards.add(Card("Laplace${i}", bitmap))
            }
    
            for (gauss in gaussList) {
                gauss.release()
            }
            for (lap in laplaceList) {
                lap.release()
            }
        }
    }
    효과.

    위의 이 라 프 라 스 는 잘 보이 지 않 을 지 모 르 지만 자세히 보면 그림 이 있다.그림 의 폭 을 꽉 채 워 보 세 요.

    라 프 라 스 피라미드 의 그림 을 잘 보기 위해 서 는 그림 크기 자체 가 그렇지 않다.
    소스 코드
    github.com/onlyloveyd/…
    이상 은 안 드 로 이 드 가 OpenCV 를 바탕 으로 이미지 피 라 미 드 를 실현 하 는 상세 한 내용 입 니 다.안 드 로 이 드 OpenCV 이미지 피라미드 에 관 한 자 료 는 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기