안드로이드 OpenCV의 findContours 사용중 다음과 같은 오류가 발생했을 때 해결하는 방법입니다.

오류 :

Caused by: CvException [org.opencv.core.CvException: cv::Exception: OpenCV(3.4.3) /build/3_4_pack-android/opencv/modules/imgproc/src/contours.cpp:199: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function '_CvContourScanner* cvStartFindContours_Impl(void*, CvMemStorage*, int, int, int, CvPoint, int)'


오류가 나는 이유는 findContours의 입력 값과 출력 값의 데이터 옵션 값이 다르기 때문입니다.


해결 방법 : 

Imgproc.findContours를 호출하기 전

기존의 Mat result 객체를 다음과 같이 처리해줍니다.

Imgproc.cvtColor(src, result, Imgproc.COLOR_BGR2GRAY, 1);


오류해결!


* 참고

문자인식 중 findContours가 이진화(threshold) 된 이미지의 개체들의 blob을 찾지 못할 때 : 이진화 된 이미지의 픽셀 값(색상)을 모두 반전 시켜줍니다.

코드 : 

for(int x=0; x<roi.getWidth(); x++) {

    for(int y=0; y<roi.getHeight(); y++) {

        if(roi.getPixel(x, y) == -1) {

            roi.setPixel(x, y, 0);

        }

        else {

            roi.setPixel(x, y, -1);

        }

    }

}





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.




이번 시간에는 OpenCV를 이용하여 관심역영(ROI)을 추출하겠습니다.

관심영역 추출은 문자인식 전처리 기법 중 하나로

인식 할 범위를 대폭 축소시켜 프로그램 전반적인 실행속도를 향상 시키고

인식률 또한 높일 수 있는 전처리 기법입니다.


※ 안드로이드와 OpenCV 연동은 이곳을 참고하세요.

※ SurfaceView와 카메라 연동은 이곳을 참고하세요.


동작 과정

1. SurfaceView에 카메라 화면 출력

2. 캡쳐를 누르면 안드로이드 내부 저장소에 사진이 저장

3. 새로운 액티비티가 실행되며 저장소에 저장된 사진을 불러옴

4. 불러온 사진을 흑백처리, 이진화처리 수행

5. 처리된 사진을 OpenCV 라이브러리 함수로 영역들을 추출해냄

6. 추출된 영역 중 자동차 번호판에 해당하는 영역만 표시

7. 표시된 영역을 따로 결과화면에 출력

8. 출력된 관심영역을 가지고 문자인식 수행



소스코드 입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
List<MatOfPoint> contours = new ArrayList<>(); 
 
Mat hierarchy = new Mat();
 
Imgproc.findContours(imageCny1, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
 
 
for(int idx = 0; idx >= 0; idx = (int) hierarchy.get(0, idx)[0]) {
 
MatOfPoint matOfPoint = contours.get(idx);
 
Rect rect = Imgproc.boundingRect(matOfPoint);
 
if(rect.width < 30 || rect.height < 30 || rect.width <= rect.height || rect.x < 20 || rect.y < 20
 
|| rect.width <= rect.height * 3 || rect.width >= rect.height * 6continue// 사각형 크기에 따라 출력 여부 결정
 
 
 
// ROI 출력
 
Bitmap roi = Bitmap.createBitmap(myBitmap, (int)rect.tl().x, (int)rect.tl().y, rect.width, rect.height);
 
ImageView imageView1 = (ImageView)findViewById(R.id.image_result_ROI);
 
imageView1.setImageBitmap(roi);
 
}
 
 
image1= Bitmap.createBitmap(img1.cols(), img1.rows(), Bitmap.Config.ARGB_8888);
 
Utils.matToBitmap(img1, image1); // Mat to Bitmap
 
 
imageView = (ImageView)findViewById(R.id.image_result);
 
imageView.setImageBitmap(image1);
 
}
cs



실행화면 입니다.


  





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.







안드로이드에 OpenCV를 설치하는 방법에 대해 알아봅시다.

아래에 링크에 들어가서 OpenCV 3.4.3 android sdk를 다운받고 적절한 폴더에 설치합니다.

https://github.com/opencv/opencv/releases

OpenCV를 설치할 프로젝트를 열고

File-New-Import Module을 선택합니다.



방금 설치한 OpenCV 폴더로 이동해서

sdk/java를 선택하고 OK를 눌러줍니다.

제대로 된 폴더를 선택했다면 OpenCV라는 모듈명이 나옵니다.



모듈을 추가하고 app/build.gradle에 들어가서 맨 아래 프로젝트 추가 코드를 입력합니다.


아래는 이미지파일을 비트맵으로 받아와 흑백 및 에지검출 소스코드입니다.


File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "이미지 파일 경로.png"); // 파일 불러오기

if(file.exists()){ // 파일이 존재한다면

    Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); // 비트맵 생성


    Bitmap image1;

    OpenCVLoader.initDebug(); // 이 코드를 선언해주지않으면 컴파일 에러 발생


    Mat img1=new Mat();

    Utils.bitmapToMat(myBitmap ,img1);

    Mat imageGray1 = new Mat();

    Mat imageCny1 = new Mat();


    //Imgproc.cvtColor(img1, imageGray1, Imgproc.COLOR_BGR2GRAY); // GrayScale


    //Imgproc.Canny(imageGray1, imageCny1, 10, 100, 3, true); // Canny Edge 검출


    //Imgproc.threshold(imageGray1, imageCny1, 150, 255, Imgproc.THRESH_BINARY); //Binary


    image1= Bitmap.createBitmap(imageCny1.cols(), imageCny1.rows(), Bitmap.Config.ARGB_8888); // 비트맵 생성

    Utils.matToBitmap(imageCny1, image1); // Mat을 비트맵으로 변환


    imageView = (ImageView)findViewById(R.id.image_result);

    imageView.setImageBitmap(image1); // 이미지 뷰에 비트맵 출력

}





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.




