OpenCV에서는 몇가지 그리기 함수를 제공한다. 각 그리기 함수에 대해서 알아보고 안드로이드용 예제를 만들어본다.

직선 그리기

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

img: 그림을 그릴 영상
pt1: 시작점
pt2: 끝점
color: 선 색상 (B,G,R) 
thickness: 선 두께
lineType: 선 타입; LINE_8(기본값), LINE_4, LINE_AA
shift: 그리기 좌표 값의 축소 비율. 기본값은 0

선 타입

선 타입 지정에 따라 선을 그리는 방식이 차이가 있다. 다음 그림을 참고하자.

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

AA는 Anti-Aliasing(계단 현상 방지 기술)의 약자다. 

사각형 그리기

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

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

사각형 그리기 함수는 rectangle이며 직선 그리기 함수와 비슷하다.
꼭지점 좌표 pt1,pt2 대신 사각형(Rect; (x,y,w,h)) 위치 정보를 대입할 수 있다.

원 그리기

circle(img, center, radius, color, thickness, lineType, shift)

원 그리기 함수는 circle이며 직선 그리기 함수와 비슷하다.

center: 원의 중심 좌표
radius: 원의 반지름

다각형 그리기

polylines(img, pts, isClosed, color, thickness, lineType, shift)

다각형 그리기는 polylines 함수를 사용한다. 

pts: 다각형 외곽점들의 좌표 배열
isClosed: 폐곡선 여부. (Boolean)

다음과 같은 정점을 다각형으로 그릴 때 폐곡선 여부에 따른 도형의 변화

[250, 200], [300, 200], [350, 300], [250, 300]

isClosed가 true일 때

isClosed가 false일 때

문자열 그리기

putText(img, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)

text: 출력할 문자열
org: 문자열을 출력할 위치의 좌측 하단 좌표
fontFace: 폰트 종류
fontScale: 폰트 크기 비율
bottomLeftOrigin: true이면 좌측 하단을 원점으로 지정. 기본값은 false

안드로이드 예제

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
}

View에 터치 이벤트 리스너를 등록하고, ACTION_UP에서 시작점을 지정하고, ACTION_MOVE에서 끝점을 지정한 뒤 선택된 라디오 버튼에 따라 그릴 도형을 선택하도록 구현했다.

 

카테고리: OpenCV

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.