OpenCV의 다양한 기능(1)

Jang Seok Woo·2021년 7월 23일
0

실무

목록 보기
76/136
  1. imread()

이미지를 흑백으로 읽기

imread() - COLOR = RGB로 읽기
imread() - GRAYSCALE = Grayscale로 읽기
imread() - unchanged = 파일 속성 그대로 읽기

  1. 이미지 개체 속성, 픽셀 접근

객체의 타입, 원소의 데이터 타입, 전체 픽셀의 개수, shape를 이용한 color, gray 이미지 식별
, 픽셀 좌표로 이미지 객체에 접근이 가능하다.

shape를 이용해 output값이 3이면 color이미지임을 식별하고, 2이면 grayscale이미지임을 식별한다.

픽셀에 접근해 해당 픽셀의 값을 변경한다.

  1. 이미지 생성/복사

이 부분은 말 그대로 이미지를 생성하고 복사하는 부분이니 넘어가도록 하겠다.

  1. 도형 그리기

선, 사각형, 원, 다각형을 그릴 수 있다.
현재 프로젝트에서 응용하고 있는 사각형 그리기에 대해 보고 넘어가도록 하겠다.

rectangle(img, pt1, pt2, color, thickness, lineType, shift)

rectangle(img, rec, color, thickness, lineType, shift)

함수는 다음과 같으며, 각 매개변수의 역할은

img(사각형을 그릴 곳), pt1(기준점1), pt2(기준점2), color(사각형 그릴 선의 색깔), 선의 타입(기본값 LINE_8,LINE_4 등), 그리기 좌표 값의 축소비율 기본값은 0

LINE_4와 LINE_8은 인접 픽셀을 4방향 중 하나로 채울지 8방향중 하나로 채울지 결정한다.

예제

binding.canvas.setOnTouchListener { v, event ->
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            initX = event.x
            initY = event.y
        }
        MotionEvent.ACTION_MOVE -> {
            mat = Mat.zeros(
                binding.canvas.measuredHeight,
                binding.canvas.measuredWidth,
                CvType.CV_8UC3
            )
            when (binding.radioGroup.checkedRadioButtonId) {
                R.id.line -> {
                    Imgproc.line(
                        mat,
                        Point(initX.toDouble(), initY.toDouble()),
                        Point(event.x.toDouble(), event.y.toDouble()),
                        Scalar(255.0, 0.0, 0.0)
                    )
                }
                R.id.rectangle -> {
                    Imgproc.rectangle(
                        mat,
                        Point(initX.toDouble(), initY.toDouble()),
                        Point(event.x.toDouble(), event.y.toDouble()),
                        Scalar(255.0, 0.0, 0.0)
                    )
                }
                R.id.circle -> {
                    val absX = abs(initX - event.x)
                    val absY = abs(initY - event.y)
                    Imgproc.circle(
                        mat,
                        Point(initX.toDouble(), initY.toDouble()),
                        sqrt(absX * absX + absY * absY).toInt(),
                        Scalar(255.0, 0.0, 0.0)
                    )
                }
            }
            val bmp = Bitmap.createBitmap(mat.cols(), mat.rows(), Bitmap.Config.ARGB_8888)
            Utils.matToBitmap(mat, bmp)
            binding.canvas.setImageBitmap(bmp)
        }
    }
    true
}
  1. 이미지 밝기 조절

기본 컬러 이미지 뿐만 아니라 Grayscale된 이미지의 밝기도 조절할 수 있다.

밝게 조절할 때는 add(), 어둡게할 때는 sub()를 사용하면 쉽게 변환할 수 있다.

간단한 예제

private fun calcBrightness(src: Mat, additionalBrightness: Int): Mat {
    // 밝기를 스칼라값으로 치환
    val src2 = Scalar.all(additionalBrightness.toDouble())
    val dst = Mat()
    Core.add(src, src2, dst)
    return dst
}

  1. 이미지 필터링

알고리즘에 의해 픽셀의 값을 변경하여 이미지에 효과를 주는 것
이를 이용해 이미지를 흐리게, 날카롭게, 뚜렷하게, 노이즈 제거 등 다양한 효과를 줄 수 있습니다.

blur()
기본적으로 이미지를 흐리게 할 때 사용합니다.
도수 안맞은 안경쓴 느낌이 듭니다.

GaussianBlur()
blur와 마찬가지로 흐림 효과를 주는데 blur와는 차이가 있습니다.
GaussianBlur는 전체적으로 밀도가 동일한 노이즈, 백색 노이즈를 제거하는데 효과적입니다.

medianBlur()
노이즈를 제거하는데 사용합니다.

bilateralFilter()
지금까지의 처리는 경계선이 흐려지는데 반해 bilateralFilter는 경계선을 유지합니다.
결과를 보면 뽀샵처리한 듯한 느낌이 든다고 합니다.

  1. 기하학적 변환

확대,축소
resize()

대칭
flip()

이동
warpAffine()

회전
getRotation()
warpAffine()

  1. 미분 필터링

엣지를 검출하는데 사용된다.
경계를 검출하려면 픽셀 값의 변화가 급격히 일어나야 한다.
연속된 픽셀 값에 미분 연산을 해서 경계 값을 검출한다.
영상 속 픽셀 데이터는 연속적이지 않고 이산적이라 근사값으로 계산한다.

numpy

x축 방향 미분 gx
y축 방향 미분 gy

  1. 로버츠 마스크

로버츠 마스크는 대각선 방향으로 1과 -1을 배치하여 사선 엣지 검출 효과를 높입니다.
수행 속도가 빠르지만, 노이즈에 민감하고 엣지 강도가 약한 단점이 있습니다.

  1. 프리윗(Prewitt) 마스크

기존의 미분을 세번하여 엣지의 강도가 강하고, 수직과 수평 엣지를 동등하게 찾는 장점이 있습니다. 수직과 수평에 비해 대각선 검출이 약하다는 단점이 있습니다.

  1. 소벨(Sobel)

대표적인 필터로 Prewitt 필터에 픽셀의 가중치를 두 배로 두었습니다.
상대적으로 대각선 검출에 약한 Prewitt 필터에 비해 sobel은 수평, 수직, 대각선 검출에 모두 강합니다.

  1. 샤르(Scharr)

Prewitt 필터에 픽셀의 가중치를 (3, 10, 3) 배로 증가했습니다.
수평, 수직, 대각선 검출에 모두 강합니다.

  1. 라플라시안

대표적인 2차 미분 필터로 잡음 성분에 매우 민감하여 더 많은 엣지를 검출하는 경향이 있습니다. 따라서 적용하기 전에 잡음을 제거하는게 좋습니다.

  1. Magnitude calculation

x: 2D 벡터의 x좌표 행렬(실수형)
y: 2D 벡터의 y좌표 행렬(실수형)
magnigude: 2D 벡터의 크기 행렬, x와 같은 크기 & 데이터타입

  1. Canny

가우시안(Gaussian) 필터를 이용하여 노이즈를 제거
소벨(Sobel) 필터를 이용하여 Gradient 방향
비최대치 억제로 Gradient 방향에서 최대치만 검출
Theresholding으로 경계값(min, max)를 지정해서 경계 지정

상단 임계값

하단 임계값

profile
https://github.com/jsw4215

0개의 댓글