본 게시글은 Visual Studio 2017 및 OpenCV 2.4.10 버전 기준으로 작성되었음을 알려드립니다.


* 설치하기
1. https://opencv.org/releases.html 링크에 접속합니다.

2. 2.4.10 버전의 win pack을 다운받고 압축을 풉니다. 
   (경로 상관없이 외워두시기만 하면 됩니다.)

3. Visual Studio 2017을 실행합니다.

4. C# Windows Forms 앱으로 프로젝트를 생성합니다.

4-1. 프로젝트를 한번 실행해줍니다.(Ctrl + F5)

5. 생성한 c# 프로젝트 폴더로 이동합니다.

6. 프로젝트 폴더 - bin - debug 에 2번에 풀었던 압축 파일을 모두 복사해줍니다.

7. 다시 Visual Studio로 돌아와서 솔루션 탐색기 - 참조 - 우클릭 - 참조 추가

8. 아래측 찾아보기 버튼을 누르고 6번에 복사해준 폴더로 이동합니다.

9. OpenCV ~ 5개의 dll 파일을 선택하고 추가해줍니다.


10. 확인을 누르면 Visual Studio 2017 C# 환경에서 OpenCV 라이브러리를 사용할 
     준비가 완료되었습니다.


질문사항은 댓글로 달아주세요!



'C#' 카테고리의 다른 글

C# 기초다지기 - 문자열  (2) 2018.11.07
C# 기초다지기 - 배열  (1) 2018.11.06
C# 기초다지기 - 상수  (0) 2018.11.06
C# 기초다지기 - 캡슐화  (0) 2018.11.05
C# 기초다지기 - 프로그램 구조  (0) 2018.11.05
C# 기초다지기 - 변수  (0) 2018.11.05
C# DB연동  (1) 2018.08.29
[C#] 유니코드 한글로 변환하기  (0) 2018.08.22

to Top